diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index aea843ac0384c..10693448ea685 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -15,7 +15,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard}; use rustc_data_structures::unord::UnordMap; use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId}; -use rustc_hir::definitions::Definitions; +use rustc_hir::definitions::{DefPathData, Definitions}; use rustc_index::IndexVec; use rustc_lint_defs as lint; use rustc_lint_defs::builtin::UNUSED_CRATE_DEPENDENCIES; @@ -1358,14 +1358,24 @@ impl CStore { let cnum = self.resolve_crate(tcx, name, item.span, dep_kind, CrateOrigin::Extern)?; - let path_len = definitions.def_path(def_id).data.len(); + let def_path = definitions.def_path(def_id); + // An extern crate is only globally nameable if every segment in its path + // is in the type namespace (i.e., it is purely nested inside modules). + // If any segment is in the value namespace (e.g. inside a fn or const), + // it is unnameable from outside that block. + let is_unnameable = + def_path.data.iter().any(|d| !matches!(d.data, DefPathData::TypeNs(_))); self.update_extern_crate( cnum, name, ExternCrate { - src: ExternCrateSource::Extern(def_id.to_def_id()), + src: if is_unnameable { + ExternCrateSource::Path + } else { + ExternCrateSource::Extern(def_id.to_def_id()) + }, span: item.span, - path_len, + path_len: if is_unnameable { usize::MAX } else { def_path.data.len() }, dependency_of: LOCAL_CRATE, }, ); diff --git a/tests/ui/imports/auxiliary/macro-generated-extern-crate.rs b/tests/ui/imports/auxiliary/macro-generated-extern-crate.rs new file mode 100644 index 0000000000000..8a2c17266b7a9 --- /dev/null +++ b/tests/ui/imports/auxiliary/macro-generated-extern-crate.rs @@ -0,0 +1,3 @@ +pub trait MyTrait { + fn custom() {} +} diff --git a/tests/ui/imports/macro-generated-extern-crate.rs b/tests/ui/imports/macro-generated-extern-crate.rs new file mode 100644 index 0000000000000..a7b87efdd8fbe --- /dev/null +++ b/tests/ui/imports/macro-generated-extern-crate.rs @@ -0,0 +1,14 @@ +//@ edition: 2021 +//@ aux-build: macro-generated-extern-crate.rs + +const _: () = { + extern crate macro_generated_extern_crate as _my_crate; + impl _my_crate::MyTrait for Local {} +}; + +struct Local; + +fn main() { + Local::custom(); + //~^ ERROR no associated function or constant named `custom` found for struct `Local` +} diff --git a/tests/ui/imports/macro-generated-extern-crate.stderr b/tests/ui/imports/macro-generated-extern-crate.stderr new file mode 100644 index 0000000000000..e103b185789ac --- /dev/null +++ b/tests/ui/imports/macro-generated-extern-crate.stderr @@ -0,0 +1,18 @@ +error[E0599]: no associated function or constant named `custom` found for struct `Local` in the current scope + --> $DIR/macro-generated-extern-crate.rs:12:12 + | +LL | struct Local; + | ------------ associated function or constant `custom` not found for this struct +... +LL | Local::custom(); + | ^^^^^^ associated function or constant not found in `Local` + | + = help: items from traits can only be used if the trait is in scope +help: trait `MyTrait` which provides `custom` is implemented but not in scope; perhaps you want to import it + | +LL + use macro_generated_extern_crate::MyTrait; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr index c408b747b506f..ff069320f413d 100644 --- a/tests/ui/rust-2018/uniform-paths/issue-87932.stderr +++ b/tests/ui/rust-2018/uniform-paths/issue-87932.stderr @@ -10,7 +10,7 @@ LL | A::deserialize(); = help: items from traits can only be used if the trait is in scope help: trait `Deserialize` which provides `deserialize` is implemented but not in scope; perhaps you want to import it | -LL + use ::deserialize::_a::Deserialize; +LL + use issue_87932_a::Deserialize; | error: aborting due to 1 previous error diff --git a/tests/ui/traits/bound/same-crate-name.rs b/tests/ui/traits/bound/same-crate-name.rs index acd4894612872..5de6620bf4856 100644 --- a/tests/ui/traits/bound/same-crate-name.rs +++ b/tests/ui/traits/bound/same-crate-name.rs @@ -32,15 +32,11 @@ fn main() { extern crate crate_a1 as a; a::try_foo(foo); //~^ ERROR E0277 - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph - //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `implements_no_traits` has no impl for `Foo` a::try_foo(implements_no_traits); //~^ ERROR E0277 - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph - //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `other_variant_implements_mismatched_trait` @@ -48,16 +44,11 @@ fn main() { // only for its `` variant. a::try_foo(other_variant_implements_mismatched_trait); //~^ ERROR E0277 - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph - //~| HELP you can use `cargo tree` to explore your dependency tree // We don't want to see the "version mismatch" help message here // because `ImplementsTraitForUsize` only has // impls for the correct trait where the path is not misleading. a::try_foo(other_variant_implements_correct_trait); //~^ ERROR E0277 - //~| HELP the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph - //~| HELP you can use `cargo tree` to explore your dependency tree } } diff --git a/tests/ui/traits/bound/same-crate-name.stderr b/tests/ui/traits/bound/same-crate-name.stderr index 9e5e110f8624e..27cad715b0738 100644 --- a/tests/ui/traits/bound/same-crate-name.stderr +++ b/tests/ui/traits/bound/same-crate-name.stderr @@ -1,23 +1,13 @@ -error[E0277]: the trait bound `Foo: main::a::Bar` is not satisfied +error[E0277]: the trait bound `Foo: crate_a1::Bar` is not satisfied --> $DIR/same-crate-name.rs:33:20 | LL | a::try_foo(foo); - | ---------- ^^^ the trait `main::a::Bar` is not implemented for `Foo` + | ---------- ^^^ the trait `crate_a1::Bar` is not implemented for `Foo` | | | required by a bound introduced by this call | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:1:1 - | -LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait - | - ::: $DIR/auxiliary/crate_a2.rs:3:1 - | -LL | pub trait Bar {} - | ------------- this is the found trait - = help: you can use `cargo tree` to explore your dependency tree -help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` + = note: `Foo` implements similarly named trait `crate_a2::Bar`, but not `crate_a1::Bar` +help: the trait `crate_a1::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | LL | impl Bar for ImplementsTraitForUsize {} @@ -28,26 +18,15 @@ note: required by a bound in `try_foo` LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` -error[E0277]: the trait bound `DoesNotImplementTrait: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:40:20 +error[E0277]: the trait bound `DoesNotImplementTrait: crate_a1::Bar` is not satisfied + --> $DIR/same-crate-name.rs:38:20 | LL | a::try_foo(implements_no_traits); - | ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `DoesNotImplementTrait` + | ---------- ^^^^^^^^^^^^^^^^^^^^ the trait `crate_a1::Bar` is not implemented for `DoesNotImplementTrait` | | | required by a bound introduced by this call | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:1:1 - | -LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait - | - ::: $DIR/auxiliary/crate_a2.rs:3:1 - | -LL | pub trait Bar {} - | ------------- this is the trait that was imported - = help: you can use `cargo tree` to explore your dependency tree -help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` +help: the trait `crate_a1::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | LL | impl Bar for ImplementsTraitForUsize {} @@ -58,26 +37,16 @@ note: required by a bound in `try_foo` LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` -error[E0277]: the trait bound `ImplementsWrongTraitConditionally: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:49:20 +error[E0277]: the trait bound `ImplementsWrongTraitConditionally: crate_a1::Bar` is not satisfied + --> $DIR/same-crate-name.rs:45:20 | LL | a::try_foo(other_variant_implements_mismatched_trait); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsWrongTraitConditionally` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `crate_a1::Bar` is not implemented for `ImplementsWrongTraitConditionally` | | | required by a bound introduced by this call | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:1:1 - | -LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait - | - ::: $DIR/auxiliary/crate_a2.rs:3:1 - | -LL | pub trait Bar {} - | ------------- this is the found trait - = help: you can use `cargo tree` to explore your dependency tree -help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` + = note: `ImplementsWrongTraitConditionally` implements similarly named trait `crate_a2::Bar`, but not `crate_a1::Bar` +help: the trait `crate_a1::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | LL | impl Bar for ImplementsTraitForUsize {} @@ -88,26 +57,15 @@ note: required by a bound in `try_foo` LL | pub fn try_foo(x: impl Bar) {} | ^^^ required by this bound in `try_foo` -error[E0277]: the trait bound `ImplementsTraitForUsize: main::a::Bar` is not satisfied - --> $DIR/same-crate-name.rs:57:20 +error[E0277]: the trait bound `ImplementsTraitForUsize: crate_a1::Bar` is not satisfied + --> $DIR/same-crate-name.rs:51:20 | LL | a::try_foo(other_variant_implements_correct_trait); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `main::a::Bar` is not implemented for `ImplementsTraitForUsize` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `crate_a1::Bar` is not implemented for `ImplementsTraitForUsize` | | | required by a bound introduced by this call | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:1:1 - | -LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait - | - ::: $DIR/auxiliary/crate_a2.rs:3:1 - | -LL | pub trait Bar {} - | ------------- this is the trait that was imported - = help: you can use `cargo tree` to explore your dependency tree -help: the trait `main::a::Bar` is implemented for `ImplementsTraitForUsize` +help: the trait `crate_a1::Bar` is implemented for `ImplementsTraitForUsize` --> $DIR/auxiliary/crate_a1.rs:9:1 | LL | impl Bar for ImplementsTraitForUsize {} diff --git a/tests/ui/type/type-mismatch-same-crate-name.rs b/tests/ui/type/type-mismatch-same-crate-name.rs index df6d7aba8fd69..31fd47251660e 100644 --- a/tests/ui/type/type-mismatch-same-crate-name.rs +++ b/tests/ui/type/type-mismatch-same-crate-name.rs @@ -16,17 +16,18 @@ fn main() { extern crate crate_a1 as a; a::try_foo(foo2); //~^ ERROR mismatched types - //~| NOTE expected `main::a::Foo`, found a different `main::a::Foo` + //~| NOTE expected `crate_a1::Foo`, found `crate_a2::Foo` //~| NOTE arguments to this function are incorrect - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| NOTE `crate_a2::Foo` and `crate_a1::Foo` have similar names, but are actually distinct types + //~| NOTE `crate_a2::Foo` is defined in crate `crate_a2` + //~| NOTE `crate_a1::Foo` is defined in crate `crate_a1` //~| NOTE function defined here - //~| HELP you can use `cargo tree` to explore your dependency tree a::try_bar(bar2); //~^ ERROR mismatched types - //~| NOTE expected trait `main::a::Bar`, found a different trait `main::a::Bar` + //~| NOTE expected trait `crate_a1::Bar`, found trait `crate_a2::Bar` //~| NOTE arguments to this function are incorrect - //~| NOTE there are multiple different versions of crate `crate_a1` in the dependency graph + //~| NOTE expected struct `Box<(dyn crate_a1::Bar + 'static)>` + //~| NOTE found struct `Box` //~| NOTE function defined here - //~| HELP you can use `cargo tree` to explore your dependency tree } } diff --git a/tests/ui/type/type-mismatch-same-crate-name.stderr b/tests/ui/type/type-mismatch-same-crate-name.stderr index 2913b994e9529..71648741c2dd5 100644 --- a/tests/ui/type/type-mismatch-same-crate-name.stderr +++ b/tests/ui/type/type-mismatch-same-crate-name.stderr @@ -2,21 +2,21 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:17:20 | LL | a::try_foo(foo2); - | ---------- ^^^^ expected `main::a::Foo`, found a different `main::a::Foo` + | ---------- ^^^^ expected `crate_a1::Foo`, found `crate_a2::Foo` | | | arguments to this function are incorrect | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:1:1 + = note: `crate_a2::Foo` and `crate_a1::Foo` have similar names, but are actually distinct types +note: `crate_a2::Foo` is defined in crate `crate_a2` + --> $DIR/auxiliary/crate_a2.rs:1:1 | LL | pub struct Foo; - | ^^^^^^^^^^^^^^ this is the expected type - | - ::: $DIR/auxiliary/crate_a2.rs:1:1 + | ^^^^^^^^^^^^^^ +note: `crate_a1::Foo` is defined in crate `crate_a1` + --> $DIR/auxiliary/crate_a1.rs:1:1 | LL | pub struct Foo; - | -------------- this is the found type - = help: you can use `cargo tree` to explore your dependency tree + | ^^^^^^^^^^^^^^ note: function defined here --> $DIR/auxiliary/crate_a1.rs:10:8 | @@ -24,24 +24,15 @@ LL | pub fn try_foo(x: Foo){} | ^^^^^^^ error[E0308]: mismatched types - --> $DIR/type-mismatch-same-crate-name.rs:24:20 + --> $DIR/type-mismatch-same-crate-name.rs:25:20 | LL | a::try_bar(bar2); - | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` + | ---------- ^^^^ expected trait `crate_a1::Bar`, found trait `crate_a2::Bar` | | | arguments to this function are incorrect | -note: there are multiple different versions of crate `crate_a1` in the dependency graph - --> $DIR/auxiliary/crate_a1.rs:3:1 - | -LL | pub trait Bar {} - | ^^^^^^^^^^^^^ this is the expected trait - | - ::: $DIR/auxiliary/crate_a2.rs:3:1 - | -LL | pub trait Bar {} - | ------------- this is the found trait - = help: you can use `cargo tree` to explore your dependency tree + = note: expected struct `Box<(dyn crate_a1::Bar + 'static)>` + found struct `Box` note: function defined here --> $DIR/auxiliary/crate_a1.rs:11:8 |