Skip to content

Commit 4ae8f6e

Browse files
committed
address review comments
1 parent fdbe4ce commit 4ae8f6e

File tree

4 files changed

+97
-9
lines changed

4 files changed

+97
-9
lines changed

compiler/rustc_ast/src/ast.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1884,6 +1884,16 @@ impl Clone for Ty {
18841884
}
18851885
}
18861886

1887+
impl Ty {
1888+
pub fn peel_refs(&self) -> &Self {
1889+
let mut final_ty = self;
1890+
while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
1891+
final_ty = &ty;
1892+
}
1893+
final_ty
1894+
}
1895+
}
1896+
18871897
#[derive(Clone, Encodable, Decodable, Debug)]
18881898
pub struct BareFnTy {
18891899
pub unsafety: Unsafe,

compiler/rustc_resolve/src/late/diagnostics.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
442442

443443
if !self.type_ascription_suggestion(&mut err, base_span) {
444444
let mut fallback = false;
445-
if let PathSource::Trait(AliasPossibility::Maybe) = source {
445+
if let (
446+
PathSource::Trait(AliasPossibility::Maybe),
447+
Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
448+
) = (source, res)
449+
{
446450
if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object {
447451
fallback = true;
448452
let spans: Vec<Span> = bounds
@@ -580,7 +584,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
580584
return false;
581585
};
582586

583-
if let ast::TyKind::Path(None, type_param_path) = &ty.kind {
587+
if let ast::TyKind::Path(None, type_param_path) = &ty.peel_refs().kind {
584588
// Confirm that the `SelfTy` is a type parameter.
585589
let partial_res = if let Ok(Some(partial_res)) = self.resolve_qpath_anywhere(
586590
bounded_ty.id,
@@ -603,20 +607,24 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
603607
return false;
604608
}
605609
if let (
606-
[ast::PathSegment { ident, args: None, .. }],
610+
[ast::PathSegment { ident: constrain_ident, args: None, .. }],
607611
[ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifier::None)],
608612
) = (&type_param_path.segments[..], &bounds[..])
609613
{
610-
if let [ast::PathSegment { ident: bound_ident, args: None, .. }] =
614+
if let [ast::PathSegment { ident, args: None, .. }] =
611615
&poly_trait_ref.trait_ref.path.segments[..]
612616
{
613-
if bound_ident.span == span {
617+
if ident.span == span {
614618
err.span_suggestion_verbose(
615619
*where_span,
616-
&format!("constrain the associated type to `{}`", bound_ident),
620+
&format!("constrain the associated type to `{}`", ident),
617621
format!(
618622
"{}: {}<{} = {}>",
619-
ident,
623+
self.r
624+
.session
625+
.source_map()
626+
.span_to_snippet(ty.span) // Account for `<&'a T as Foo>::Bar`.
627+
.unwrap_or_else(|_| constrain_ident.to_string()),
620628
path.segments[..*position]
621629
.iter()
622630
.map(|segment| path_segment_to_string(segment))
@@ -627,7 +635,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
627635
.map(|segment| path_segment_to_string(segment))
628636
.collect::<Vec<_>>()
629637
.join("::"),
630-
bound_ident,
638+
ident,
631639
),
632640
Applicability::MaybeIncorrect,
633641
);

src/test/ui/traits/assoc_type_bound_with_struct.rs

+10
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,14 @@ struct Foo<T> where T: Bar, <T as Bar>::Baz: String { //~ ERROR expected trait,
66
t: T,
77
}
88

9+
struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found struct
10+
t: &'a T,
11+
}
12+
13+
fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String { //~ ERROR expected trait, found struct
14+
}
15+
16+
fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { //~ ERROR expected trait, found
17+
}
18+
919
fn main() {}

src/test/ui/traits/assoc_type_bound_with_struct.stderr

+61-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,66 @@ help: a trait with a similar name exists
1818
LL | struct Foo<T> where T: Bar, <T as Bar>::Baz: ToString {
1919
| ^^^^^^^^
2020

21-
error: aborting due to previous error
21+
error[E0404]: expected trait, found struct `String`
22+
--> $DIR/assoc_type_bound_with_struct.rs:9:54
23+
|
24+
LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String {
25+
| ^^^^^^ not a trait
26+
|
27+
::: $SRC_DIR/alloc/src/string.rs:LL:COL
28+
|
29+
LL | pub trait ToString {
30+
| ------------------ similarly named trait `ToString` defined here
31+
|
32+
help: constrain the associated type to `String`
33+
|
34+
LL | struct Qux<'a, T> where T: Bar, &'a T: Bar<Baz = String> {
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^
36+
help: a trait with a similar name exists
37+
|
38+
LL | struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: ToString {
39+
| ^^^^^^^^
40+
41+
error[E0404]: expected trait, found struct `String`
42+
--> $DIR/assoc_type_bound_with_struct.rs:13:45
43+
|
44+
LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: String {
45+
| ^^^^^^ not a trait
46+
|
47+
::: $SRC_DIR/alloc/src/string.rs:LL:COL
48+
|
49+
LL | pub trait ToString {
50+
| ------------------ similarly named trait `ToString` defined here
51+
|
52+
help: constrain the associated type to `String`
53+
|
54+
LL | fn foo<T: Bar>(_: T) where T: Bar<Baz = String> {
55+
| ^^^^^^^^^^^^^^^^^^^^
56+
help: a trait with a similar name exists
57+
|
58+
LL | fn foo<T: Bar>(_: T) where <T as Bar>::Baz: ToString {
59+
| ^^^^^^^^
60+
61+
error[E0404]: expected trait, found struct `String`
62+
--> $DIR/assoc_type_bound_with_struct.rs:16:57
63+
|
64+
LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String {
65+
| ^^^^^^ not a trait
66+
|
67+
::: $SRC_DIR/alloc/src/string.rs:LL:COL
68+
|
69+
LL | pub trait ToString {
70+
| ------------------ similarly named trait `ToString` defined here
71+
|
72+
help: constrain the associated type to `String`
73+
|
74+
LL | fn qux<'a, T: Bar>(_: &'a T) where &'a T: Bar<Baz = String> {
75+
| ^^^^^^^^^^^^^^^^^^^^^^^^
76+
help: a trait with a similar name exists
77+
|
78+
LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString {
79+
| ^^^^^^^^
80+
81+
error: aborting due to 4 previous errors
2282

2383
For more information about this error, try `rustc --explain E0404`.

0 commit comments

Comments
 (0)