diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-08-08 22:29:55 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-08-08 22:29:55 +0100 |
commit | 72483b1ca912dca78543f5cc2a7e9d1380ef5784 (patch) | |
tree | fc4db17b64ffe2717ba4b6f2ddf716a81aa1ef31 | |
parent | 3f544652b42f9c9330e87ceb6df517d675aa5300 (diff) | |
download | gcc-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.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 43 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 38 |
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; } |