diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index cfb49d9a21d1..c4a0cde2837a 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -649,10 +649,17 @@ fn build_reduced_graph_for_use_tree( } } kw::Super => { - if module_path.iter().any(|seg| seg.ident.name != kw::Super) { + // Allow `self::super` as a valid prefix - `self` at position 0 + // followed by any number of `super` segments. + let valid_prefix = module_path.iter().enumerate().all(|(i, seg)| { + let name = seg.ident.name; + name == kw::Super || (name == kw::SelfLower && i == 0) + }); + + if !valid_prefix { self.r.dcx().span_err( source.ident.span, - "`super` in paths can only be used in start position or after another `super`", + "`super` in paths can only be used in start position, after `self`, or after another `super`", ); return; } diff --git a/tests/ui/use/use-path-segment-kw.e2015.stderr b/tests/ui/use/use-path-segment-kw.e2015.stderr index df16de85d279..908e739ec520 100644 --- a/tests/ui/use/use-path-segment-kw.e2015.stderr +++ b/tests/ui/use/use-path-segment-kw.e2015.stderr @@ -140,77 +140,77 @@ help: try renaming it with a name LL | use super as name; | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:139:15 | LL | use ::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:140:15 | LL | use ::super as _super2; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:141:16 | LL | use ::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:142:16 | -LL | use ::{super as _nested_super2}; - | ^^^^^ +LL | ... use ::{super as _nested_super2}; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:145:21 | LL | use foobar::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:146:21 | -LL | use foobar::super as _super3; - | ^^^^^ +LL | ... use foobar::super as _super3; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:147:22 | LL | use foobar::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:148:22 | -LL | use foobar::{super as _nested_super3}; - | ^^^^^ +LL | ... use foobar::{super as _nested_super3}; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:151:20 | LL | use crate::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:152:20 | -LL | use crate::super as _super4; - | ^^^^^ +LL | ... use crate::super as _super4; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:153:21 | LL | use crate::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:154:21 | -LL | use crate::{super as _nested_super4}; - | ^^^^^ +LL | ... use crate::{super as _nested_super4}; + | ^^^^^ error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:157:20 @@ -234,29 +234,27 @@ help: try renaming it with a name LL | use super::{super as name}; | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:163:19 | LL | use self::super; | ^^^^^ - -error: `super` in paths can only be used in start position or after another `super` - --> $DIR/use-path-segment-kw.rs:164:19 | -LL | use self::super as _super6; - | ^^^^^ +help: try renaming it with a name + | +LL | use self::super as name; + | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:165:20 | LL | use self::{super}; | ^^^^^ - -error: `super` in paths can only be used in start position or after another `super` - --> $DIR/use-path-segment-kw.rs:166:20 | -LL | use self::{super as _nested_super6}; - | ^^^^^ +help: try renaming it with a name + | +LL | use self::{super as name}; + | +++++++ error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:173:13 @@ -827,7 +825,7 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:57:21 | LL | use $crate::super; @@ -838,18 +836,18 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:58:21 | -LL | use $crate::super as _m_super8; - | ^^^^^ +LL | ... use $crate::super as _m_super8; + | ^^^^^ ... -LL | macro_dollar_crate!(); - | --------------------- in this macro invocation +LL | ... macro_dollar_crate!(); + | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:59:22 | LL | use $crate::{super}; @@ -860,14 +858,14 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:60:22 | -LL | use $crate::{super as _m_nested_super8}; - | ^^^^^ +LL | ... use $crate::{super as _m_nested_super8}; + | ^^^^^ ... -LL | macro_dollar_crate!(); - | --------------------- in this macro invocation +LL | ... macro_dollar_crate!(); + | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -1195,7 +1193,7 @@ error[E0433]: `self` in paths can only be used in start position LL | type D6 = self::self; | ^^^^ can only be used in path start position -error: aborting due to 131 previous errors +error: aborting due to 129 previous errors Some errors have detailed explanations: E0429, E0432, E0433, E0573. For more information about an error, try `rustc --explain E0429`. diff --git a/tests/ui/use/use-path-segment-kw.e2018.stderr b/tests/ui/use/use-path-segment-kw.e2018.stderr index 35772f640d56..878fd166b845 100644 --- a/tests/ui/use/use-path-segment-kw.e2018.stderr +++ b/tests/ui/use/use-path-segment-kw.e2018.stderr @@ -140,77 +140,77 @@ help: try renaming it with a name LL | use super as name; | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:139:15 | LL | use ::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:140:15 | LL | use ::super as _super2; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:141:16 | LL | use ::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:142:16 | -LL | use ::{super as _nested_super2}; - | ^^^^^ +LL | ... use ::{super as _nested_super2}; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:145:21 | LL | use foobar::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:146:21 | -LL | use foobar::super as _super3; - | ^^^^^ +LL | ... use foobar::super as _super3; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:147:22 | LL | use foobar::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:148:22 | -LL | use foobar::{super as _nested_super3}; - | ^^^^^ +LL | ... use foobar::{super as _nested_super3}; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:151:20 | LL | use crate::super; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:152:20 | -LL | use crate::super as _super4; - | ^^^^^ +LL | ... use crate::super as _super4; + | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:153:21 | LL | use crate::{super}; | ^^^^^ -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:154:21 | -LL | use crate::{super as _nested_super4}; - | ^^^^^ +LL | ... use crate::{super as _nested_super4}; + | ^^^^^ error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:157:20 @@ -234,29 +234,27 @@ help: try renaming it with a name LL | use super::{super as name}; | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:163:19 | LL | use self::super; | ^^^^^ - -error: `super` in paths can only be used in start position or after another `super` - --> $DIR/use-path-segment-kw.rs:164:19 | -LL | use self::super as _super6; - | ^^^^^ +help: try renaming it with a name + | +LL | use self::super as name; + | +++++++ -error: `super` in paths can only be used in start position or after another `super` +error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:165:20 | LL | use self::{super}; | ^^^^^ - -error: `super` in paths can only be used in start position or after another `super` - --> $DIR/use-path-segment-kw.rs:166:20 | -LL | use self::{super as _nested_super6}; - | ^^^^^ +help: try renaming it with a name + | +LL | use self::{super as name}; + | +++++++ error: imports need to be explicitly named --> $DIR/use-path-segment-kw.rs:173:13 @@ -822,7 +820,7 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:57:21 | LL | use $crate::super; @@ -833,18 +831,18 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:58:21 | -LL | use $crate::super as _m_super8; - | ^^^^^ +LL | ... use $crate::super as _m_super8; + | ^^^^^ ... -LL | macro_dollar_crate!(); - | --------------------- in this macro invocation +LL | ... macro_dollar_crate!(); + | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:59:22 | LL | use $crate::{super}; @@ -855,14 +853,14 @@ LL | macro_dollar_crate!(); | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error: `super` in paths can only be used in start position or after another `super` +error: `super` in paths can only be used in start position, after `self`, or after another `super` --> $DIR/use-path-segment-kw.rs:60:22 | -LL | use $crate::{super as _m_nested_super8}; - | ^^^^^ +LL | ... use $crate::{super as _m_nested_super8}; + | ^^^^^ ... -LL | macro_dollar_crate!(); - | --------------------- in this macro invocation +LL | ... macro_dollar_crate!(); + | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -939,7 +937,7 @@ LL | type D7 = crate::foo::bar::self; | ^^^^ can only be used in path start position error[E0433]: cannot find `_nested_self2` in `bar` - --> $DIR/use-path-segment-kw.rs:239:15 + --> $DIR/use-path-segment-kw.rs:241:15 | LL | foo::bar::_nested_self2::outer(); | ^^^^^^^^^^^^^ could not find `_nested_self2` in `bar` @@ -1162,7 +1160,7 @@ error[E0433]: `self` in paths can only be used in start position LL | type D6 = self::self; | ^^^^ can only be used in path start position -error: aborting due to 128 previous errors +error: aborting due to 126 previous errors Some errors have detailed explanations: E0429, E0433, E0573. For more information about an error, try `rustc --explain E0429`. diff --git a/tests/ui/use/use-path-segment-kw.rs b/tests/ui/use/use-path-segment-kw.rs index ac3389c9da40..be64f239b9fc 100644 --- a/tests/ui/use/use-path-segment-kw.rs +++ b/tests/ui/use/use-path-segment-kw.rs @@ -54,10 +54,10 @@ macro_rules! macro_dollar_crate { use $crate::{crate as _m_nested_crate8}; //~ ERROR `crate` in paths can only be used in start position type A9 = $crate::super; //~ ERROR `super` in paths can only be used in start position - use $crate::super; //~ ERROR `super` in paths can only be used in start position or after another `super` - use $crate::super as _m_super8; //~ ERROR `super` in paths can only be used in start position or after another `super` - use $crate::{super}; //~ ERROR `super` in paths can only be used in start position or after another `super` - use $crate::{super as _m_nested_super8}; //~ ERROR `super` in paths can only be used in start position or after another `super` + use $crate::super; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use $crate::super as _m_super8; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use $crate::{super}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use $crate::{super as _m_nested_super8}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` type A10 = $crate::self; //~ ERROR `self` in paths can only be used in start position use $crate::self; //~ ERROR imports need to be explicitly named @@ -136,22 +136,22 @@ pub fn inner() {} pub use super as _super; type C2 = ::super; //~ ERROR global paths cannot start with `super` - use ::super; //~ ERROR `super` in paths can only be used in start position or after another `super` - use ::super as _super2; //~ ERROR `super` in paths can only be used in start position or after another `super` - use ::{super}; //~ ERROR `super` in paths can only be used in start position or after another `super` - use ::{super as _nested_super2}; //~ ERROR `super` in paths can only be used in start position or after another `super` + use ::super; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use ::super as _super2; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use ::{super}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use ::{super as _nested_super2}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` type C3 = foobar::super; //~ ERROR `super` in paths can only be used in start position - use foobar::super; //~ ERROR `super` in paths can only be used in start position or after another `super` - use foobar::super as _super3; //~ ERROR `super` in paths can only be used in start position or after another `super` - use foobar::{super}; //~ ERROR `super` in paths can only be used in start position or after another `super` - use foobar::{super as _nested_super3}; //~ ERROR `super` in paths can only be used in start position or after another `super` + use foobar::super; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use foobar::super as _super3; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use foobar::{super}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use foobar::{super as _nested_super3}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` type C4 = crate::super; //~ ERROR `super` in paths can only be used in start position - use crate::super; //~ ERROR `super` in paths can only be used in start position or after another `super` - use crate::super as _super4; //~ ERROR `super` in paths can only be used in start position or after another `super` - use crate::{super}; //~ ERROR `super` in paths can only be used in start position or after another `super` - use crate::{super as _nested_super4}; //~ ERROR `super` in paths can only be used in start position or after another `super` + use crate::super; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use crate::super as _super4; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use crate::{super}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` + use crate::{super as _nested_super4}; //~ ERROR `super` in paths can only be used in start position, after `self`, or after another `super` type C5 = super::super; //~ ERROR expected type, found module `super::super` use super::super; //~ ERROR imports need to be explicitly named @@ -160,10 +160,10 @@ pub fn inner() {} pub use super::{super as _nested_super5}; type C6 = self::super; //~ ERROR expected type, found module `self::super` - use self::super; //~ ERROR `super` in paths can only be used in start position or after another `super` - use self::super as _super6; //~ ERROR `super` in paths can only be used in start position or after another `super` - use self::{super}; //~ ERROR `super` in paths can only be used in start position or after another `super` - use self::{super as _nested_super6}; //~ ERROR `super` in paths can only be used in start position or after another `super` + use self::super; //~ ERROR imports need to be explicitly named + pub use self::super as _super6; + use self::{super}; //~ ERROR imports need to be explicitly named + pub use self::{super as _nested_super6}; // --- self --- // use self::*; // Suppress other errors @@ -232,6 +232,8 @@ fn main() { foo::bar::_super::bar::foobar::inner(); foo::bar::_super5::outer(); foo::bar::_nested_super5::outer(); + foo::bar::_super6::bar::foobar::inner(); + foo::bar::_nested_super6::bar::foobar::inner(); foo::bar::_self::foobar::inner(); foo::bar::qux::inner(); // Works after recovery