review comments + more tests

This commit is contained in:
Esteban Küber 2023-10-16 01:22:25 +00:00
parent 5cc9216ff3
commit 6cf01fcf1e
9 changed files with 421 additions and 20 deletions

View File

@ -1340,7 +1340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err, err,
path, path,
ty, ty,
impl_ty, Some(impl_ty),
item.kind, item.kind,
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id), self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
sugg_span, sugg_span,
@ -1377,7 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err, err,
path, path,
rcvr_ty, rcvr_ty,
rcvr_ty, None,
item.kind, item.kind,
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id), self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
sugg_span, sugg_span,
@ -3148,7 +3148,7 @@ fn print_disambiguation_help<'tcx>(
err: &mut Diagnostic, err: &mut Diagnostic,
trait_name: String, trait_name: String,
rcvr_ty: Ty<'_>, rcvr_ty: Ty<'_>,
self_ty: Ty<'_>, impl_self_ty: Option<Ty<'_>>,
kind: ty::AssocKind, kind: ty::AssocKind,
def_kind_descr: &'static str, def_kind_descr: &'static str,
span: Span, span: Span,
@ -3174,20 +3174,21 @@ fn print_disambiguation_help<'tcx>(
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "), .join(", "),
); );
let trait_name = if !fn_has_self_parameter { let trait_name = if !fn_has_self_parameter && let Some(impl_self_ty) = impl_self_ty {
format!("<{self_ty} as {trait_name}>") format!("<{impl_self_ty} as {trait_name}>")
} else { } else {
trait_name trait_name
}; };
(span, format!("{trait_name}::{item_name}{args}")) (span, format!("{trait_name}::{item_name}{args}"))
} else if let Some(impl_self_ty) = impl_self_ty {
(span.with_hi(item_name.span.lo()), format!("<{impl_self_ty} as {trait_name}>::"))
} else { } else {
(span.with_hi(item_name.span.lo()), format!("<{self_ty} as {trait_name}>::")) (span.with_hi(item_name.span.lo()), format!("{trait_name}::"))
}; };
err.span_suggestion_verbose( err.span_suggestion_verbose(
span, span,
format!( format!(
"disambiguate the {} for {}", "disambiguate the {def_kind_descr} for {}",
def_kind_descr,
if let Some(candidate) = candidate { if let Some(candidate) = candidate {
format!("candidate #{candidate}") format!("candidate #{candidate}")
} else { } else {

View File

@ -1,8 +1,12 @@
trait A { trait A {
type Type;
const CONST: usize;
fn foo(&self); fn foo(&self);
} }
trait B { trait B {
type Type;
const CONST: usize;
fn foo(&self); fn foo(&self);
} }
@ -10,10 +14,14 @@ trait B {
struct S; struct S;
impl<T: std::fmt::Debug> A for T { impl<T: std::fmt::Debug> A for T {
type Type = ();
const CONST: usize = 1; //~ NOTE candidate #1
fn foo(&self) {} //~ NOTE candidate #1 fn foo(&self) {} //~ NOTE candidate #1
} }
impl<T: std::fmt::Debug> B for T { impl<T: std::fmt::Debug> B for T {
type Type = ();
const CONST: usize = 2; //~ NOTE candidate #2
fn foo(&self) {} //~ NOTE candidate #2 fn foo(&self) {} //~ NOTE candidate #2
} }
@ -23,5 +31,10 @@ fn main() {
//~^ NOTE multiple `foo` found //~^ NOTE multiple `foo` found
//~| HELP disambiguate //~| HELP disambiguate
//~| HELP disambiguate //~| HELP disambiguate
S::CONST; //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `CONST` found
//~| HELP disambiguate
//~| HELP disambiguate
let _: S::Type; //~ ERROR ambiguous associated type
//~^ HELP use the fully-qualified path
} }

View File

@ -1,16 +1,29 @@
error[E0223]: ambiguous associated type
--> $DIR/disambiguate-multiple-blanket-impl.rs:38:12
|
LL | let _: S::Type;
| ^^^^^^^
|
help: use the fully-qualified path
|
LL | let _: <S as A>::Type;
| ~~~~~~~~~~~~~~
LL | let _: <S as B>::Type;
| ~~~~~~~~~~~~~~
error[E0034]: multiple applicable items in scope error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-blanket-impl.rs:22:8 --> $DIR/disambiguate-multiple-blanket-impl.rs:30:8
| |
LL | S::foo(&s); LL | S::foo(&s);
| ^^^ multiple `foo` found | ^^^ multiple `foo` found
| |
note: candidate #1 is defined in an impl of the trait `A` for the type `T` note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-blanket-impl.rs:13:5 --> $DIR/disambiguate-multiple-blanket-impl.rs:19:5
| |
LL | fn foo(&self) {} LL | fn foo(&self) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T` note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-blanket-impl.rs:17:5 --> $DIR/disambiguate-multiple-blanket-impl.rs:25:5
| |
LL | fn foo(&self) {} LL | fn foo(&self) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -23,6 +36,32 @@ help: disambiguate the method for candidate #2
LL | <T as B>::foo(&s); LL | <T as B>::foo(&s);
| ~~~~~~~~~~ | ~~~~~~~~~~
error: aborting due to previous error error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-blanket-impl.rs:34:8
|
LL | S::CONST;
| ^^^^^ multiple `CONST` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-blanket-impl.rs:18:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-blanket-impl.rs:24:5
|
LL | const CONST: usize = 2;
| ^^^^^^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | <T as A>::CONST;
| ~~~~~~~~~~
help: disambiguate the associated constant for candidate #2
|
LL | <T as B>::CONST;
| ~~~~~~~~~~
For more information about this error, try `rustc --explain E0034`. error: aborting due to 3 previous errors
Some errors have detailed explanations: E0034, E0223.
For more information about an error, try `rustc --explain E0034`.

View File

@ -1,18 +1,26 @@
trait A { trait A {
type Type;
const CONST: usize;
fn foo(&self); fn foo(&self);
} }
trait B { trait B {
type Type;
const CONST: usize;
fn foo(&self); fn foo(&self);
} }
struct S; struct S;
impl A for S { impl A for S {
type Type = ();
const CONST: usize = 1; //~ NOTE candidate #1
fn foo(&self) {} //~ NOTE candidate #1 fn foo(&self) {} //~ NOTE candidate #1
} }
impl B for S { impl B for S {
type Type = ();
const CONST: usize = 2; //~ NOTE candidate #2
fn foo(&self) {} //~ NOTE candidate #2 fn foo(&self) {} //~ NOTE candidate #2
} }
@ -22,5 +30,10 @@ fn main() {
//~^ NOTE multiple `foo` found //~^ NOTE multiple `foo` found
//~| HELP disambiguate //~| HELP disambiguate
//~| HELP disambiguate //~| HELP disambiguate
let _: S::Type = (); //~ ERROR ambiguous associated type
//~| HELP use the fully-qualified path
let _ = S::CONST; //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `CONST` found
//~| HELP disambiguate
//~| HELP disambiguate
} }

View File

@ -1,16 +1,29 @@
error[E0223]: ambiguous associated type
--> $DIR/disambiguate-multiple-impl.rs:33:12
|
LL | let _: S::Type = ();
| ^^^^^^^
|
help: use the fully-qualified path
|
LL | let _: <S as A>::Type = ();
| ~~~~~~~~~~~~~~
LL | let _: <S as B>::Type = ();
| ~~~~~~~~~~~~~~
error[E0034]: multiple applicable items in scope error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-impl.rs:21:8 --> $DIR/disambiguate-multiple-impl.rs:29:8
| |
LL | S::foo(&s); LL | S::foo(&s);
| ^^^ multiple `foo` found | ^^^ multiple `foo` found
| |
note: candidate #1 is defined in an impl of the trait `A` for the type `S` note: candidate #1 is defined in an impl of the trait `A` for the type `S`
--> $DIR/disambiguate-multiple-impl.rs:12:5 --> $DIR/disambiguate-multiple-impl.rs:18:5
| |
LL | fn foo(&self) {} LL | fn foo(&self) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `S` note: candidate #2 is defined in an impl of the trait `B` for the type `S`
--> $DIR/disambiguate-multiple-impl.rs:16:5 --> $DIR/disambiguate-multiple-impl.rs:24:5
| |
LL | fn foo(&self) {} LL | fn foo(&self) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -23,6 +36,32 @@ help: disambiguate the method for candidate #2
LL | <S as B>::foo(&s); LL | <S as B>::foo(&s);
| ~~~~~~~~~~ | ~~~~~~~~~~
error: aborting due to previous error error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-impl.rs:35:16
|
LL | let _ = S::CONST;
| ^^^^^ multiple `CONST` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `S`
--> $DIR/disambiguate-multiple-impl.rs:17:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `S`
--> $DIR/disambiguate-multiple-impl.rs:23:5
|
LL | const CONST: usize = 2;
| ^^^^^^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | let _ = <S as A>::CONST;
| ~~~~~~~~~~
help: disambiguate the associated constant for candidate #2
|
LL | let _ = <S as B>::CONST;
| ~~~~~~~~~~
For more information about this error, try `rustc --explain E0034`. error: aborting due to 3 previous errors
Some errors have detailed explanations: E0034, E0223.
For more information about an error, try `rustc --explain E0034`.

View File

@ -0,0 +1,57 @@
trait A {
type Type; //~ NOTE ambiguous `Type` from `A`
const CONST: usize = 1; //~ NOTE candidate #1
fn foo(&self); //~ NOTE candidate #1
}
trait B {
type Type; //~ NOTE ambiguous `Type` from `B`
const CONST: usize; //~ NOTE candidate #2
fn foo(&self); //~ NOTE candidate #2
}
trait C: A + B {}
fn a<T: C>(t: T) {
t.foo(); //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `foo` found
//~| HELP disambiguate the method
//~| HELP disambiguate the method
let _ = T::CONST; //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `CONST` found
//~| HELP disambiguate
//~| HELP disambiguate
let _: T::Type; //~ ERROR ambiguous associated type
//~^ NOTE ambiguous associated type `Type`
//~| HELP use fully qualified syntax
//~| HELP use fully qualified syntax
}
#[derive(Debug)]
struct S;
impl<T: std::fmt::Debug> A for T {
type Type = ();
const CONST: usize = 1; //~ NOTE candidate #1
fn foo(&self) {} //~ NOTE candidate #1
}
impl<T: std::fmt::Debug> B for T {
type Type = ();
const CONST: usize = 1; //~ NOTE candidate #2
fn foo(&self) {} //~ NOTE candidate #2
}
fn main() {
let s = S;
S::foo(&s); //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `foo` found
//~| HELP disambiguate
//~| HELP disambiguate
let _ = S::CONST; //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `CONST` found
//~| HELP disambiguate
//~| HELP disambiguate
let _: S::Type; //~ ERROR ambiguous associated type
//~^ HELP use the fully-qualified path
}

View File

@ -0,0 +1,138 @@
error[E0221]: ambiguous associated type `Type` in bounds of `T`
--> $DIR/disambiguate-multiple-trait-2.rs:24:12
|
LL | type Type;
| --------- ambiguous `Type` from `A`
...
LL | type Type;
| --------- ambiguous `Type` from `B`
...
LL | let _: T::Type;
| ^^^^^^^ ambiguous associated type `Type`
|
help: use fully qualified syntax to disambiguate
|
LL | let _: <T as A>::Type;
| ~~~~~~~~~~
help: use fully qualified syntax to disambiguate
|
LL | let _: <T as B>::Type;
| ~~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait-2.rs:16:7
|
LL | t.foo();
| ^^^ multiple `foo` found
|
note: candidate #1 is defined in the trait `A`
--> $DIR/disambiguate-multiple-trait-2.rs:4:5
|
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `B`
--> $DIR/disambiguate-multiple-trait-2.rs:10:5
|
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
help: disambiguate the method for candidate #1
|
LL | A::foo(t);
| ~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | B::foo(t);
| ~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait-2.rs:20:16
|
LL | let _ = T::CONST;
| ^^^^^ multiple `CONST` found
|
note: candidate #1 is defined in the trait `A`
--> $DIR/disambiguate-multiple-trait-2.rs:3:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `B`
--> $DIR/disambiguate-multiple-trait-2.rs:9:5
|
LL | const CONST: usize;
| ^^^^^^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | let _ = A::CONST;
| ~~~
help: disambiguate the associated constant for candidate #2
|
LL | let _ = B::CONST;
| ~~~
error[E0223]: ambiguous associated type
--> $DIR/disambiguate-multiple-trait-2.rs:55:12
|
LL | let _: S::Type;
| ^^^^^^^
|
help: use the fully-qualified path
|
LL | let _: <S as A>::Type;
| ~~~~~~~~~~~~~~
LL | let _: <S as B>::Type;
| ~~~~~~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait-2.rs:47:8
|
LL | S::foo(&s);
| ^^^ multiple `foo` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-trait-2.rs:36:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-trait-2.rs:42:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
help: disambiguate the method for candidate #1
|
LL | <T as A>::foo(&s);
| ~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | <T as B>::foo(&s);
| ~~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait-2.rs:51:16
|
LL | let _ = S::CONST;
| ^^^^^ multiple `CONST` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-trait-2.rs:35:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-trait-2.rs:41:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | let _ = <T as A>::CONST;
| ~~~~~~~~~~
help: disambiguate the associated constant for candidate #2
|
LL | let _ = <T as B>::CONST;
| ~~~~~~~~~~
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0034, E0221, E0223.
For more information about an error, try `rustc --explain E0034`.

View File

@ -0,0 +1,34 @@
#![feature(associated_type_defaults)]
trait A {
type Type = ();
const CONST: usize = 1; //~ NOTE candidate #1
fn foo(&self) {} //~ NOTE candidate #1
}
trait B {
type Type = ();
const CONST: usize = 2; //~ NOTE candidate #2
fn foo(&self) {} //~ NOTE candidate #2
}
#[derive(Debug)]
struct S;
impl<T: std::fmt::Debug> A for T {}
impl<T: std::fmt::Debug> B for T {}
fn main() {
let s = S;
S::foo(&s); //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `foo` found
//~| HELP disambiguate
//~| HELP disambiguate
let _ = S::CONST; //~ ERROR multiple applicable items in scope
//~^ NOTE multiple `CONST` found
//~| HELP disambiguate
//~| HELP disambiguate
let _: S::Type; //~ ERROR ambiguous associated type
//~^ HELP use the fully-qualified path
}

View File

@ -0,0 +1,67 @@
error[E0223]: ambiguous associated type
--> $DIR/disambiguate-multiple-trait.rs:32:12
|
LL | let _: S::Type;
| ^^^^^^^
|
help: use the fully-qualified path
|
LL | let _: <S as A>::Type;
| ~~~~~~~~~~~~~~
LL | let _: <S as B>::Type;
| ~~~~~~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait.rs:24:8
|
LL | S::foo(&s);
| ^^^ multiple `foo` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-trait.rs:6:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-trait.rs:12:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
help: disambiguate the method for candidate #1
|
LL | <T as A>::foo(&s);
| ~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | <T as B>::foo(&s);
| ~~~~~~~~~~
error[E0034]: multiple applicable items in scope
--> $DIR/disambiguate-multiple-trait.rs:28:16
|
LL | let _ = S::CONST;
| ^^^^^ multiple `CONST` found
|
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
--> $DIR/disambiguate-multiple-trait.rs:5:5
|
LL | const CONST: usize = 1;
| ^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
--> $DIR/disambiguate-multiple-trait.rs:11:5
|
LL | const CONST: usize = 2;
| ^^^^^^^^^^^^^^^^^^
help: disambiguate the associated constant for candidate #1
|
LL | let _ = <T as A>::CONST;
| ~~~~~~~~~~
help: disambiguate the associated constant for candidate #2
|
LL | let _ = <T as B>::CONST;
| ~~~~~~~~~~
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0034, E0223.
For more information about an error, try `rustc --explain E0034`.