aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-08-08 22:29:55 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-08-08 22:29:55 +0100
commit72483b1ca912dca78543f5cc2a7e9d1380ef5784 (patch)
treefc4db17b64ffe2717ba4b6f2ddf716a81aa1ef31
parent3f544652b42f9c9330e87ceb6df517d675aa5300 (diff)
downloadgcc-72483b1ca912dca78543f5cc2a7e9d1380ef5784.zip
gcc-72483b1ca912dca78543f5cc2a7e9d1380ef5784.tar.gz
gcc-72483b1ca912dca78543f5cc2a7e9d1380ef5784.tar.bz2
Improve the error message for bad type bounds
We emit one error for all unsatisfied bounds such as: test.rs:26:31: error: bounds not satisfied for Test ‘Bar, Baz’ is not satisfied 21 | fn type_bound_test<T: Foo + Bar + Baz>() -> i32 { | ~ ~ ...... 26 | let a = type_bound_test::<Test>(); | ^
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc6
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc43
-rw-r--r--gcc/rust/typecheck/rust-tyty.h38
4 files changed, 60 insertions, 29 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index ef1510e..fff86be 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -283,7 +283,7 @@ public:
TraitReference *trait = resolve_trait_path (b->get_path ());
TyTy::TypeBoundPredicate predicate (
- trait->get_mappings ().get_defid ());
+ trait->get_mappings ().get_defid (), b->get_locus ());
specified_bounds.push_back (std::move (predicate));
}
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 3562e85..008dc19 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -83,5 +83,11 @@ TypeBoundPredicate::get () const
return ref;
}
+std::string
+TypeBoundPredicate::get_name () const
+{
+ return get ()->get_name ();
+}
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 88b6c35..2d165c3 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -62,6 +62,49 @@ BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
return false;
}
+bool
+BaseType::bounds_compatible (const BaseType &other, Location locus) const
+{
+ std::vector<std::reference_wrapper<const TypeBoundPredicate>>
+ unsatisfied_bounds;
+ for (auto &bound : get_specified_bounds ())
+ {
+ if (!other.satisfies_bound (bound))
+ unsatisfied_bounds.push_back (bound);
+ }
+
+ // lets emit a single error for this
+ if (unsatisfied_bounds.size () > 0)
+ {
+ RichLocation r (locus);
+ std::string missing_preds;
+ for (size_t i = 0; i < unsatisfied_bounds.size (); i++)
+ {
+ const TypeBoundPredicate &pred = unsatisfied_bounds.at (i);
+ r.add_range (pred.get_locus ());
+ missing_preds += pred.get_name ();
+
+ bool have_next = (i + 1) < unsatisfied_bounds.size ();
+ if (have_next)
+ missing_preds += ", ";
+ }
+
+ rust_error_at (r, "bounds not satisfied for %s %<%s%> is not satisfied",
+ other.get_name ().c_str (), missing_preds.c_str ());
+ }
+
+ return unsatisfied_bounds.size () == 0;
+}
+
+void
+BaseType::inherit_bounds (const BaseType &other)
+{
+ for (auto &bound : other.get_specified_bounds ())
+ {
+ add_bound (bound);
+ }
+}
+
TyVar::TyVar (HirId ref) : ref (ref)
{
// ensure this reference is defined within the context
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index f6f9579..c1afa14 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -132,14 +132,21 @@ public:
class TypeBoundPredicate
{
public:
- TypeBoundPredicate (DefId reference) : reference (reference) {}
+ TypeBoundPredicate (DefId reference, Location locus)
+ : reference (reference), locus (locus)
+ {}
std::string as_string () const;
const Resolver::TraitReference *get () const;
+ Location get_locus () const { return locus; }
+
+ std::string get_name () const;
+
private:
DefId reference;
+ Location locus;
};
class TypeBoundsMappings
@@ -241,34 +248,9 @@ public:
bool satisfies_bound (const TypeBoundPredicate &predicate) const;
- bool bounds_compatible (const BaseType &other, Location locus) const
- {
- std::vector<std::reference_wrapper<const TypeBoundPredicate>>
- unsatisfied_bounds;
- for (auto &bound : get_specified_bounds ())
- {
- if (!other.satisfies_bound (bound))
- unsatisfied_bounds.push_back (bound);
- }
-
- if (unsatisfied_bounds.size () > 0)
- {
- RichLocation r (locus);
- rust_error_at (r, "bounds not satisfied for %s",
- other.as_string ().c_str ());
- return false;
- }
-
- return unsatisfied_bounds.size () == 0;
- }
+ bool bounds_compatible (const BaseType &other, Location locus) const;
- void inherit_bounds (const BaseType &other)
- {
- for (auto &bound : other.get_specified_bounds ())
- {
- add_bound (bound);
- }
- }
+ void inherit_bounds (const BaseType &other);
virtual bool is_unit () const { return false; }