Handle more specific case E0222
This commit is contained in:
parent
8e74f63054
commit
66ea471f9d
7 changed files with 167 additions and 60 deletions
|
@ -116,6 +116,7 @@ E0211: include_str!("./error_codes/E0211.md"),
|
||||||
E0214: include_str!("./error_codes/E0214.md"),
|
E0214: include_str!("./error_codes/E0214.md"),
|
||||||
E0220: include_str!("./error_codes/E0220.md"),
|
E0220: include_str!("./error_codes/E0220.md"),
|
||||||
E0221: include_str!("./error_codes/E0221.md"),
|
E0221: include_str!("./error_codes/E0221.md"),
|
||||||
|
E0222: include_str!("./error_codes/E0222.md"),
|
||||||
E0223: include_str!("./error_codes/E0223.md"),
|
E0223: include_str!("./error_codes/E0223.md"),
|
||||||
E0225: include_str!("./error_codes/E0225.md"),
|
E0225: include_str!("./error_codes/E0225.md"),
|
||||||
E0229: include_str!("./error_codes/E0229.md"),
|
E0229: include_str!("./error_codes/E0229.md"),
|
||||||
|
@ -457,8 +458,6 @@ E0745: include_str!("./error_codes/E0745.md"),
|
||||||
// E0217, // ambiguous associated type, defined in multiple supertraits
|
// E0217, // ambiguous associated type, defined in multiple supertraits
|
||||||
// E0218, // no associated type defined
|
// E0218, // no associated type defined
|
||||||
// E0219, // associated type defined in higher-ranked supertrait
|
// E0219, // associated type defined in higher-ranked supertrait
|
||||||
// E0222, // Error code E0045 (variadic function must have C or cdecl calling
|
|
||||||
// convention) duplicate
|
|
||||||
E0224, // at least one non-builtin train is required for an object type
|
E0224, // at least one non-builtin train is required for an object type
|
||||||
E0226, // only a single explicit lifetime bound is permitted
|
E0226, // only a single explicit lifetime bound is permitted
|
||||||
E0227, // ambiguous lifetime bound, explicit lifetime bound required
|
E0227, // ambiguous lifetime bound, explicit lifetime bound required
|
||||||
|
|
51
src/librustc_error_codes/error_codes/E0222.md
Normal file
51
src/librustc_error_codes/error_codes/E0222.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
An attempt was made to constrain an associated type.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```compile_fail,E0222
|
||||||
|
pub trait Vehicle {
|
||||||
|
type Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Box {
|
||||||
|
type Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait BoxCar : Box + Vehicle {}
|
||||||
|
|
||||||
|
fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {} // Invalid constraint
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, `BoxCar` has two super-traits: `Vehicle` and `Box`. Both of
|
||||||
|
these traits define an associated type `Color`. `BoxCar` inherits two types
|
||||||
|
with that name from both super-traits. Because of this, we need to use the
|
||||||
|
fully qualified path syntax to refer to the appropriate `Color` associated
|
||||||
|
type, either `<BoxCar as Vehicle>::Color` or `<BoxCar as Box>::Color`, but this
|
||||||
|
syntax is not allowed to be used in a function signature.
|
||||||
|
|
||||||
|
In order to encode this kind of constraint, a `where` clause and a new type
|
||||||
|
parameter are needed:
|
||||||
|
|
||||||
|
```
|
||||||
|
pub trait Vehicle {
|
||||||
|
type Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Box {
|
||||||
|
type Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait BoxCar : Box + Vehicle {}
|
||||||
|
|
||||||
|
// Introduce a new `CAR` type parameter
|
||||||
|
fn foo<CAR, COLOR>(
|
||||||
|
c: CAR,
|
||||||
|
) where
|
||||||
|
// Bind the type parameter `CAR` to the trait `BoxCar`
|
||||||
|
CAR: BoxCar,
|
||||||
|
// Further restrict `<BoxCar as Vehicle>::Color` to be the same as the
|
||||||
|
// type parameter `COLOR`
|
||||||
|
CAR: Vehicle<Color = COLOR>,
|
||||||
|
// We can also simultaneously restrict the other trait's associated type
|
||||||
|
CAR: Box<Color = COLOR>
|
||||||
|
{}
|
||||||
|
```
|
|
@ -804,6 +804,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
predicate.span,
|
predicate.span,
|
||||||
"equality constraints are not yet supported in `where` clauses",
|
"equality constraints are not yet supported in `where` clauses",
|
||||||
)
|
)
|
||||||
|
.span_label(predicate.span, "not supported")
|
||||||
.note(
|
.note(
|
||||||
"for more information, see https://github.com/rust-lang/rust/issues/20041",
|
"for more information, see https://github.com/rust-lang/rust/issues/20041",
|
||||||
)
|
)
|
||||||
|
|
|
@ -1267,7 +1267,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let candidate =
|
let candidate =
|
||||||
if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
|
if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
|
||||||
// Simple case: X is defined in the current trait.
|
// Simple case: X is defined in the current trait.
|
||||||
Ok(trait_ref)
|
trait_ref
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we have to walk through the supertraits to find
|
// Otherwise, we have to walk through the supertraits to find
|
||||||
// those that do.
|
// those that do.
|
||||||
|
@ -1276,8 +1276,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&trait_ref.print_only_trait_path().to_string(),
|
&trait_ref.print_only_trait_path().to_string(),
|
||||||
binding.item_name,
|
binding.item_name,
|
||||||
path_span,
|
path_span,
|
||||||
)
|
match binding.kind {
|
||||||
}?;
|
ConvertedBindingKind::Equality(ty) => Some(ty.to_string()),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
let (assoc_ident, def_scope) =
|
let (assoc_ident, def_scope) =
|
||||||
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
||||||
|
@ -1626,20 +1630,31 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
let mut suggestions_len = suggestions.len();
|
let mut suggestions_len = suggestions.len();
|
||||||
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sugg_span) {
|
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sugg_span) {
|
||||||
if potential_assoc_types.is_empty() && trait_bounds.len() == 1 &&
|
let assoc_types: Vec<String> = associated_types
|
||||||
|
.iter()
|
||||||
|
.map(|item_def_id| {
|
||||||
|
let assoc_item = tcx.associated_item(*item_def_id);
|
||||||
|
format!("{} = Type", assoc_item.ident)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let dedup = assoc_types.clone().drain(..).collect::<FxHashSet<_>>();
|
||||||
|
|
||||||
|
if dedup.len() != assoc_types.len() && trait_bounds.len() == 1 {
|
||||||
|
// If there are duplicates associated type names and a single trait bound do not
|
||||||
|
// use structured suggestion, it means that there are multiple super-traits with
|
||||||
|
// the same associated type name.
|
||||||
|
err.help(
|
||||||
|
"consider introducing a new type parameter, adding `where` constraints \
|
||||||
|
using the fully-qualified path to the associated type",
|
||||||
|
);
|
||||||
|
} else if dedup.len() == assoc_types.len() &&
|
||||||
|
potential_assoc_types.is_empty() &&
|
||||||
|
trait_bounds.len() == 1 &&
|
||||||
// Do not attempt to suggest when we don't know which path segment needs the
|
// Do not attempt to suggest when we don't know which path segment needs the
|
||||||
// type parameter set.
|
// type parameter set.
|
||||||
trait_bounds[0].trait_ref.path.segments.len() == 1
|
trait_bounds[0].trait_ref.path.segments.len() == 1
|
||||||
{
|
{
|
||||||
debug!("path segments {:?}", trait_bounds[0].trait_ref.path.segments);
|
|
||||||
applicability = Applicability::HasPlaceholders;
|
applicability = Applicability::HasPlaceholders;
|
||||||
let assoc_types: Vec<String> = associated_types
|
|
||||||
.iter()
|
|
||||||
.map(|item_def_id| {
|
|
||||||
let assoc_item = tcx.associated_item(*item_def_id);
|
|
||||||
format!("{} = Type", assoc_item.ident)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let sugg = assoc_types.join(", ");
|
let sugg = assoc_types.join(", ");
|
||||||
if snippet.ends_with('>') {
|
if snippet.ends_with('>') {
|
||||||
// The user wrote `Trait<'a>` or similar and we don't have a type we can
|
// The user wrote `Trait<'a>` or similar and we don't have a type we can
|
||||||
|
@ -1666,7 +1681,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
err.span_label(
|
err.span_label(
|
||||||
span,
|
sugg_span,
|
||||||
format!(
|
format!(
|
||||||
"associated type{} {} must be specified",
|
"associated type{} {} must be specified",
|
||||||
pluralize!(associated_types.len()),
|
pluralize!(associated_types.len()),
|
||||||
|
@ -1743,15 +1758,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
¶m_name.as_str(),
|
¶m_name.as_str(),
|
||||||
assoc_name,
|
assoc_name,
|
||||||
span,
|
span,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks that `bounds` contains exactly one element and reports appropriate
|
||||||
|
// errors otherwise.
|
||||||
fn one_bound_for_assoc_type<I>(
|
fn one_bound_for_assoc_type<I>(
|
||||||
&self,
|
&self,
|
||||||
all_candidates: impl Fn() -> I,
|
all_candidates: impl Fn() -> I,
|
||||||
ty_param_name: &str,
|
ty_param_name: &str,
|
||||||
assoc_name: ast::Ident,
|
assoc_name: ast::Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
is_equality: Option<String>,
|
||||||
) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
@ -1778,16 +1797,29 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
|
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
|
||||||
|
|
||||||
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
|
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
|
||||||
let mut err = struct_span_err!(
|
let mut err = if is_equality.is_some() {
|
||||||
self.tcx().sess,
|
// More specific Error Index entry.
|
||||||
span,
|
struct_span_err!(
|
||||||
E0221,
|
self.tcx().sess,
|
||||||
"ambiguous associated type `{}` in bounds of `{}`",
|
span,
|
||||||
assoc_name,
|
E0222,
|
||||||
ty_param_name
|
"ambiguous associated type `{}` in bounds of `{}`",
|
||||||
);
|
assoc_name,
|
||||||
|
ty_param_name
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
struct_span_err!(
|
||||||
|
self.tcx().sess,
|
||||||
|
span,
|
||||||
|
E0221,
|
||||||
|
"ambiguous associated type `{}` in bounds of `{}`",
|
||||||
|
assoc_name,
|
||||||
|
ty_param_name
|
||||||
|
)
|
||||||
|
};
|
||||||
err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
|
err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
|
||||||
|
|
||||||
|
let mut where_bounds = vec![];
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
let bound_span = self
|
let bound_span = self
|
||||||
.tcx()
|
.tcx()
|
||||||
|
@ -1807,17 +1839,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
bound.print_only_trait_path(),
|
bound.print_only_trait_path(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
err.span_suggestion(
|
if let Some(constraint) = &is_equality {
|
||||||
span,
|
where_bounds.push(format!(
|
||||||
"use fully qualified syntax to disambiguate",
|
" T: {trait}::{assoc} = {constraint}",
|
||||||
format!(
|
trait=bound.print_only_trait_path(),
|
||||||
"<{} as {}>::{}",
|
assoc=assoc_name,
|
||||||
ty_param_name,
|
constraint=constraint,
|
||||||
bound.print_only_trait_path(),
|
));
|
||||||
assoc_name,
|
} else {
|
||||||
),
|
err.span_suggestion(
|
||||||
Applicability::MaybeIncorrect,
|
span,
|
||||||
);
|
"use fully qualified syntax to disambiguate",
|
||||||
|
format!(
|
||||||
|
"<{} as {}>::{}",
|
||||||
|
ty_param_name,
|
||||||
|
bound.print_only_trait_path(),
|
||||||
|
assoc_name,
|
||||||
|
),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err.note(&format!(
|
err.note(&format!(
|
||||||
"associated type `{}` could derive from `{}`",
|
"associated type `{}` could derive from `{}`",
|
||||||
|
@ -1826,9 +1867,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !where_bounds.is_empty() {
|
||||||
|
err.help(&format!(
|
||||||
|
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
||||||
|
\n where\n T: {},\n{}",
|
||||||
|
ty_param_name,
|
||||||
|
where_bounds.join(",\n"),
|
||||||
|
));
|
||||||
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
|
if !where_bounds.is_empty() {
|
||||||
|
return Err(ErrorReported);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(bound);
|
return Ok(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1933,6 +1984,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
"Self",
|
"Self",
|
||||||
assoc_ident,
|
assoc_ident,
|
||||||
span,
|
span,
|
||||||
|
None,
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
(&ty::Param(_), Res::SelfTy(Some(param_did), None))
|
(&ty::Param(_), Res::SelfTy(Some(param_did), None))
|
||||||
|
|
|
@ -20,11 +20,9 @@ fn dent<C:BoxCar>(c: C, color: C::Color) {
|
||||||
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
|
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: add error code to detect this case and explain that you'll want the approach in
|
|
||||||
// `dent_object_3` of using a new type param and relying on the `where` clauses.
|
|
||||||
fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
||||||
//~^ ERROR ambiguous associated type
|
//~^ ERROR ambiguous associated type
|
||||||
//~| ERROR the value of the associated type `Color` (from trait `Vehicle`) must be specified
|
//~| ERROR the value of the associated types `Color` (from trait `Vehicle`), `Color` (from
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint<C:BoxCar>(c: C, d: C::Color) {
|
fn paint<C:BoxCar>(c: C, d: C::Color) {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
error: equality constraints are not yet supported in where clauses (see #20041)
|
error: equality constraints are not yet supported in where clauses
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:34:46
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:46
|
||||||
|
|
|
|
||||||
LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
|
LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||||
|
|
|
||||||
|
= note: for more information, see #20041
|
||||||
|
|
||||||
error[E0221]: ambiguous associated type `Color` in bounds of `C`
|
error[E0221]: ambiguous associated type `Color` in bounds of `C`
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:19:32
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:19:32
|
||||||
|
@ -25,8 +27,8 @@ help: use fully qualified syntax to disambiguate
|
||||||
LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
|
LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0221]: ambiguous associated type `Color` in bounds of `BoxCar`
|
error[E0222]: ambiguous associated type `Color` in bounds of `BoxCar`
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:25:30
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:30
|
||||||
|
|
|
|
||||||
LL | type Color;
|
LL | type Color;
|
||||||
| ----------- ambiguous `Color` from `Vehicle`
|
| ----------- ambiguous `Color` from `Vehicle`
|
||||||
|
@ -37,26 +39,28 @@ LL | type Color;
|
||||||
LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^ ambiguous associated type `Color`
|
| ^^^^^^^^^^^^^^^^^^^ ambiguous associated type `Color`
|
||||||
|
|
|
|
||||||
help: use fully qualified syntax to disambiguate
|
= help: consider introducing a new type parameter `T` and adding `where` constraints:
|
||||||
|
|
where
|
||||||
LL | fn dent_object<COLOR>(c: dyn <BoxCar as Box>::Color) {
|
T: BoxCar,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
T: Box::Color = COLOR,
|
||||||
help: use fully qualified syntax to disambiguate
|
T: Vehicle::Color = COLOR
|
||||||
|
|
|
||||||
LL | fn dent_object<COLOR>(c: dyn <BoxCar as Vehicle>::Color) {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0191]: the value of the associated type `Color` (from trait `Vehicle`) must be specified
|
error[E0191]: the value of the associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:25:30
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:30
|
||||||
|
|
|
|
||||||
LL | type Color;
|
LL | type Color;
|
||||||
| ----------- `Color` defined here
|
| ----------- `Color` defined here
|
||||||
...
|
...
|
||||||
|
LL | type Color;
|
||||||
|
| ----------- `Color` defined here
|
||||||
|
...
|
||||||
LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `BoxCar<Color=COLOR, Color = Type>`
|
| ^^^^^^^^^^^^^^^^^^^ associated types `Color`, `Color` must be specified
|
||||||
|
|
|
||||||
|
= help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated type
|
||||||
|
|
||||||
error[E0221]: ambiguous associated type `Color` in bounds of `C`
|
error[E0221]: ambiguous associated type `Color` in bounds of `C`
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:30:29
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:28:29
|
||||||
|
|
|
|
||||||
LL | type Color;
|
LL | type Color;
|
||||||
| ----------- ambiguous `Color` from `Vehicle`
|
| ----------- ambiguous `Color` from `Vehicle`
|
||||||
|
@ -77,7 +81,7 @@ LL | fn paint<C:BoxCar>(c: C, d: <C as Vehicle>::Color) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0191]: the value of the associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified
|
error[E0191]: the value of the associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified
|
||||||
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:34:32
|
--> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:32
|
||||||
|
|
|
|
||||||
LL | type Color;
|
LL | type Color;
|
||||||
| ----------- `Color` defined here
|
| ----------- `Color` defined here
|
||||||
|
@ -86,9 +90,11 @@ LL | type Color;
|
||||||
| ----------- `Color` defined here
|
| ----------- `Color` defined here
|
||||||
...
|
...
|
||||||
LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
|
LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
|
||||||
| ^^^^^^ help: specify the associated types: `BoxCar<Color = Type, Color = Type>`
|
| ^^^^^^ associated types `Color`, `Color` must be specified
|
||||||
|
|
|
||||||
|
= help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated type
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0191, E0221.
|
Some errors have detailed explanations: E0191, E0221, E0222.
|
||||||
For more information about an error, try `rustc --explain E0191`.
|
For more information about an error, try `rustc --explain E0191`.
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: equality constraints are not yet supported in `where` clauses
|
||||||
--> $DIR/where-equality-constraints.rs:1:14
|
--> $DIR/where-equality-constraints.rs:1:14
|
||||||
|
|
|
|
||||||
LL | fn f() where u8 = u16 {}
|
LL | fn f() where u8 = u16 {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ not supported
|
||||||
|
|
|
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/20041
|
= note: for more information, see https://github.com/rust-lang/rust/issues/20041
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ error: equality constraints are not yet supported in `where` clauses
|
||||||
--> $DIR/where-equality-constraints.rs:3:14
|
--> $DIR/where-equality-constraints.rs:3:14
|
||||||
|
|
|
|
||||||
LL | fn g() where for<'a> &'static (u8,) == u16, {}
|
LL | fn g() where for<'a> &'static (u8,) == u16, {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||||
|
|
|
|
||||||
= note: for more information, see https://github.com/rust-lang/rust/issues/20041
|
= note: for more information, see https://github.com/rust-lang/rust/issues/20041
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue