diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 7e6375968ae..2e2d3674560 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -443,11 +443,22 @@ impl<'a> ResolverExpand for Resolver<'a> { PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => { return Ok(true); } + PathResult::NonModule(..) | + // HACK(Urgau): This shouldn't be necessary + PathResult::Failed { is_error_from_last_segment: false, .. } => { + self.session + .struct_span_err(span, "not sure whether the path is accessible or not") + .note("the type may have associated items, but we are currently not checking them") + .emit(); + + // If we get a partially resolved NonModule in one namespace, we should get the + // same result in any other namespaces, so we can return early. + return Ok(false); + } PathResult::Indeterminate => indeterminate = true, - // FIXME: `resolve_path` is not ready to report partially resolved paths - // correctly, so we just report an error if the path was reported as unresolved. - // This needs to be fixed for `cfg_accessible` to be useful. - PathResult::NonModule(..) | PathResult::Failed { .. } => {} + // We can only be sure that a path doesn't exist after having tested all the + // posibilities, only at that time we can return false. + PathResult::Failed { .. } => {} PathResult::Module(_) => panic!("unexpected path resolution"), } } @@ -456,10 +467,6 @@ impl<'a> ResolverExpand for Resolver<'a> { return Err(Indeterminate); } - self.session - .struct_span_err(span, "not sure whether the path is accessible or not") - .span_note(span, "`cfg_accessible` is not fully implemented") - .emit(); Ok(false) } diff --git a/src/test/ui/conditional-compilation/cfg_accessible-bugs.rs b/src/test/ui/conditional-compilation/cfg_accessible-bugs.rs new file mode 100644 index 00000000000..ae18bc55c4f --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-bugs.rs @@ -0,0 +1,18 @@ +// This test is a collection of test that should pass. +// +// check-fail + +#![feature(cfg_accessible)] +#![feature(trait_alias)] + +trait TraitAlias = std::fmt::Debug + Send; + +// FIXME: Currently shows "cannot determine" but should be `false` +#[cfg_accessible(unresolved)] //~ ERROR cannot determine +const C: bool = true; + +// FIXME: Currently shows "not sure" but should be `false` +#[cfg_accessible(TraitAlias::unresolved)] //~ ERROR not sure whether the path is accessible or not +const D: bool = true; + +fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg_accessible-bugs.stderr b/src/test/ui/conditional-compilation/cfg_accessible-bugs.stderr new file mode 100644 index 00000000000..81f02387835 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-bugs.stderr @@ -0,0 +1,16 @@ +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-bugs.rs:15:18 + | +LL | #[cfg_accessible(TraitAlias::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: cannot determine whether the path is accessible or not + --> $DIR/cfg_accessible-bugs.rs:11:1 + | +LL | #[cfg_accessible(unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2015.stderr b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2015.stderr new file mode 100644 index 00000000000..7d5dd589027 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2015.stderr @@ -0,0 +1,122 @@ +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:14:18 + | +LL | #[cfg_accessible(Struct::existing)] + | ^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:16:18 + | +LL | #[cfg_accessible(Struct::unresolved)] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:25:18 + | +LL | #[cfg_accessible(Union::existing)] + | ^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:27:18 + | +LL | #[cfg_accessible(Union::unresolved)] + | ^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:36:18 + | +LL | #[cfg_accessible(Enum::Existing::existing)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:38:18 + | +LL | #[cfg_accessible(Enum::Existing::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:40:18 + | +LL | #[cfg_accessible(Enum::unresolved)] + | ^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:50:18 + | +LL | #[cfg_accessible(Trait::existing)] + | ^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:52:18 + | +LL | #[cfg_accessible(Trait::unresolved)] + | ^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:59:18 + | +LL | #[cfg_accessible(TypeAlias::existing)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:61:18 + | +LL | #[cfg_accessible(TypeAlias::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:70:18 + | +LL | #[cfg_accessible(ForeignType::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:79:18 + | +LL | #[cfg_accessible(AssocType::AssocType::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:84:18 + | +LL | #[cfg_accessible(u8::unresolved)] + | ^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:86:18 + | +LL | #[cfg_accessible(u8::is_ascii)] + | ^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: aborting due to 15 previous errors + diff --git a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2021.stderr b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2021.stderr new file mode 100644 index 00000000000..7d5dd589027 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.edition2021.stderr @@ -0,0 +1,122 @@ +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:14:18 + | +LL | #[cfg_accessible(Struct::existing)] + | ^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:16:18 + | +LL | #[cfg_accessible(Struct::unresolved)] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:25:18 + | +LL | #[cfg_accessible(Union::existing)] + | ^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:27:18 + | +LL | #[cfg_accessible(Union::unresolved)] + | ^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:36:18 + | +LL | #[cfg_accessible(Enum::Existing::existing)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:38:18 + | +LL | #[cfg_accessible(Enum::Existing::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:40:18 + | +LL | #[cfg_accessible(Enum::unresolved)] + | ^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:50:18 + | +LL | #[cfg_accessible(Trait::existing)] + | ^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:52:18 + | +LL | #[cfg_accessible(Trait::unresolved)] + | ^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:59:18 + | +LL | #[cfg_accessible(TypeAlias::existing)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:61:18 + | +LL | #[cfg_accessible(TypeAlias::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:70:18 + | +LL | #[cfg_accessible(ForeignType::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:79:18 + | +LL | #[cfg_accessible(AssocType::AssocType::unresolved)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:84:18 + | +LL | #[cfg_accessible(u8::unresolved)] + | ^^^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: not sure whether the path is accessible or not + --> $DIR/cfg_accessible-not_sure.rs:86:18 + | +LL | #[cfg_accessible(u8::is_ascii)] + | ^^^^^^^^^^^^ + | + = note: the type may have associated items, but we are currently not checking them + +error: aborting due to 15 previous errors + diff --git a/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs new file mode 100644 index 00000000000..d68acd2451f --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-not_sure.rs @@ -0,0 +1,89 @@ +// revisions: edition2015 edition2021 +// [edition2015]compile-flags: --edition=2015 +// [edition2021]compile-flags: --edition=2021 + +#![feature(extern_types)] +#![feature(cfg_accessible)] + +// Struct::unresolved - error + +struct Struct { + existing: u8, +} + +#[cfg_accessible(Struct::existing)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(Struct::unresolved)] //~ ERROR not sure +const B: bool = true; + +// Union::unresolved - error + +struct Union { + existing: u8, +} + +#[cfg_accessible(Union::existing)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(Union::unresolved)] //~ ERROR not sure +const B: bool = true; + +// Enum::unresolved - error + +enum Enum { + Existing { existing: u8 }, +} + +#[cfg_accessible(Enum::Existing::existing)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(Enum::Existing::unresolved)] //~ ERROR not sure +const B: bool = true; +#[cfg_accessible(Enum::unresolved)] //~ ERROR not sure +const C: bool = true; + +// Trait::unresolved - false or error, depending on edition (error if you can write Trait::foo +// instead of ::foo for methods like impl dyn Trait { fn foo() {} }) + +trait Trait {} +impl dyn Trait { fn existing() {} } + +// FIXME: Should be a error for edition > 2015 +#[cfg_accessible(Trait::existing)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(Trait::unresolved)] //~ ERROR not sure +const B: bool = true; + +// TypeAlias::unresolved - error + +type TypeAlias = Struct; + +#[cfg_accessible(TypeAlias::existing)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(TypeAlias::unresolved)] //~ ERROR not sure +const B: bool = true; + +// ForeignType::unresolved - error + +extern { + type ForeignType; +} + +#[cfg_accessible(ForeignType::unresolved)] //~ ERROR not sure +const A: bool = true; + +// AssocType::unresolved - error + +trait AssocType { + type AssocType; +} + +#[cfg_accessible(AssocType::AssocType::unresolved)] //~ ERROR not sure +const A: bool = true; + +// PrimitiveType::unresolved - error + +#[cfg_accessible(u8::unresolved)] //~ ERROR not sure +const A: bool = true; +#[cfg_accessible(u8::is_ascii)] //~ ERROR not sure +const B: bool = true; + +fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg_accessible-private.rs b/src/test/ui/conditional-compilation/cfg_accessible-private.rs new file mode 100644 index 00000000000..5b095675c79 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg_accessible-private.rs @@ -0,0 +1,21 @@ +// check-pass + +#![feature(cfg_accessible)] + +mod private { + struct Struct; + enum Enum{} + union Union{_a:u8} +} + +#[cfg_accessible(private::Struct)] +const A: bool = true; + +#[cfg_accessible(private::Enum)] +const A: bool = true; + +#[cfg_accessible(private::Union)] +const A: bool = true; + +const A: bool = false; // Will conflict if any of those is accessible +fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg_accessible.rs b/src/test/ui/conditional-compilation/cfg_accessible.rs index 07b0be5b1ae..df380d0d16f 100644 --- a/src/test/ui/conditional-compilation/cfg_accessible.rs +++ b/src/test/ui/conditional-compilation/cfg_accessible.rs @@ -5,20 +5,35 @@ mod m { struct ExistingPrivate; } +trait Trait { + type Assoc; +} + +enum Enum { + Existing, +} + +#[cfg_accessible(Enum)] +struct ExistingResolved; + +#[cfg_accessible(Enum::Existing)] +struct ExistingResolvedVariant; + #[cfg_accessible(m::ExistingPublic)] struct ExistingPublic; -// FIXME: Not implemented yet. -#[cfg_accessible(m::ExistingPrivate)] //~ ERROR not sure whether the path is accessible or not +#[cfg_accessible(m::ExistingPrivate)] struct ExistingPrivate; -// FIXME: Not implemented yet. -#[cfg_accessible(m::NonExistent)] //~ ERROR not sure whether the path is accessible or not -struct ExistingPrivate; +#[cfg_accessible(m::NonExistent)] +struct NonExistingPrivate; #[cfg_accessible(n::AccessibleExpanded)] // OK, `cfg_accessible` can wait and retry. struct AccessibleExpanded; +#[cfg_accessible(Trait::Assoc)] +struct AccessibleTraitAssoc; + macro_rules! generate_accessible_expanded { () => { mod n { @@ -29,15 +44,12 @@ macro_rules! generate_accessible_expanded { generate_accessible_expanded!(); -struct S { - field: u8, -} - -// FIXME: Not implemented yet. -#[cfg_accessible(S::field)] //~ ERROR not sure whether the path is accessible or not -struct Field; - fn main() { ExistingPublic; AccessibleExpanded; + AccessibleTraitAssoc; + + ExistingPrivate; //~ ERROR cannot find + NonExistingPrivate; //~ ERROR cannot find + NonExistingTraitAlias; //~ ERROR cannot find } diff --git a/src/test/ui/conditional-compilation/cfg_accessible.stderr b/src/test/ui/conditional-compilation/cfg_accessible.stderr index 167765cd66e..e3731a1ad71 100644 --- a/src/test/ui/conditional-compilation/cfg_accessible.stderr +++ b/src/test/ui/conditional-compilation/cfg_accessible.stderr @@ -1,38 +1,27 @@ -error: not sure whether the path is accessible or not - --> $DIR/cfg_accessible.rs:12:18 +error[E0425]: cannot find value `ExistingPrivate` in this scope + --> $DIR/cfg_accessible.rs:52:5 | -LL | #[cfg_accessible(m::ExistingPrivate)] - | ^^^^^^^^^^^^^^^^^^ +LL | ExistingPrivate; + | ^^^^^^^^^^^^^^^ not found in this scope | -note: `cfg_accessible` is not fully implemented - --> $DIR/cfg_accessible.rs:12:18 +note: unit struct `m::ExistingPrivate` exists but is inaccessible + --> $DIR/cfg_accessible.rs:5:5 | -LL | #[cfg_accessible(m::ExistingPrivate)] - | ^^^^^^^^^^^^^^^^^^ +LL | struct ExistingPrivate; + | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible -error: not sure whether the path is accessible or not - --> $DIR/cfg_accessible.rs:16:18 +error[E0425]: cannot find value `NonExistingPrivate` in this scope + --> $DIR/cfg_accessible.rs:53:5 | -LL | #[cfg_accessible(m::NonExistent)] - | ^^^^^^^^^^^^^^ - | -note: `cfg_accessible` is not fully implemented - --> $DIR/cfg_accessible.rs:16:18 - | -LL | #[cfg_accessible(m::NonExistent)] - | ^^^^^^^^^^^^^^ +LL | NonExistingPrivate; + | ^^^^^^^^^^^^^^^^^^ not found in this scope -error: not sure whether the path is accessible or not - --> $DIR/cfg_accessible.rs:37:18 +error[E0425]: cannot find value `NonExistingTraitAlias` in this scope + --> $DIR/cfg_accessible.rs:54:5 | -LL | #[cfg_accessible(S::field)] - | ^^^^^^^^ - | -note: `cfg_accessible` is not fully implemented - --> $DIR/cfg_accessible.rs:37:18 - | -LL | #[cfg_accessible(S::field)] - | ^^^^^^^^ +LL | NonExistingTraitAlias; + | ^^^^^^^^^^^^^^^^^^^^^ not found in this scope error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0425`.