address review comments
This commit is contained in:
parent
fdbe4ce5c1
commit
4ae8f6ec7c
4 changed files with 97 additions and 9 deletions
|
@ -1884,6 +1884,16 @@ impl Clone for Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ty {
|
||||||
|
pub fn peel_refs(&self) -> &Self {
|
||||||
|
let mut final_ty = self;
|
||||||
|
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
|
||||||
|
final_ty = &ty;
|
||||||
|
}
|
||||||
|
final_ty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct BareFnTy {
|
pub struct BareFnTy {
|
||||||
pub unsafety: Unsafe,
|
pub unsafety: Unsafe,
|
||||||
|
|
|
@ -442,7 +442,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
|
|
||||||
if !self.type_ascription_suggestion(&mut err, base_span) {
|
if !self.type_ascription_suggestion(&mut err, base_span) {
|
||||||
let mut fallback = false;
|
let mut fallback = false;
|
||||||
if let PathSource::Trait(AliasPossibility::Maybe) = source {
|
if let (
|
||||||
|
PathSource::Trait(AliasPossibility::Maybe),
|
||||||
|
Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
|
||||||
|
) = (source, res)
|
||||||
|
{
|
||||||
if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object {
|
if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object {
|
||||||
fallback = true;
|
fallback = true;
|
||||||
let spans: Vec<Span> = bounds
|
let spans: Vec<Span> = bounds
|
||||||
|
@ -580,7 +584,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ast::TyKind::Path(None, type_param_path) = &ty.kind {
|
if let ast::TyKind::Path(None, type_param_path) = &ty.peel_refs().kind {
|
||||||
// Confirm that the `SelfTy` is a type parameter.
|
// Confirm that the `SelfTy` is a type parameter.
|
||||||
let partial_res = if let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
|
let partial_res = if let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
|
||||||
bounded_ty.id,
|
bounded_ty.id,
|
||||||
|
@ -603,20 +607,24 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let (
|
if let (
|
||||||
[ast::PathSegment { ident, args: None, .. }],
|
[ast::PathSegment { ident: constrain_ident, args: None, .. }],
|
||||||
[ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifier::None)],
|
[ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifier::None)],
|
||||||
) = (&type_param_path.segments[..], &bounds[..])
|
) = (&type_param_path.segments[..], &bounds[..])
|
||||||
{
|
{
|
||||||
if let [ast::PathSegment { ident: bound_ident, args: None, .. }] =
|
if let [ast::PathSegment { ident, args: None, .. }] =
|
||||||
&poly_trait_ref.trait_ref.path.segments[..]
|
&poly_trait_ref.trait_ref.path.segments[..]
|
||||||
{
|
{
|
||||||
if bound_ident.span == span {
|
if ident.span == span {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
*where_span,
|
*where_span,
|
||||||
&format!("constrain the associated type to `{}`", bound_ident),
|
&format!("constrain the associated type to `{}`", ident),
|
||||||
format!(
|
format!(
|
||||||
"{}: {}<{} = {}>",
|
"{}: {}<{} = {}>",
|
||||||
ident,
|
self.r
|
||||||
|
.session
|
||||||
|
.source_map()
|
||||||
|
.span_to_snippet(ty.span) // Account for `<&'a T as Foo>::Bar`.
|
||||||
|
.unwrap_or_else(|_| constrain_ident.to_string()),
|
||||||
path.segments[..*position]
|
path.segments[..*position]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|segment| path_segment_to_string(segment))
|
.map(|segment| path_segment_to_string(segment))
|
||||||
|
@ -627,7 +635,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
.map(|segment| path_segment_to_string(segment))
|
.map(|segment| path_segment_to_string(segment))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("::"),
|
.join("::"),
|
||||||
bound_ident,
|
ident,
|
||||||
),
|
),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,4 +6,14 @@ struct Foo<T> where T: Bar, <T as Bar>::Baz: String { //~ ERROR expected trait,
|
||||||
t: T,
|
t: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found struct
|
||||||
|
t: &'a T,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String { //~ ERROR expected trait, found struct
|
||||||
|
}
|
||||||
|
|
||||||
|
fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -18,6 +18,66 @@ help: a trait with a similar name exists
|
||||||
LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: ToString {
|
LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: ToString {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0404]: expected trait, found struct `String`
|
||||||
|
--> $DIR/assoc_type_bound_with_struct.rs:9:54
|
||||||
|
|
|
||||||
|
LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String {
|
||||||
|
| ^^^^^^ not a trait
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/alloc/src/string.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub trait ToString {
|
||||||
|
| ------------------ similarly named trait `ToString` defined here
|
||||||
|
|
|
||||||
|
help: constrain the associated type to `String`
|
||||||
|
|
|
||||||
|
LL | struct Qux<'a, T> where T: Bar, &'a T: Bar<Baz = String> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: a trait with a similar name exists
|
||||||
|
|
|
||||||
|
LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: ToString {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found struct `String`
|
||||||
|
--> $DIR/assoc_type_bound_with_struct.rs:13:45
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String {
|
||||||
|
| ^^^^^^ not a trait
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/alloc/src/string.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub trait ToString {
|
||||||
|
| ------------------ similarly named trait `ToString` defined here
|
||||||
|
|
|
||||||
|
help: constrain the associated type to `String`
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Bar>(_: T) where T: Bar<Baz = String> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: a trait with a similar name exists
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: ToString {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error[E0404]: expected trait, found struct `String`
|
||||||
|
--> $DIR/assoc_type_bound_with_struct.rs:16:57
|
||||||
|
|
|
||||||
|
LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String {
|
||||||
|
| ^^^^^^ not a trait
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/alloc/src/string.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub trait ToString {
|
||||||
|
| ------------------ similarly named trait `ToString` defined here
|
||||||
|
|
|
||||||
|
help: constrain the associated type to `String`
|
||||||
|
|
|
||||||
|
LL | fn qux<'a, T: Bar>(_: &'a T) where &'a T: Bar<Baz = String> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
help: a trait with a similar name exists
|
||||||
|
|
|
||||||
|
LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0404`.
|
For more information about this error, try `rustc --explain E0404`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue