Skip to content

More descriptive error when qself path doesnt have a trait on the RHS of as #109788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ pub(crate) enum ConstantItemKind {
Static,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum RecordPartialRes {
Yes,
No,
}

/// The rib kind restricts certain accesses,
/// e.g. to a `Res::Local` of an outer item.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -2682,6 +2688,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
&path,
PathSource::Trait(AliasPossibility::No),
Finalize::new(trait_ref.ref_id, trait_ref.path.span),
RecordPartialRes::Yes,
);
self.diagnostic_metadata.currently_processing_impl_trait = None;
if let Some(def_id) = res.expect_full_res().opt_def_id() {
Expand Down Expand Up @@ -3420,6 +3427,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
&Segment::from_path(path),
source,
Finalize::new(id, path.span),
RecordPartialRes::Yes,
);
}

Expand All @@ -3430,6 +3438,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
path: &[Segment],
source: PathSource<'ast>,
finalize: Finalize,
record_partial_res: RecordPartialRes,
) -> PartialRes {
let ns = source.namespace();

Expand Down Expand Up @@ -3636,7 +3645,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
_ => report_errors(self, None),
};

if !matches!(source, PathSource::TraitItem(..)) {
if record_partial_res == RecordPartialRes::Yes {
// Avoid recording definition of `A::B` in `<T as A>::B::C`.
self.r.record_partial_res(node_id, partial_res);
self.resolve_elided_lifetimes_in_path(node_id, partial_res, path, source, path_span);
Expand Down Expand Up @@ -3740,7 +3749,25 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
)));
}

// Make sure `A::B` in `<T as A::B>::C` is a trait item.
let num_privacy_errors = self.r.privacy_errors.len();
// Make sure that `A` in `<T as A>::B::C` is a trait.
let trait_res = self.smart_resolve_path_fragment(
&None,
&path[..qself.position],
PathSource::Trait(AliasPossibility::No),
Finalize::new(finalize.node_id, qself.path_span),
RecordPartialRes::No,
);

if trait_res.expect_full_res() == Res::Err {
return Ok(Some(trait_res));
}

// Truncate additional privacy errors reported above,
// because they'll be recomputed below.
self.r.privacy_errors.truncate(num_privacy_errors);

// Make sure `A::B` in `<T as A>::B::C` is a trait item.
//
// Currently, `path` names the full item (`A::B::C`, in
// our example). so we extract the prefix of that that is
Expand All @@ -3753,6 +3780,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
&path[..=qself.position],
PathSource::TraitItem(ns),
Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
RecordPartialRes::No,
);

// The remaining segments (the `C` in our example) will
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/dyn-trait-compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ type A2 = dyn<dyn, dyn>;
type A3 = dyn<<dyn as dyn>::dyn>;
//~^ ERROR cannot find type `dyn` in this scope
//~| ERROR cannot find type `dyn` in this scope
//~| ERROR use of undeclared crate or module `dyn`
//~| ERROR cannot find trait `dyn` in this scope

fn main() {}
16 changes: 8 additions & 8 deletions tests/ui/parser/dyn-trait-compatibility.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
LL | type A1 = dyn::dyn;
| ^^^ use of undeclared crate or module `dyn`

error[E0433]: failed to resolve: use of undeclared crate or module `dyn`
--> $DIR/dyn-trait-compatibility.rs:9:23
|
LL | type A3 = dyn<<dyn as dyn>::dyn>;
| ^^^ use of undeclared crate or module `dyn`

error[E0412]: cannot find type `dyn` in this scope
--> $DIR/dyn-trait-compatibility.rs:1:11
|
Expand Down Expand Up @@ -40,6 +34,12 @@ error[E0412]: cannot find type `dyn` in this scope
LL | type A3 = dyn<<dyn as dyn>::dyn>;
| ^^^ not found in this scope

error[E0405]: cannot find trait `dyn` in this scope
--> $DIR/dyn-trait-compatibility.rs:9:23
|
LL | type A3 = dyn<<dyn as dyn>::dyn>;
| ^^^ not found in this scope

error[E0412]: cannot find type `dyn` in this scope
--> $DIR/dyn-trait-compatibility.rs:9:16
|
Expand All @@ -48,5 +48,5 @@ LL | type A3 = dyn<<dyn as dyn>::dyn>;

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0412, E0433.
For more information about an error, try `rustc --explain E0412`.
Some errors have detailed explanations: E0405, E0412, E0433.
For more information about an error, try `rustc --explain E0405`.
6 changes: 4 additions & 2 deletions tests/ui/rust-2018/edition-lint-fully-qualified-paths.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ mod foo {
fn main() {
let _: <foo::Baz as crate::foo::Foo>::Bar = ();
//~^ ERROR absolute paths must start with
//~| this is accepted in the current edition
//~| WARN this is accepted in the current edition
//~| ERROR absolute paths must start with
//~| WARN this is accepted in the current edition

let _: <crate::foo::Baz as foo::Foo>::Bar = ();
//~^ ERROR absolute paths must start with
//~| this is accepted in the current edition
//~| WARN this is accepted in the current edition
}
6 changes: 4 additions & 2 deletions tests/ui/rust-2018/edition-lint-fully-qualified-paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ mod foo {
fn main() {
let _: <foo::Baz as ::foo::Foo>::Bar = ();
//~^ ERROR absolute paths must start with
//~| this is accepted in the current edition
//~| WARN this is accepted in the current edition
//~| ERROR absolute paths must start with
//~| WARN this is accepted in the current edition

let _: <::foo::Baz as foo::Foo>::Bar = ();
//~^ ERROR absolute paths must start with
//~| this is accepted in the current edition
//~| WARN this is accepted in the current edition
}
13 changes: 11 additions & 2 deletions tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ LL | #![deny(absolute_paths_not_starting_with_crate)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
--> $DIR/edition-lint-fully-qualified-paths.rs:23:13
--> $DIR/edition-lint-fully-qualified-paths.rs:19:25
|
LL | let _: <foo::Baz as ::foo::Foo>::Bar = ();
| ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
= note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>

error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
--> $DIR/edition-lint-fully-qualified-paths.rs:25:13
|
LL | let _: <::foo::Baz as foo::Foo>::Bar = ();
| ^^^^^^^^^^ help: use `crate`: `crate::foo::Baz`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
= note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>

error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { //~ ERROR expec

fn issue_95327() where <u8 as Unresolved>::Assoc: String {}
//~^ ERROR expected trait, found struct
//~| ERROR use of undeclared type `Unresolved`
//~| ERROR cannot find trait `Unresolved` in this scope

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
error[E0433]: failed to resolve: use of undeclared type `Unresolved`
--> $DIR/assoc_type_bound_with_struct.rs:19:31
|
LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {}
| ^^^^^^^^^^ use of undeclared type `Unresolved`

error[E0404]: expected trait, found struct `String`
--> $DIR/assoc_type_bound_with_struct.rs:5:46
|
Expand Down Expand Up @@ -76,6 +70,12 @@ help: a trait with a similar name exists
LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString {
| ~~~~~~~~

error[E0405]: cannot find trait `Unresolved` in this scope
--> $DIR/assoc_type_bound_with_struct.rs:19:31
|
LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {}
| ^^^^^^^^^^ not found in this scope

error[E0404]: expected trait, found struct `String`
--> $DIR/assoc_type_bound_with_struct.rs:19:51
|
Expand All @@ -87,5 +87,5 @@ LL | fn issue_95327() where <u8 as Unresolved>::Assoc: String {}

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0404, E0433.
Some errors have detailed explanations: E0404, E0405.
For more information about an error, try `rustc --explain E0404`.
44 changes: 22 additions & 22 deletions tests/ui/ufcs/ufcs-partially-resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,37 @@ type A = u32;

fn main() {
let _: <u8 as Tr>::N; //~ ERROR cannot find associated type `N` in trait `Tr`
let _: <u8 as E>::N; //~ ERROR cannot find associated type `N` in enum `E`
let _: <u8 as A>::N; //~ ERROR cannot find associated type `N` in `A`
let _: <u8 as E>::N; //~ ERROR expected trait, found enum `E`
let _: <u8 as A>::N; //~ ERROR expected trait, found type alias `A`
<u8 as Tr>::N; //~ ERROR cannot find method or associated constant `N` in trait `Tr`
<u8 as E>::N; //~ ERROR cannot find method or associated constant `N` in enum `E`
<u8 as A>::N; //~ ERROR cannot find method or associated constant `N` in `A`
<u8 as E>::N; //~ ERROR expected trait, found enum `E`
<u8 as A>::N; //~ ERROR expected trait, found type alias `A`
let _: <u8 as Tr>::Y; // OK
let _: <u8 as E>::Y; //~ ERROR expected associated type, found variant `E::Y`
let _: <u8 as E>::Y; //~ ERROR expected trait, found enum `E`
<u8 as Tr>::Y; // OK
<u8 as E>::Y; //~ ERROR expected method or associated constant, found unit variant `E::Y`
<u8 as E>::Y; //~ ERROR expected trait, found enum `E`

let _: <u8 as Tr>::N::NN; //~ ERROR cannot find associated type `N` in trait `Tr`
let _: <u8 as E>::N::NN; //~ ERROR cannot find associated type `N` in enum `E`
let _: <u8 as A>::N::NN; //~ ERROR cannot find associated type `N` in `A`
let _: <u8 as E>::N::NN; //~ ERROR expected trait, found enum `E`
let _: <u8 as A>::N::NN; //~ ERROR expected trait, found type alias `A`
<u8 as Tr>::N::NN; //~ ERROR cannot find associated type `N` in trait `Tr`
<u8 as E>::N::NN; //~ ERROR cannot find associated type `N` in enum `E`
<u8 as A>::N::NN; //~ ERROR cannot find associated type `N` in `A`
<u8 as E>::N::NN; //~ ERROR expected trait, found enum `E`
<u8 as A>::N::NN; //~ ERROR expected trait, found type alias `A`
let _: <u8 as Tr>::Y::NN; //~ ERROR ambiguous associated type
let _: <u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
let _: <u8 as E>::Y::NN; //~ ERROR expected trait, found enum `E`
<u8 as Tr>::Y::NN; //~ ERROR no associated item named `NN` found for type `u16`
<u8 as E>::Y::NN; //~ ERROR expected associated type, found variant `E::Y`
<u8 as E>::Y::NN; //~ ERROR expected trait, found enum `E`

let _: <u8 as Tr::N>::NN; //~ ERROR cannot find associated type `NN` in `Tr::N`
let _: <u8 as E::N>::NN; //~ ERROR cannot find associated type `NN` in `E::N`
let _: <u8 as A::N>::NN; //~ ERROR cannot find associated type `NN` in `A::N`
<u8 as Tr::N>::NN; //~ ERROR cannot find method or associated constant `NN` in `Tr::N`
<u8 as E::N>::NN; //~ ERROR cannot find method or associated constant `NN` in `E::N`
<u8 as A::N>::NN; //~ ERROR cannot find method or associated constant `NN` in `A::N`
let _: <u8 as Tr::Y>::NN; //~ ERROR cannot find associated type `NN` in `Tr::Y`
let _: <u8 as E::Y>::NN; //~ ERROR failed to resolve: `Y` is a variant, not a module
<u8 as Tr::Y>::NN; //~ ERROR cannot find method or associated constant `NN` in `Tr::Y`
<u8 as E::Y>::NN; //~ ERROR failed to resolve: `Y` is a variant, not a module
let _: <u8 as Tr::N>::NN; //~ ERROR cannot find trait `N` in trait `Tr`
let _: <u8 as E::N>::NN; //~ ERROR cannot find trait `N` in enum `E`
let _: <u8 as A::N>::NN; //~ ERROR cannot find trait `N` in `A`
<u8 as Tr::N>::NN; //~ ERROR cannot find trait `N` in trait `Tr`
<u8 as E::N>::NN; //~ ERROR cannot find trait `N` in enum `E`
<u8 as A::N>::NN; //~ ERROR cannot find trait `N` in `A`
let _: <u8 as Tr::Y>::NN; //~ ERROR expected trait, found associated type `Tr::Y
let _: <u8 as E::Y>::NN; //~ ERROR expected trait, found variant `E::Y`
<u8 as Tr::Y>::NN; //~ ERROR expected trait, found associated type `Tr::Y`
<u8 as E::Y>::NN; //~ ERROR expected trait, found variant `E::Y`

let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found associated function `Dr::Z`
<u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X`
Expand Down
Loading