Skip to content

Commit bdd264a

Browse files
committed
Rollup merge of rust-lang#32403 - vlastachu:super_in_path, r=jseyfried
Fix issue: Global paths in `use` directives can begin with `super` or `self` rust-lang#32225 This PR fixes rust-lang#32225 by warning on `use ::super::...` and `use ::self::...` on `resolve`. Current changes is the most minimal and ad-hoc.
2 parents 7fd331e + 6c73134 commit bdd264a

File tree

6 files changed

+58
-9
lines changed

6 files changed

+58
-9
lines changed

src/librustc/lint/builtin.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ declare_lint! {
179179
"lints that have been renamed or removed"
180180
}
181181

182+
declare_lint! {
183+
pub SUPER_OR_SELF_IN_GLOBAL_PATH,
184+
Warn,
185+
"detects super or self keywords at the beginning of global path"
186+
}
187+
182188
/// Does nothing as a lint pass, but registers some `Lint`s
183189
/// which are used by other parts of the compiler.
184190
#[derive(Copy, Clone)]
@@ -213,7 +219,8 @@ impl LintPass for HardwiredLints {
213219
RAW_POINTER_DERIVE,
214220
TRANSMUTE_FROM_FN_ITEM_TYPES,
215221
OVERLAPPING_INHERENT_IMPLS,
216-
RENAMED_AND_REMOVED_LINTS
222+
RENAMED_AND_REMOVED_LINTS,
223+
SUPER_OR_SELF_IN_GLOBAL_PATH
217224
)
218225
}
219226
}

src/librustc_lint/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
167167
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
168168
reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
169169
},
170+
FutureIncompatibleInfo {
171+
id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH),
172+
reference: "PR #32403 <https://github.com/rust-lang/rust/pull/32403>",
173+
},
170174
FutureIncompatibleInfo {
171175
id: LintId::of(MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT),
172176
reference: "RFC 218 <https://github.com/rust-lang/rfcs/blob/\

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ use Resolver;
2323
use {resolve_error, resolve_struct_error, ResolutionError};
2424

2525
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
26+
use rustc::lint;
2627
use rustc::middle::def::*;
2728
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
2829
use rustc::ty::VariantKind;
2930

3031
use syntax::ast::Name;
3132
use syntax::attr::AttrMetaMethods;
32-
use syntax::parse::token::special_idents;
33+
use syntax::parse::token::{special_idents, SELF_KEYWORD_NAME, SUPER_KEYWORD_NAME};
3334
use syntax::codemap::{Span, DUMMY_SP};
3435

3536
use rustc_front::hir;
@@ -116,8 +117,10 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
116117
// Extract and intern the module part of the path. For
117118
// globs and lists, the path is found directly in the AST;
118119
// for simple paths we have to munge the path a little.
119-
let module_path = match view_path.node {
120+
let is_global;
121+
let module_path: Vec<Name> = match view_path.node {
120122
ViewPathSimple(_, ref full_path) => {
123+
is_global = full_path.global;
121124
full_path.segments
122125
.split_last()
123126
.unwrap()
@@ -129,13 +132,26 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
129132

130133
ViewPathGlob(ref module_ident_path) |
131134
ViewPathList(ref module_ident_path, _) => {
135+
is_global = module_ident_path.global;
132136
module_ident_path.segments
133137
.iter()
134138
.map(|seg| seg.identifier.name)
135139
.collect()
136140
}
137141
};
138142

143+
// Checking for special identifiers in path
144+
// prevent `self` or `super` at beginning of global path
145+
if is_global && (module_path.first() == Some(&SELF_KEYWORD_NAME) ||
146+
module_path.first() == Some(&SUPER_KEYWORD_NAME)) {
147+
self.session.add_lint(
148+
lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
149+
item.id,
150+
item.span,
151+
format!("expected identifier, found keyword `{}`",
152+
module_path.first().unwrap().as_str()));
153+
}
154+
139155
// Build up the import directives.
140156
let is_prelude = item.attrs.iter().any(|attr| {
141157
attr.name() == special_idents::prelude_import.name.as_str()

src/libsyntax/parse/parser.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6124,7 +6124,7 @@ impl<'a> Parser<'a> {
61246124

61256125
// Allow a leading :: because the paths are absolute either way.
61266126
// This occurs with "use $crate::..." in macros.
6127-
self.eat(&token::ModSep);
6127+
let is_global = self.eat(&token::ModSep);
61286128

61296129
if self.check(&token::OpenDelim(token::Brace)) {
61306130
// use {foo,bar}
@@ -6135,7 +6135,7 @@ impl<'a> Parser<'a> {
61356135
|p| p.parse_path_list_item())?;
61366136
let path = ast::Path {
61376137
span: mk_sp(lo, self.span.hi),
6138-
global: false,
6138+
global: is_global,
61396139
segments: Vec::new()
61406140
};
61416141
return Ok(P(spanned(lo, self.span.hi, ViewPathList(path, idents))));
@@ -6164,7 +6164,7 @@ impl<'a> Parser<'a> {
61646164
)?;
61656165
let path = ast::Path {
61666166
span: mk_sp(lo, self.span.hi),
6167-
global: false,
6167+
global: is_global,
61686168
segments: path.into_iter().map(|identifier| {
61696169
ast::PathSegment {
61706170
identifier: identifier,
@@ -6180,7 +6180,7 @@ impl<'a> Parser<'a> {
61806180
self.bump();
61816181
let path = ast::Path {
61826182
span: mk_sp(lo, self.span.hi),
6183-
global: false,
6183+
global: is_global,
61846184
segments: path.into_iter().map(|identifier| {
61856185
ast::PathSegment {
61866186
identifier: identifier,
@@ -6203,7 +6203,7 @@ impl<'a> Parser<'a> {
62036203
let mut rename_to = path[path.len() - 1];
62046204
let path = ast::Path {
62056205
span: mk_sp(lo, self.last_span.hi),
6206-
global: false,
6206+
global: is_global,
62076207
segments: path.into_iter().map(|identifier| {
62086208
ast::PathSegment {
62096209
identifier: identifier,

src/libsyntax/parse/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ macro_rules! declare_special_idents_and_keywords {(
514514
// If the special idents get renumbered, remember to modify these two as appropriate
515515
pub const SELF_KEYWORD_NAME: ast::Name = ast::Name(SELF_KEYWORD_NAME_NUM);
516516
const STATIC_KEYWORD_NAME: ast::Name = ast::Name(STATIC_KEYWORD_NAME_NUM);
517-
const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM);
517+
pub const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM);
518518
const SELF_TYPE_KEYWORD_NAME: ast::Name = ast::Name(SELF_TYPE_KEYWORD_NAME_NUM);
519519

520520
pub const SELF_KEYWORD_NAME_NUM: u32 = 1;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rustc_attrs)]
12+
13+
mod foo {
14+
pub fn g() {
15+
use ::super::main; //~ WARN expected identifier, found keyword `super`
16+
//~^ WARN this was previously accepted by the compiler but is being phased out
17+
main();
18+
}
19+
}
20+
21+
#[rustc_error]
22+
fn main() { foo::g(); } //~ ERROR compilation successful

0 commit comments

Comments
 (0)