diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5a7957be318ea..5baaaf09edb66 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -24,6 +24,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; @@ -1633,8 +1634,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn report_ambiguous_associated_type( &self, span: Span, - type_str: &str, - trait_str: &str, + types: &[String], + traits: &[String], name: Symbol, ) -> ErrorGuaranteed { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); @@ -1645,19 +1646,92 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .keys() .any(|full_span| full_span.contains(span)) { - err.span_suggestion( + err.span_suggestion_verbose( span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", "std::", Applicability::MachineApplicable, ); } else { - err.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", type_str, trait_str, name), - Applicability::HasPlaceholders, - ); + match (types, traits) { + ([], []) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a type named `Type` that implements a trait named \ + `Trait` with associated type `{name}`, you could use the \ + fully-qualified path", + ), + format!("::{name}"), + Applicability::HasPlaceholders, + ); + } + ([], [trait_str]) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a type named `Example` that implemented `{trait_str}`, \ + you could use the fully-qualified path", + ), + format!("::{name}"), + Applicability::HasPlaceholders, + ); + } + ([], traits) => { + err.span_suggestions( + span, + &format!( + "if there were a type named `Example` that implemented one of the \ + traits with associated type `{name}`, you could use the \ + fully-qualified path", + ), + traits + .iter() + .map(|trait_str| format!("::{name}")) + .collect::>(), + Applicability::HasPlaceholders, + ); + } + ([type_str], []) => { + err.span_suggestion_verbose( + span, + &format!( + "if there were a trait named `Example` with associated type `{name}` \ + implemented for `{type_str}`, you could use the fully-qualified path", + ), + format!("<{type_str} as Example>::{name}"), + Applicability::HasPlaceholders, + ); + } + (types, []) => { + err.span_suggestions( + span, + &format!( + "if there were a trait named `Example` with associated type `{name}` \ + implemented for one of the types, you could use the fully-qualified \ + path", + ), + types + .into_iter() + .map(|type_str| format!("<{type_str} as Example>::{name}")), + Applicability::HasPlaceholders, + ); + } + (types, traits) => { + let mut suggestions = vec![]; + for type_str in types { + for trait_str in traits { + suggestions.push(format!("<{type_str} as {trait_str}>::{name}")); + } + } + err.span_suggestions( + span, + "use the fully-qualified path", + suggestions, + Applicability::MachineApplicable, + ); + } + } } err.emit() } @@ -2040,12 +2114,64 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.emit() } else if let Err(reported) = qself_ty.error_reported() { reported + } else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() { + // `::Assoc` makes no sense. + struct_span_err!( + tcx.sess, + tcx.def_span(alias_ty.def_id), + E0667, + "`impl Trait` is not allowed in path parameters" + ) + .emit() // Already reported in an earlier stage. } else { + // Find all the `impl`s that `qself_ty` has for any trait that has the + // associated type, so that we suggest the right one. + let infcx = tcx.infer_ctxt().build(); + // We create a fresh `ty::ParamEnv` instead of the one for `self.item_def_id()` + // to avoid a cycle error in `src/test/ui/resolve/issue-102946.rs`. + let param_env = ty::ParamEnv::empty(); + let traits: Vec<_> = self + .tcx() + .all_traits() + .filter(|trait_def_id| { + // Consider only traits with the associated type + tcx.associated_items(*trait_def_id) + .in_definition_order() + .any(|i| { + i.kind.namespace() == Namespace::TypeNS + && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident + && matches!(i.kind, ty::AssocKind::Type) + }) + // Consider only accessible traits + && tcx.visibility(*trait_def_id) + .is_accessible_from(self.item_def_id(), tcx) + && tcx.all_impls(*trait_def_id) + .any(|impl_def_id| { + let trait_ref = tcx.bound_impl_trait_ref(impl_def_id); + trait_ref.map_or(false, |trait_ref| { + let impl_ = trait_ref.subst( + tcx, + infcx.fresh_substs_for_item(span, impl_def_id), + ); + infcx + .can_eq( + param_env, + tcx.erase_regions(impl_.self_ty()), + tcx.erase_regions(qself_ty), + ) + .is_ok() + }) + && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative + }) + }) + .map(|trait_def_id| tcx.def_path_str(trait_def_id)) + .collect(); + // Don't print `TyErr` to the user. self.report_ambiguous_associated_type( span, - &qself_ty.to_string(), - "Trait", + &[qself_ty.to_string()], + &traits, assoc_ident.name, ) }; @@ -2163,16 +2289,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let is_part_of_self_trait_constraints = def_id == trait_def_id; let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id); - let type_name = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait { - "Self" + let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait { + vec!["Self".to_string()] } else { - "Type" + // Find all the types that have an `impl` for the trait. + tcx.all_impls(trait_def_id) + .filter(|impl_def_id| { + // Consider only accessible traits + tcx.visibility(*impl_def_id).is_accessible_from(self.item_def_id(), tcx) + && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative + }) + .filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id)) + .map(|impl_| impl_.self_ty()) + // We don't care about blanket impls. + .filter(|self_ty| !self_ty.has_non_region_param()) + .map(|self_ty| tcx.erase_regions(self_ty).to_string()) + .collect() }; - + // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that + // references the trait. Relevant for the first case in + // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs` let reported = self.report_ambiguous_associated_type( span, - type_name, - &path_str, + &type_names, + &[path_str], item_segment.ident.name, ); return tcx.ty_error_with_guaranteed(reported) diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed b/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed new file mode 100644 index 0000000000000..23f7152004008 --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.fixed @@ -0,0 +1,14 @@ +// run-rustfix +trait Trait {} + +trait Assoc { + type Ty; +} + +impl Assoc for dyn Trait { + type Ty = i32; +} + +fn main() { + let _x: as Assoc>::Ty; //~ ERROR ambiguous associated type +} diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs b/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs new file mode 100644 index 0000000000000..9c26e339a449b --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.rs @@ -0,0 +1,14 @@ +// run-rustfix +trait Trait {} + +trait Assoc { + type Ty; +} + +impl Assoc for dyn Trait { + type Ty = i32; +} + +fn main() { + let _x: >::Ty; //~ ERROR ambiguous associated type +} diff --git a/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr b/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr new file mode 100644 index 0000000000000..97088b79fd671 --- /dev/null +++ b/tests/ui/associated-item/ambiguous-associated-type-with-generics.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/ambiguous-associated-type-with-generics.rs:13:13 + | +LL | let _x: >::Ty; + | ^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: ` as Assoc>::Ty` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. diff --git a/tests/ui/associated-item/associated-item-duplicate-names-3.stderr b/tests/ui/associated-item/associated-item-duplicate-names-3.stderr index bf4bd634cf1d4..d0c170620766c 100644 --- a/tests/ui/associated-item/associated-item-duplicate-names-3.stderr +++ b/tests/ui/associated-item/associated-item-duplicate-names-3.stderr @@ -13,7 +13,7 @@ error[E0223]: ambiguous associated type --> $DIR/associated-item-duplicate-names-3.rs:18:12 | LL | let x: Baz::Bar = 5; - | ^^^^^^^^ help: use fully-qualified syntax: `::Bar` + | ^^^^^^^^ help: use the fully-qualified path: `::Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index 289911779ff71..00856b55df5ec 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -2,31 +2,46 @@ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:6:36 | LL | fn get(x: T, y: U) -> Get::Value {} - | ^^^^^^^^^^ help: use fully-qualified syntax: `::Value` + | ^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path + | +LL | fn get(x: T, y: U) -> ::Value {} + | ~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:20:17 | LL | trait Foo where Foo::Assoc: Bar { - | ^^^^^^^^^^ help: use fully-qualified syntax: `::Assoc` + | ^^^^^^^^^^ help: use the fully-qualified path: `::Assoc` error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:25:10 | LL | type X = std::ops::Deref::Target; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::Target` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Deref`, you could use the fully-qualified path + | +LL | type X = ::Target; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:11:23 | LL | fn grab(&self) -> Grab::Value; - | ^^^^^^^^^^^ help: use fully-qualified syntax: `::Value` + | ^^^^^^^^^^^ help: use the fully-qualified path: `::Value` error[E0223]: ambiguous associated type --> $DIR/associated-types-in-ambiguous-context.rs:14:22 | LL | fn get(&self) -> Get::Value; - | ^^^^^^^^^^ help: use fully-qualified syntax: `::Value` + | ^^^^^^^^^^ + | +help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path + | +LL | fn get(&self) -> ::Value; + | ~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 5 previous errors diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr index 21f957ab549a3..55096e95df7e0 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr @@ -61,25 +61,45 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 | LL | type A = [u8; 4]::AssocTy; - | ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; 4] as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `[u8; 4]`, you could use the fully-qualified path + | +LL | type A = <[u8; 4] as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:5:10 | LL | type B = [u8]::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8] as Trait>::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `[u8]`, you could use the fully-qualified path + | +LL | type B = <[u8] as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:9:10 | LL | type C = (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type C = ::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:13:10 | LL | type D = (u8, u8)::AssocTy; - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(u8, u8) as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `(u8, u8)`, you could use the fully-qualified path + | +LL | type D = <(u8, u8) as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases --> $DIR/bad-assoc-ty.rs:17:10 @@ -91,13 +111,23 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:21:19 | LL | type F = &'static (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` + | ^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type F = &'static ::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:27:10 | LL | type G = dyn 'static + (Send)::AssocTy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Send + 'static) as Trait>::AssocTy` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `(dyn Send + 'static)`, you could use the fully-qualified path + | +LL | type G = <(dyn Send + 'static) as Example>::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bad-assoc-ty.rs:33:10 @@ -117,24 +147,33 @@ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:33:10 | LL | type H = Fn(u8) -> (u8)::Output; - | ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as Trait>::Output` + | ^^^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:39:19 | LL | ($ty: ty) => ($ty::AssocTy); - | ^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` + | ^^^^^^^^^^^^ ... LL | type J = ty!(u8); | ------- in this macro invocation | = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | ($ty: ty) => (::AssocTy); + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:46:10 | LL | type I = ty!()::AssocTy; - | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` + | ^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `AssocTy` implemented for `u8`, you could use the fully-qualified path + | +LL | type I = ::AssocTy; + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:51:13 diff --git a/tests/ui/error-codes/E0223.rs b/tests/ui/error-codes/E0223.rs index 6031b682d72a0..2fe252de25665 100644 --- a/tests/ui/error-codes/E0223.rs +++ b/tests/ui/error-codes/E0223.rs @@ -1,4 +1,8 @@ trait MyTrait { type X; } +struct MyStruct; +impl MyTrait for MyStruct { + type X = (); +} fn main() { let foo: MyTrait::X; diff --git a/tests/ui/error-codes/E0223.stderr b/tests/ui/error-codes/E0223.stderr index 726f39e11f134..42945e42f6ea1 100644 --- a/tests/ui/error-codes/E0223.stderr +++ b/tests/ui/error-codes/E0223.stderr @@ -1,8 +1,8 @@ error[E0223]: ambiguous associated type - --> $DIR/E0223.rs:4:14 + --> $DIR/E0223.rs:8:14 | LL | let foo: MyTrait::X; - | ^^^^^^^^^^ help: use fully-qualified syntax: `::X` + | ^^^^^^^^^^ help: use the fully-qualified path: `::X` error: aborting due to previous error diff --git a/tests/ui/impl-trait/impl_trait_projections.rs b/tests/ui/impl-trait/impl_trait_projections.rs index fd0986d7c0a9d..b3ff2ce5a7bfa 100644 --- a/tests/ui/impl-trait/impl_trait_projections.rs +++ b/tests/ui/impl-trait/impl_trait_projections.rs @@ -11,7 +11,7 @@ fn path_parametrized_type_is_allowed() -> option::Option { fn projection_is_disallowed(x: impl Iterator) -> ::Item { //~^ ERROR `impl Trait` is not allowed in path parameters -//~^^ ERROR ambiguous associated type +//~| ERROR `impl Trait` is not allowed in path parameters x.next().unwrap() } diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr index 82d2422c40779..4deb24731bc03 100644 --- a/tests/ui/impl-trait/impl_trait_projections.stderr +++ b/tests/ui/impl-trait/impl_trait_projections.stderr @@ -22,13 +22,12 @@ error[E0667]: `impl Trait` is not allowed in path parameters LL | -> as Iterator>::Item | ^^^^^^^^^^ -error[E0223]: ambiguous associated type - --> $DIR/impl_trait_projections.rs:12:50 +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/impl_trait_projections.rs:12:51 | LL | fn projection_is_disallowed(x: impl Iterator) -> ::Item { - | ^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::Item` + | ^^^^^^^^^^^^^ error: aborting due to 5 previous errors -Some errors have detailed explanations: E0223, E0667. -For more information about an error, try `rustc --explain E0223`. +For more information about this error, try `rustc --explain E0667`. diff --git a/tests/ui/issues/issue-23073.stderr b/tests/ui/issues/issue-23073.stderr index 3a10a1ab11ac5..3a9f49ef167d6 100644 --- a/tests/ui/issues/issue-23073.stderr +++ b/tests/ui/issues/issue-23073.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-23073.rs:6:17 | LL | type FooT = <::Foo>::T; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::Foo as Trait>::T` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `T` implemented for `::Foo`, you could use the fully-qualified path + | +LL | type FooT = <::Foo as Example>::T; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/issues/issue-78622.stderr b/tests/ui/issues/issue-78622.stderr index f7d44f21d3bec..70daf8a2f1a64 100644 --- a/tests/ui/issues/issue-78622.stderr +++ b/tests/ui/issues/issue-78622.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-78622.rs:5:5 | LL | S::A:: {} - | ^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `A` implemented for `S`, you could use the fully-qualified path + | +LL | ::A:: {} + | ~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr index 8ed303ca6069c..a19f4963c239b 100644 --- a/tests/ui/lint/bare-trait-objects-path.stderr +++ b/tests/ui/lint/bare-trait-objects-path.stderr @@ -16,7 +16,7 @@ error[E0223]: ambiguous associated type --> $DIR/bare-trait-objects-path.rs:23:12 | LL | let _: Dyn::Ty; - | ^^^^^^^ help: use fully-qualified syntax: `::Ty` + | ^^^^^^^ help: use the fully-qualified path: `::Ty` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/bare-trait-objects-path.rs:14:5 diff --git a/tests/ui/qualified/qualified-path-params-2.stderr b/tests/ui/qualified/qualified-path-params-2.stderr index 948f21fce4bdb..b6cf19b8286cc 100644 --- a/tests/ui/qualified/qualified-path-params-2.stderr +++ b/tests/ui/qualified/qualified-path-params-2.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/qualified-path-params-2.rs:18:10 | LL | type A = ::A::f; - | ^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::A as Trait>::f` + | ^^^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `f` implemented for `::A`, you could use the fully-qualified path + | +LL | type A = <::A as Example>::f; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/resolve/issue-103202.stderr b/tests/ui/resolve/issue-103202.stderr index 880389371ef70..d4d141fb06f39 100644 --- a/tests/ui/resolve/issue-103202.stderr +++ b/tests/ui/resolve/issue-103202.stderr @@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type --> $DIR/issue-103202.rs:4:17 | LL | fn f(self: &S::x) {} - | ^^^^ help: use fully-qualified syntax: `::x` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `x` implemented for `S`, you could use the fully-qualified path + | +LL | fn f(self: &::x) {} + | ~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/tests/ui/self/self-impl.stderr b/tests/ui/self/self-impl.stderr index fb47f27e022f5..36372b644d6e1 100644 --- a/tests/ui/self/self-impl.stderr +++ b/tests/ui/self/self-impl.stderr @@ -2,13 +2,13 @@ error[E0223]: ambiguous associated type --> $DIR/self-impl.rs:23:16 | LL | let _: ::Baz = true; - | ^^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` + | ^^^^^^^^^^^ help: use the fully-qualified path: `::Baz` error[E0223]: ambiguous associated type --> $DIR/self-impl.rs:25:16 | LL | let _: Self::Baz = true; - | ^^^^^^^^^ help: use fully-qualified syntax: `::Baz` + | ^^^^^^^^^ help: use the fully-qualified path: `::Baz` error: aborting due to 2 previous errors diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr index abb445214f362..ca5f0b7e21e7d 100644 --- a/tests/ui/structs/struct-path-associated-type.stderr +++ b/tests/ui/structs/struct-path-associated-type.stderr @@ -48,19 +48,19 @@ error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:32:13 | LL | let s = S::A {}; - | ^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ help: use the fully-qualified path: `::A` error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:33:13 | LL | let z = S::A:: {}; - | ^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ help: use the fully-qualified path: `::A` error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:35:9 | LL | S::A {} => {} - | ^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ help: use the fully-qualified path: `::A` error: aborting due to 8 previous errors diff --git a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr index 2bf072ef52175..b90ae051fb776 100644 --- a/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr +++ b/tests/ui/suggestions/let-binding-init-expr-as-ty.stderr @@ -21,7 +21,12 @@ error[E0223]: ambiguous associated type --> $DIR/let-binding-init-expr-as-ty.rs:2:14 | LL | let foo: i32::from_be(num); - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::from_be` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `from_be` implemented for `i32`, you could use the fully-qualified path + | +LL | let foo: ::from_be; + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index f137a298a7f41..293cfbda86c49 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -148,19 +148,24 @@ error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:115:12 | LL | let _: S::A; - | ^^^^ help: use fully-qualified syntax: `::A` + | ^^^^ + | +help: if there were a trait named `Example` with associated type `A` implemented for `S`, you could use the fully-qualified path + | +LL | let _: ::A; + | ~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:116:12 | LL | let _: S::B; - | ^^^^ help: use fully-qualified syntax: `::B` + | ^^^^ help: use the fully-qualified path: `::B` error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:117:12 | LL | let _: S::C; - | ^^^^ help: use fully-qualified syntax: `::C` + | ^^^^ help: use the fully-qualified path: `::C` error[E0624]: associated type `A` is private --> $DIR/item-privacy.rs:119:12 diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index 5f7f6aa9f6ec6..72fccea8ae399 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -205,7 +205,12 @@ error[E0223]: ambiguous associated type --> $DIR/ufcs-partially-resolved.rs:36:12 | LL | let _: ::Y::NN; - | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::Y as Trait>::NN` + | ^^^^^^^^^^^^^^^^^ + | +help: if there were a trait named `Example` with associated type `NN` implemented for `::Y`, you could use the fully-qualified path + | +LL | let _: <::Y as Example>::NN; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0599]: no associated item named `NN` found for type `u16` in the current scope --> $DIR/ufcs-partially-resolved.rs:38:20