When suggesting writing a fully qualified path probe for appropriate types
Fix #46585.
This commit is contained in:
parent
b22c152958
commit
12ddf77811
18 changed files with 295 additions and 55 deletions
|
@ -24,6 +24,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
||||||
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
||||||
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
||||||
use rustc_middle::ty::GenericParamDefKind;
|
use rustc_middle::ty::GenericParamDefKind;
|
||||||
|
@ -1633,8 +1634,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
fn report_ambiguous_associated_type(
|
fn report_ambiguous_associated_type(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
type_str: &str,
|
types: &[String],
|
||||||
trait_str: &str,
|
traits: &[String],
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
|
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()
|
.keys()
|
||||||
.any(|full_span| full_span.contains(span))
|
.any(|full_span| full_span.contains(span))
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion_verbose(
|
||||||
span.shrink_to_lo(),
|
span.shrink_to_lo(),
|
||||||
"you are looking for the module in `std`, not the primitive type",
|
"you are looking for the module in `std`, not the primitive type",
|
||||||
"std::",
|
"std::",
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
err.span_suggestion(
|
match (types, traits) {
|
||||||
span,
|
([], []) => {
|
||||||
"use fully-qualified syntax",
|
err.span_suggestion_verbose(
|
||||||
format!("<{} as {}>::{}", type_str, trait_str, name),
|
span,
|
||||||
Applicability::HasPlaceholders,
|
&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!("<Type as Trait>::{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!("<Example as {trait_str}>::{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!("<Example as {trait_str}>::{name}"))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
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()
|
err.emit()
|
||||||
}
|
}
|
||||||
|
@ -2040,12 +2114,67 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
err.emit()
|
err.emit()
|
||||||
} else if let Err(reported) = qself_ty.error_reported() {
|
} else if let Err(reported) = qself_ty.error_reported() {
|
||||||
reported
|
reported
|
||||||
|
} else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() {
|
||||||
|
// `<impl Trait as OtherTrait>::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 {
|
} 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::new(
|
||||||
|
ty::List::empty(),
|
||||||
|
traits::Reveal::All,
|
||||||
|
hir::Constness::NotConst,
|
||||||
|
);
|
||||||
|
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()
|
||||||
|
.find(|i| {
|
||||||
|
i.kind.namespace() == Namespace::TypeNS
|
||||||
|
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
|
||||||
|
&& matches!(i.kind, ty::AssocKind::Type)
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
// Consider only accessible traits
|
||||||
|
&& tcx.visibility(*trait_def_id)
|
||||||
|
.is_accessible_from(self.item_def_id(), tcx)
|
||||||
|
&& tcx.all_impls(*trait_def_id)
|
||||||
|
.filter(|impl_def_id| {
|
||||||
|
let trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||||
|
trait_ref.map_or(false, |impl_| {
|
||||||
|
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
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.is_some()
|
||||||
|
})
|
||||||
|
.map(|trait_def_id| tcx.def_path_str(trait_def_id))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Don't print `TyErr` to the user.
|
// Don't print `TyErr` to the user.
|
||||||
self.report_ambiguous_associated_type(
|
self.report_ambiguous_associated_type(
|
||||||
span,
|
span,
|
||||||
&qself_ty.to_string(),
|
&[qself_ty.to_string()],
|
||||||
"Trait",
|
&traits,
|
||||||
assoc_ident.name,
|
assoc_ident.name,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -2163,16 +2292,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let is_part_of_self_trait_constraints = def_id == trait_def_id;
|
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 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 {
|
let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
|
||||||
"Self"
|
vec!["Self".to_string()]
|
||||||
} else {
|
} 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_infer())
|
||||||
|
.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(
|
let reported = self.report_ambiguous_associated_type(
|
||||||
span,
|
span,
|
||||||
type_name,
|
&type_names,
|
||||||
&path_str,
|
&[path_str],
|
||||||
item_segment.ident.name,
|
item_segment.ident.name,
|
||||||
);
|
);
|
||||||
return tcx.ty_error_with_guaranteed(reported)
|
return tcx.ty_error_with_guaranteed(reported)
|
||||||
|
|
|
@ -13,7 +13,7 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-item-duplicate-names-3.rs:18:12
|
--> $DIR/associated-item-duplicate-names-3.rs:18:12
|
||||||
|
|
|
|
||||||
LL | let x: Baz::Bar = 5;
|
LL | let x: Baz::Bar = 5;
|
||||||
| ^^^^^^^^ help: use fully-qualified syntax: `<Baz as Trait>::Bar`
|
| ^^^^^^^^ help: use the fully-qualified path: `<Baz as Foo>::Bar`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,46 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-types-in-ambiguous-context.rs:6:36
|
--> $DIR/associated-types-in-ambiguous-context.rs:6:36
|
||||||
|
|
|
|
||||||
LL | fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
|
LL | fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
|
||||||
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value`
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | fn get<T:Get,U:Get>(x: T, y: U) -> <Example as Get>::Value {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-types-in-ambiguous-context.rs:20:17
|
--> $DIR/associated-types-in-ambiguous-context.rs:20:17
|
||||||
|
|
|
|
||||||
LL | trait Foo where Foo::Assoc: Bar {
|
LL | trait Foo where Foo::Assoc: Bar {
|
||||||
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`
|
| ^^^^^^^^^^ help: use the fully-qualified path: `<Self as Foo>::Assoc`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-types-in-ambiguous-context.rs:25:10
|
--> $DIR/associated-types-in-ambiguous-context.rs:25:10
|
||||||
|
|
|
|
||||||
LL | type X = std::ops::Deref::Target;
|
LL | type X = std::ops::Deref::Target;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Deref>::Target`
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a type named `Example` that implemented `Deref`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | type X = <Example as Deref>::Target;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-types-in-ambiguous-context.rs:11:23
|
--> $DIR/associated-types-in-ambiguous-context.rs:11:23
|
||||||
|
|
|
|
||||||
LL | fn grab(&self) -> Grab::Value;
|
LL | fn grab(&self) -> Grab::Value;
|
||||||
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
|
| ^^^^^^^^^^^ help: use the fully-qualified path: `<Self as Grab>::Value`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/associated-types-in-ambiguous-context.rs:14:22
|
--> $DIR/associated-types-in-ambiguous-context.rs:14:22
|
||||||
|
|
|
|
||||||
LL | fn get(&self) -> Get::Value;
|
LL | fn get(&self) -> Get::Value;
|
||||||
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value`
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a type named `Example` that implemented `Get`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | fn get(&self) -> <Example as Get>::Value;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -61,25 +61,45 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:1:10
|
--> $DIR/bad-assoc-ty.rs:1:10
|
||||||
|
|
|
|
||||||
LL | type A = [u8; 4]::AssocTy;
|
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
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:5:10
|
--> $DIR/bad-assoc-ty.rs:5:10
|
||||||
|
|
|
|
||||||
LL | type B = [u8]::AssocTy;
|
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
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:9:10
|
--> $DIR/bad-assoc-ty.rs:9:10
|
||||||
|
|
|
|
||||||
LL | type C = (u8)::AssocTy;
|
LL | type C = (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 C = <u8 as Example>::AssocTy;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:13:10
|
--> $DIR/bad-assoc-ty.rs:13:10
|
||||||
|
|
|
|
||||||
LL | type D = (u8, u8)::AssocTy;
|
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
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases
|
||||||
--> $DIR/bad-assoc-ty.rs:17:10
|
--> $DIR/bad-assoc-ty.rs:17:10
|
||||||
|
@ -91,13 +111,23 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:21:19
|
--> $DIR/bad-assoc-ty.rs:21:19
|
||||||
|
|
|
|
||||||
LL | type F = &'static (u8)::AssocTy;
|
LL | type F = &'static (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 F = &'static <u8 as Example>::AssocTy;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:27:10
|
--> $DIR/bad-assoc-ty.rs:27:10
|
||||||
|
|
|
|
||||||
LL | type G = dyn 'static + (Send)::AssocTy;
|
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
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
--> $DIR/bad-assoc-ty.rs:33:10
|
--> $DIR/bad-assoc-ty.rs:33:10
|
||||||
|
@ -117,24 +147,38 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:33:10
|
--> $DIR/bad-assoc-ty.rs:33:10
|
||||||
|
|
|
|
||||||
LL | type H = Fn(u8) -> (u8)::Output;
|
LL | type H = Fn(u8) -> (u8)::Output;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn Fn(u8) -> u8 + 'static) as Trait>::Output`
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a trait named `Example` with associated type `Output` implemented for `(dyn Fn(u8) -> u8 + 'static)`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as Example>::Output;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:39:19
|
--> $DIR/bad-assoc-ty.rs:39:19
|
||||||
|
|
|
|
||||||
LL | ($ty: ty) => ($ty::AssocTy);
|
LL | ($ty: ty) => ($ty::AssocTy);
|
||||||
| ^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
|
| ^^^^^^^^^^^^
|
||||||
...
|
...
|
||||||
LL | type J = ty!(u8);
|
LL | type J = ty!(u8);
|
||||||
| ------- in this macro invocation
|
| ------- in this macro invocation
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= 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) => (<u8 as Example>::AssocTy);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bad-assoc-ty.rs:46:10
|
--> $DIR/bad-assoc-ty.rs:46:10
|
||||||
|
|
|
|
||||||
LL | type I = ty!()::AssocTy;
|
LL | type I = ty!()::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 I = <u8 as Example>::AssocTy;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
|
||||||
--> $DIR/bad-assoc-ty.rs:51:13
|
--> $DIR/bad-assoc-ty.rs:51:13
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
trait MyTrait { type X; }
|
trait MyTrait { type X; }
|
||||||
|
struct MyStruct;
|
||||||
|
impl MyTrait for MyStruct {
|
||||||
|
type X = ();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let foo: MyTrait::X;
|
let foo: MyTrait::X;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/E0223.rs:4:14
|
--> $DIR/E0223.rs:8:14
|
||||||
|
|
|
|
||||||
LL | let foo: MyTrait::X;
|
LL | let foo: MyTrait::X;
|
||||||
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as MyTrait>::X`
|
| ^^^^^^^^^^ help: use the fully-qualified path: `<MyStruct as MyTrait>::X`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> {
|
||||||
|
|
||||||
fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ 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()
|
x.next().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,12 @@ error[E0667]: `impl Trait` is not allowed in path parameters
|
||||||
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0667]: `impl Trait` is not allowed in path parameters
|
||||||
--> $DIR/impl_trait_projections.rs:12:50
|
--> $DIR/impl_trait_projections.rs:12:51
|
||||||
|
|
|
|
||||||
LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<impl Iterator as Trait>::Item`
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0223, E0667.
|
For more information about this error, try `rustc --explain E0667`.
|
||||||
For more information about an error, try `rustc --explain E0223`.
|
|
||||||
|
|
|
@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/issue-23073.rs:6:17
|
--> $DIR/issue-23073.rs:6:17
|
||||||
|
|
|
|
||||||
LL | type FooT = <<Self as Bar>::Foo>::T;
|
LL | type FooT = <<Self as Bar>::Foo>::T;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<Self as Bar>::Foo as Trait>::T`
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a trait named `Example` with associated type `T` implemented for `<Self as Bar>::Foo`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | type FooT = <<Self as Bar>::Foo as Example>::T;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/issue-78622.rs:5:5
|
--> $DIR/issue-78622.rs:5:5
|
||||||
|
|
|
|
||||||
LL | S::A::<f> {}
|
LL | S::A::<f> {}
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: if there were a trait named `Example` with associated type `A` implemented for `S`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | <S as Example>::A::<f> {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/bare-trait-objects-path.rs:23:12
|
--> $DIR/bare-trait-objects-path.rs:23:12
|
||||||
|
|
|
|
||||||
LL | let _: Dyn::Ty;
|
LL | let _: Dyn::Ty;
|
||||||
| ^^^^^^^ help: use fully-qualified syntax: `<dyn Dyn as Trait>::Ty`
|
| ^^^^^^^ help: use the fully-qualified path: `<dyn Dyn as Assoc>::Ty`
|
||||||
|
|
||||||
warning: trait objects without an explicit `dyn` are deprecated
|
warning: trait objects without an explicit `dyn` are deprecated
|
||||||
--> $DIR/bare-trait-objects-path.rs:14:5
|
--> $DIR/bare-trait-objects-path.rs:14:5
|
||||||
|
|
|
@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/qualified-path-params-2.rs:18:10
|
--> $DIR/qualified-path-params-2.rs:18:10
|
||||||
|
|
|
|
||||||
LL | type A = <S as Tr>::A::f<u8>;
|
LL | type A = <S as Tr>::A::f<u8>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<S as Tr>::A as Trait>::f`
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a trait named `Example` with associated type `f` implemented for `<S as Tr>::A`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | type A = <<S as Tr>::A as Example>::f;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/issue-103202.rs:4:17
|
--> $DIR/issue-103202.rs:4:17
|
||||||
|
|
|
|
||||||
LL | fn f(self: &S::x) {}
|
LL | fn f(self: &S::x) {}
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::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: &<S as Example>::x) {}
|
||||||
|
| ~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/self-impl.rs:23:16
|
--> $DIR/self-impl.rs:23:16
|
||||||
|
|
|
|
||||||
LL | let _: <Self>::Baz = true;
|
LL | let _: <Self>::Baz = true;
|
||||||
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Trait>::Baz`
|
| ^^^^^^^^^^^ help: use the fully-qualified path: `<Bar as Foo>::Baz`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/self-impl.rs:25:16
|
--> $DIR/self-impl.rs:25:16
|
||||||
|
|
|
|
||||||
LL | let _: Self::Baz = true;
|
LL | let _: Self::Baz = true;
|
||||||
| ^^^^^^^^^ help: use fully-qualified syntax: `<Bar as Trait>::Baz`
|
| ^^^^^^^^^ help: use the fully-qualified path: `<Bar as Foo>::Baz`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -48,19 +48,19 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/struct-path-associated-type.rs:32:13
|
--> $DIR/struct-path-associated-type.rs:32:13
|
||||||
|
|
|
|
||||||
LL | let s = S::A {};
|
LL | let s = S::A {};
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
|
| ^^^^ help: use the fully-qualified path: `<S as Tr>::A`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/struct-path-associated-type.rs:33:13
|
--> $DIR/struct-path-associated-type.rs:33:13
|
||||||
|
|
|
|
||||||
LL | let z = S::A::<u8> {};
|
LL | let z = S::A::<u8> {};
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
|
| ^^^^ help: use the fully-qualified path: `<S as Tr>::A`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/struct-path-associated-type.rs:35:9
|
--> $DIR/struct-path-associated-type.rs:35:9
|
||||||
|
|
|
|
||||||
LL | S::A {} => {}
|
LL | S::A {} => {}
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
|
| ^^^^ help: use the fully-qualified path: `<S as Tr>::A`
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/let-binding-init-expr-as-ty.rs:2:14
|
--> $DIR/let-binding-init-expr-as-ty.rs:2:14
|
||||||
|
|
|
|
||||||
LL | let foo: i32::from_be(num);
|
LL | let foo: i32::from_be(num);
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<i32 as Trait>::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: <i32 as Example>::from_be;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -148,19 +148,24 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/item-privacy.rs:115:12
|
--> $DIR/item-privacy.rs:115:12
|
||||||
|
|
|
|
||||||
LL | let _: S::A;
|
LL | let _: S::A;
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::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 _: <S as Example>::A;
|
||||||
|
| ~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/item-privacy.rs:116:12
|
--> $DIR/item-privacy.rs:116:12
|
||||||
|
|
|
|
||||||
LL | let _: S::B;
|
LL | let _: S::B;
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::B`
|
| ^^^^ help: use the fully-qualified path: `<S as assoc_ty::B>::B`
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
error[E0223]: ambiguous associated type
|
||||||
--> $DIR/item-privacy.rs:117:12
|
--> $DIR/item-privacy.rs:117:12
|
||||||
|
|
|
|
||||||
LL | let _: S::C;
|
LL | let _: S::C;
|
||||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::C`
|
| ^^^^ help: use the fully-qualified path: `<S as assoc_ty::C>::C`
|
||||||
|
|
||||||
error[E0624]: associated type `A` is private
|
error[E0624]: associated type `A` is private
|
||||||
--> $DIR/item-privacy.rs:119:12
|
--> $DIR/item-privacy.rs:119:12
|
||||||
|
|
|
@ -205,7 +205,12 @@ error[E0223]: ambiguous associated type
|
||||||
--> $DIR/ufcs-partially-resolved.rs:36:12
|
--> $DIR/ufcs-partially-resolved.rs:36:12
|
||||||
|
|
|
|
||||||
LL | let _: <u8 as Tr>::Y::NN;
|
LL | let _: <u8 as Tr>::Y::NN;
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<<u8 as Tr>::Y as Trait>::NN`
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if there were a trait named `Example` with associated type `NN` implemented for `<u8 as Tr>::Y`, you could use the fully-qualified path
|
||||||
|
|
|
||||||
|
LL | let _: <<u8 as Tr>::Y as Example>::NN;
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0599]: no associated item named `NN` found for type `u16` in the current scope
|
error[E0599]: no associated item named `NN` found for type `u16` in the current scope
|
||||||
--> $DIR/ufcs-partially-resolved.rs:38:20
|
--> $DIR/ufcs-partially-resolved.rs:38:20
|
||||||
|
|
Loading…
Add table
Reference in a new issue