From 3a795fba038bf64452abb8c2240fd1221185e274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Apr 2020 13:36:35 -0700 Subject: [PATCH] On type mismatch involving associated type, suggest constraint When an associated type is found when a specific type was expected, if possible provide a structured suggestion constraining the associated type in a bound. ``` error[E0271]: type mismatch resolving `::Y == i32` --> $DIR/associated-types-multiple-types-one-trait.rs:13:5 | LL | want_y(t); | ^^^^^^ expected `i32`, found associated type ... LL | fn want_y>(t: &T) { } | ----- required by this bound in `want_y` | = note: expected type `i32` found associated type `::Y` help: consider constraining the associated type `::Y` to `i32` | LL | fn have_x_want_y>(t: &T) | ^^^^^^^^^ ``` ``` error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:12:9 | LL | qux(x.func()) | ^^^^^^^^ expected `usize`, found associated type | = note: expected type `usize` found associated type `::A` help: consider constraining the associated type `::A` to `usize` | LL | fn foo(x: impl Trait) { | ^^^^^^^^^^ ``` --- src/librustc_middle/ty/error.rs | 144 ++++++++++++++++-- .../associated-types-eq-3.stderr | 6 +- .../associated-types-issue-20346.stderr | 2 - ...ated-types-multiple-types-one-trait.stderr | 12 +- .../generic-associated-types/iterable.stderr | 4 +- src/test/ui/hrtb/issue-62203-hrtb-ice.stderr | 2 +- .../bound-normalization-fail.stderr | 12 +- src/test/ui/impl-trait/equality2.stderr | 2 +- .../universal-mismatched-type.stderr | 2 - src/test/ui/issues/issue-13853.stderr | 2 - src/test/ui/issues/issue-20225.stderr | 6 - src/test/ui/issues/issue-69306.stderr | 12 -- .../ui/mismatched_types/issue-35030.stderr | 2 - .../specialization-default-projection.stderr | 2 +- .../specialization-default-types.stderr | 2 +- .../expected-boxed-future-isnt-pinned.stderr | 2 - ...-associated-type-restriction-fixable.fixed | 43 ++++++ ...ing-associated-type-restriction-fixable.rs | 43 ++++++ ...associated-type-restriction-fixable.stderr | 94 ++++++++++++ ...ith-missing-associated-type-restriction.rs | 41 +++++ ...missing-associated-type-restriction.stderr | 88 +++++++++++ .../enum-variant-generic-args.stderr | 12 -- 22 files changed, 469 insertions(+), 66 deletions(-) create mode 100644 src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.fixed create mode 100644 src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs create mode 100644 src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr create mode 100644 src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs create mode 100644 src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index 78a94b62d47..eb5a5702c45 100644 --- a/src/librustc_middle/ty/error.rs +++ b/src/librustc_middle/ty/error.rs @@ -4,7 +4,7 @@ use rustc_errors::{pluralize, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::sym; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use rustc_target::spec::abi; use std::borrow::Cow; @@ -401,7 +401,10 @@ impl<'tcx> TyCtxt<'tcx> { (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => { db.note("you might be missing a type parameter or trait bound"); } - (ty::Param(p), _) | (_, ty::Param(p)) => { + (ty::Param(p), ty::Dynamic(..)) + | (ty::Dynamic(..), ty::Param(p)) + | (ty::Param(p), ty::Opaque(..)) + | (ty::Opaque(..), ty::Param(p)) => { let generics = self.generics_of(body_owner_def_id); let p_span = self.def_span(generics.type_param(p, self).def_id); if !sp.contains(p_span) { @@ -441,11 +444,18 @@ impl Trait for X { #traits-as-parameters", ); } + (ty::Param(p), _) | (_, ty::Param(p)) => { + let generics = self.generics_of(body_owner_def_id); + let p_span = self.def_span(generics.type_param(p, self).def_id); + if !sp.contains(p_span) { + db.span_label(p_span, "this type parameter"); + } + } (ty::Projection(_), _) => { db.note(&format!( "consider constraining the associated type `{}` to `{}` or calling a \ - method that returns `{}`", - values.expected, values.found, values.expected, + method that returns `{0}`", + values.expected, values.found, )); if self.sess.teach(&db.get_code().unwrap()) { db.help( @@ -470,15 +480,18 @@ impl Trait for X { https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", ); } - (_, ty::Projection(_)) => { - db.note(&format!( + (_, ty::Projection(proj_ty)) => { + let msg = format!( "consider constraining the associated type `{}` to `{}`", values.found, values.expected, - )); - db.note( - "for more information, visit \ - https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", ); + if !self.suggest_constraint(db, &msg, body_owner_def_id, proj_ty, values) { + db.help(&msg); + db.note( + "for more information, visit \ + https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", + ); + } } _ => {} } @@ -513,4 +526,115 @@ impl Trait for X { _ => {} } } + + fn suggest_constraint( + &self, + db: &mut DiagnosticBuilder<'_>, + msg: &str, + body_owner_def_id: DefId, + proj_ty: &ty::ProjectionTy<'tcx>, + values: &ExpectedFound>, + ) -> bool { + let assoc = self.associated_item(proj_ty.item_def_id); + let trait_ref = proj_ty.trait_ref(*self); + if let Some(item) = self.hir().get_if_local(body_owner_def_id) { + if let Some(hir_generics) = item.generics() { + // Get the `DefId` for the type parameter corresponding to `A` in `::Foo`. + // This will also work for `impl Trait`. + let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind { + let generics = self.generics_of(body_owner_def_id); + generics.type_param(¶m_ty, *self).def_id + } else { + return false; + }; + + // First look in the `where` clause, as this might be + // `fn foo(x: T) where T: Trait`. + for predicate in hir_generics.where_clause.predicates { + if let hir::WherePredicate::BoundPredicate(pred) = predicate { + if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = + pred.bounded_ty.kind + { + if path.res.opt_def_id() == Some(def_id) { + // This predicate is binding type param `A` in `::Foo` to + // something, potentially `T`. + } else { + continue; + } + } else { + continue; + } + + if self.constrain_associated_type_structured_suggestion( + db, + &trait_ref, + pred.bounds, + &assoc, + values, + msg, + ) { + return true; + } + } + } + for param in hir_generics.params { + if self.hir().opt_local_def_id(param.hir_id).map(|id| id.to_def_id()) + == Some(def_id) + { + // This is type param `A` in `::Foo`. + return self.constrain_associated_type_structured_suggestion( + db, + &trait_ref, + param.bounds, + &assoc, + values, + msg, + ); + } + } + } + } + false + } + + fn constrain_associated_type_structured_suggestion( + &self, + db: &mut DiagnosticBuilder<'_>, + trait_ref: &ty::TraitRef<'tcx>, + bounds: hir::GenericBounds<'_>, + assoc: &ty::AssocItem, + values: &ExpectedFound>, + msg: &str, + ) -> bool { + for bound in bounds { + match bound { + hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => { + // Relate the type param against `T` in `::Foo`. + if ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id) { + if let Ok(has_params) = self + .sess + .source_map() + .span_to_snippet(ptr.span) + .map(|snippet| snippet.ends_with('>')) + { + let (span, sugg) = if has_params { + let pos = ptr.span.hi() - BytePos(1); + let span = Span::new(pos, pos, ptr.span.ctxt()); + (span, format!(", {} = {}", assoc.ident, values.expected)) + } else { + ( + ptr.span.shrink_to_hi(), + format!("<{} = {}>", assoc.ident, values.expected), + ) + }; + db.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect); + return true; + } + } + } + _ => {} + } + } + false + } } diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr index a8608abb4d9..dffa4780a09 100644 --- a/src/test/ui/associated-types/associated-types-eq-3.stderr +++ b/src/test/ui/associated-types/associated-types-eq-3.stderr @@ -8,8 +8,10 @@ LL | let _: Bar = x.boo(); | = note: expected struct `Bar` found associated type `::A` - = note: consider constraining the associated type `::A` to `Bar` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `::A` to `Bar` + | +LL | fn foo2>(x: I) { + | ^^^^^^^^^ error[E0271]: type mismatch resolving `::A == Bar` --> $DIR/associated-types-eq-3.rs:38:5 diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr index 8f2b760840c..db35c1af171 100644 --- a/src/test/ui/associated-types/associated-types-issue-20346.stderr +++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr @@ -12,8 +12,6 @@ LL | is_iterator_of::, _>(&adapter); | = note: expected enum `std::option::Option` found type `T` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr index 4e481411b4d..b8f20d00ff8 100644 --- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr +++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr @@ -9,8 +9,10 @@ LL | fn want_y>(t: &T) { } | = note: expected type `i32` found associated type `::Y` - = note: consider constraining the associated type `::Y` to `i32` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `::Y` to `i32` + | +LL | fn have_x_want_y>(t: &T) + | ^^^^^^^^^ error[E0271]: type mismatch resolving `::X == u32` --> $DIR/associated-types-multiple-types-one-trait.rs:18:5 @@ -23,8 +25,10 @@ LL | fn want_x>(t: &T) { } | = note: expected type `u32` found associated type `::X` - = note: consider constraining the associated type `::X` to `u32` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `::X` to `u32` + | +LL | fn have_y_want_x>(t: &T) + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr index b1298163aab..4a839ac4bcb 100644 --- a/src/test/ui/generic-associated-types/iterable.stderr +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -6,7 +6,7 @@ LL | type Item<'a> where T: 'a = as Iterator>::Item | = note: expected reference `&T` found associated type ` as Iterable>::Item<'_>` - = note: consider constraining the associated type ` as Iterable>::Item<'_>` to `&_` + = help: consider constraining the associated type ` as Iterable>::Item<'_>` to `&_` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` @@ -17,7 +17,7 @@ LL | type Item<'a> where T: 'a = as Iterator>::Item | = note: expected reference `&T` found associated type `<[T] as Iterable>::Item<'_>` - = note: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_` + = help: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr index 759c7302d13..1c7bfa65d7c 100644 --- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr +++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr @@ -6,7 +6,7 @@ LL | let v = Unit2.m( | = note: expected struct `Unit4` found associated type `<_ as Ty<'_>>::V` - = note: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` + = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3` diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 314ed96fd5e..f5092044627 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -14,9 +14,11 @@ LL | fn foo_fail() -> impl FooLike { | = note: expected type `()` found associated type `::Assoc` - = note: consider constraining the associated type `::Assoc` to `()` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: the return type of a function must have a statically known size +help: consider constraining the associated type `::Assoc` to `()` + | +LL | fn foo_fail>() -> impl FooLike { + | ^^^^^^^^^^^^ error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope --> $DIR/bound-normalization-fail.rs:43:41 @@ -32,9 +34,11 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | = note: expected type `()` found associated type `>::Assoc` - = note: consider constraining the associated type `>::Assoc` to `()` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html = note: the return type of a function must have a statically known size +help: consider constraining the associated type `>::Assoc` to `()` + | +LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike { + | ^^^^^^^^^^^^ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index b882514f616..2454c218ffc 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -25,7 +25,7 @@ LL | let _: i32 = Leak::leak(hide(0_i32)); | = note: expected type `i32` found associated type `::T` - = note: consider constraining the associated type `::T` to `i32` + = help: consider constraining the associated type `::T` to `i32` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0308]: mismatched types diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr index 3ffa2b55712..a12b01b4d2b 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.stderr +++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr @@ -10,8 +10,6 @@ LL | x | = note: expected struct `std::string::String` found type parameter `impl Debug` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr index 2f31636f8ad..3f1b955dddb 100644 --- a/src/test/ui/issues/issue-13853.stderr +++ b/src/test/ui/issues/issue-13853.stderr @@ -9,8 +9,6 @@ LL | self.iter() | = note: expected type parameter `I` found struct `std::slice::Iter<'_, N>` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0599]: no method named `iter` found for reference `&G` in the current scope --> $DIR/issue-13853.rs:27:23 diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr index 1c5911e05f7..3bcc50ded84 100644 --- a/src/test/ui/issues/issue-20225.stderr +++ b/src/test/ui/issues/issue-20225.stderr @@ -8,8 +8,6 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} | = note: expected fn pointer `extern "rust-call" fn(&Foo, (&'a T,))` found fn pointer `extern "rust-call" fn(&Foo, (T,))` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:3 @@ -21,8 +19,6 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} | = note: expected fn pointer `extern "rust-call" fn(&mut Foo, (&'a T,))` found fn pointer `extern "rust-call" fn(&mut Foo, (T,))` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:3 @@ -35,8 +31,6 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} | = note: expected fn pointer `extern "rust-call" fn(Foo, (&'a T,))` found fn pointer `extern "rust-call" fn(Foo, (T,))` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-69306.stderr b/src/test/ui/issues/issue-69306.stderr index a2a42739ca8..58e85ec700d 100644 --- a/src/test/ui/issues/issue-69306.stderr +++ b/src/test/ui/issues/issue-69306.stderr @@ -8,8 +8,6 @@ LL | const C: S0 = Self(0); | = note: expected type parameter `T` found type `{integer}` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:5:23 @@ -21,8 +19,6 @@ LL | const C: S0 = Self(0); | = note: expected struct `S0` found struct `S0` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:10:14 @@ -35,8 +31,6 @@ LL | Self(0); | = note: expected type parameter `T` found type `{integer}` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:27:14 @@ -49,8 +43,6 @@ LL | Self(0); | = note: expected type parameter `T` found type `{integer}` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:33:32 @@ -62,8 +54,6 @@ LL | const C: S1 = Self(0, 1); | = note: expected type parameter `T` found type `{integer}` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:33:27 @@ -75,8 +65,6 @@ LL | const C: S1 = Self(0, 1); | = note: expected struct `S1` found struct `S1` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/issue-69306.rs:41:14 diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr index 6fb04ef5c99..9f4e4398984 100644 --- a/src/test/ui/mismatched_types/issue-35030.stderr +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -9,8 +9,6 @@ LL | Some(true) | = note: expected type parameter `bool` (type parameter `bool`) found type `bool` (`bool`) - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error: aborting due to previous error diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr index d03aec7ab30..4344fe23bbc 100644 --- a/src/test/ui/specialization/specialization-default-projection.stderr +++ b/src/test/ui/specialization/specialization-default-projection.stderr @@ -25,7 +25,7 @@ LL | generic::<()>() | = note: expected unit type `()` found associated type `<() as Foo>::Assoc` - = note: consider constraining the associated type `<() as Foo>::Assoc` to `()` + = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to 2 previous errors diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr index 257c114252c..d66aaa96274 100644 --- a/src/test/ui/specialization/specialization-default-types.stderr +++ b/src/test/ui/specialization/specialization-default-types.stderr @@ -21,7 +21,7 @@ LL | Example::generate(t) | = note: expected struct `std::boxed::Box` found associated type `::Output` - = note: consider constraining the associated type `::Output` to `std::boxed::Box` + = help: consider constraining the associated type `::Output` to `std::boxed::Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index ff256eb3094..0e68e81d7ab 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -12,8 +12,6 @@ LL | x | = note: expected struct `std::pin::Pin + std::marker::Send + 'static)>>` found type parameter `F` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0308]: mismatched types --> $DIR/expected-boxed-future-isnt-pinned.rs:18:5 diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.fixed b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.fixed new file mode 100644 index 00000000000..8ef7e34ab30 --- /dev/null +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.fixed @@ -0,0 +1,43 @@ +// run-rustfix +#![allow(unused)] // for the fixed file + +trait Trait { + type A; + + fn func(&self) -> Self::A; +} + +struct S(T); +impl S { + fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait, _: T) { + qux(x.func()) //~ ERROR mismatched types + } + + fn ban(x: T) where T: Trait { + qux(x.func()) //~ ERROR mismatched types + } +} + +fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait, _: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar>(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn foo2(x: impl Trait) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar2>(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn ban(x: T) where T: Trait { + qux(x.func()) //~ ERROR mismatched types +} + +fn qux(_: usize) {} + +fn main() {} diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs new file mode 100644 index 00000000000..7bd38d0d45d --- /dev/null +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs @@ -0,0 +1,43 @@ +// run-rustfix +#![allow(unused)] // for the fixed file + +trait Trait { + type A; + + fn func(&self) -> Self::A; +} + +struct S(T); +impl S { + fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait, _: T) { + qux(x.func()) //~ ERROR mismatched types + } + + fn ban(x: T) where T: Trait { + qux(x.func()) //~ ERROR mismatched types + } +} + +fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait, _: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn foo2(x: impl Trait) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar2>(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn ban(x: T) where T: Trait { + qux(x.func()) //~ ERROR mismatched types +} + +fn qux(_: usize) {} + +fn main() {} diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr new file mode 100644 index 00000000000..f785f7b84a7 --- /dev/null +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr @@ -0,0 +1,94 @@ +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:13:13 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait, _: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:17:13 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn ban(x: T) where T: Trait { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:22:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait, _: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:26:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn bar>(x: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:30:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type ` as Trait>::A` +help: consider constraining the associated type ` as Trait>::A` to `usize` + | +LL | fn foo2(x: impl Trait) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:34:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `>::A` +help: consider constraining the associated type `>::A` to `usize` + | +LL | fn bar2>(x: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:38:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn ban(x: T) where T: Trait { + | ^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs new file mode 100644 index 00000000000..1166785d739 --- /dev/null +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs @@ -0,0 +1,41 @@ +// These are all the possible variations of this error I could think of for. +// `trait-with-missing-associated-type-restriction-fixable.rs` contains the subset of these that +// can be fixed with `rustfix`. + +trait Trait { + type A; + + fn func(&self) -> Self::A; +} + +fn foo(_: impl Trait, x: impl Trait) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn foo2(x: impl Trait) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bar2>(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn baz>(x: T) { + qux(x.func()) //~ ERROR mismatched types +} + +fn bat(x: &mut dyn Trait<(), A = ()>) { + qux(x) //~ ERROR mismatched types +} + +fn ban(x: T) where T: Trait { + qux(x.func()) //~ ERROR mismatched types +} + +fn qux(_: usize) {} + +fn main() {} diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr new file mode 100644 index 00000000000..08788db6ec9 --- /dev/null +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr @@ -0,0 +1,88 @@ +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:12:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn foo(_: impl Trait, x: impl Trait) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:16:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn bar>(x: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:20:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type ` as Trait>::A` +help: consider constraining the associated type ` as Trait>::A` to `usize` + | +LL | fn foo2(x: impl Trait) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:24:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `>::A` +help: consider constraining the associated type `>::A` to `usize` + | +LL | fn bar2>(x: T) { + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:28:9 + | +LL | fn baz>(x: T) { + | - this type parameter +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found type parameter `D` + | + = note: expected type `usize` + found type parameter `D` + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:32:9 + | +LL | qux(x) + | ^ expected `usize`, found mutable reference + | + = note: expected type `usize` + found mutable reference `&mut dyn Trait<(), A = ()>` + +error[E0308]: mismatched types + --> $DIR/trait-with-missing-associated-type-restriction.rs:36:9 + | +LL | qux(x.func()) + | ^^^^^^^^ expected `usize`, found associated type + | + = note: expected type `usize` + found associated type `::A` +help: consider constraining the associated type `::A` to `usize` + | +LL | fn ban(x: T) where T: Trait { + | ^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index 412b4dbda4f..caea791e653 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -9,8 +9,6 @@ LL | Self::TSVariant(()); | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:15:27 @@ -35,8 +33,6 @@ LL | Self::<()>::TSVariant(()); | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:20:16 @@ -61,8 +57,6 @@ LL | Self::SVariant { v: () }; | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:28:26 @@ -81,8 +75,6 @@ LL | Self::SVariant::<()> { v: () }; | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:31:16 @@ -101,8 +93,6 @@ LL | Self::<()>::SVariant { v: () }; | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:34:16 @@ -127,8 +117,6 @@ LL | Self::<()>::SVariant::<()> { v: () }; | = note: expected type parameter `T` found unit type `()` - = help: type parameters must be constrained to match other types - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:41:26