Skip to content

Commit 6c73134

Browse files
committed
Fixes bug which accepting using super in use statemet.
Issue: #32225
1 parent 211c35a commit 6c73134

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
@@ -24,13 +24,14 @@ use Resolver;
2424
use {resolve_error, resolve_struct_error, ResolutionError};
2525

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

3132
use syntax::ast::{Name, NodeId};
3233
use syntax::attr::AttrMetaMethods;
33-
use syntax::parse::token::special_idents;
34+
use syntax::parse::token::{special_idents, SELF_KEYWORD_NAME, SUPER_KEYWORD_NAME};
3435
use syntax::codemap::{Span, DUMMY_SP};
3536

3637
use rustc_front::hir;
@@ -117,8 +118,10 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
117118
// Extract and intern the module part of the path. For
118119
// globs and lists, the path is found directly in the AST;
119120
// for simple paths we have to munge the path a little.
120-
let module_path = match view_path.node {
121+
let is_global;
122+
let module_path: Vec<Name> = match view_path.node {
121123
ViewPathSimple(_, ref full_path) => {
124+
is_global = full_path.global;
122125
full_path.segments
123126
.split_last()
124127
.unwrap()
@@ -130,13 +133,26 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
130133

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

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