Rollup merge of #32403 - vlastachu:super_in_path, r=jseyfried

Fix issue: Global paths in `use` directives can begin with `super` or `self` #32225

This PR fixes #32225 by warning on `use ::super::...` and `use ::self::...` on `resolve`.

Current changes is the most minimal and ad-hoc.
This commit is contained in:
Manish Goregaokar 2016-04-05 16:43:20 +05:30
commit bdd264a0bb
6 changed files with 58 additions and 9 deletions

View File

@ -179,6 +179,12 @@ declare_lint! {
"lints that have been renamed or removed"
}
declare_lint! {
pub SUPER_OR_SELF_IN_GLOBAL_PATH,
Warn,
"detects super or self keywords at the beginning of global path"
}
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
@ -213,7 +219,8 @@ impl LintPass for HardwiredLints {
RAW_POINTER_DERIVE,
TRANSMUTE_FROM_FN_ITEM_TYPES,
OVERLAPPING_INHERENT_IMPLS,
RENAMED_AND_REMOVED_LINTS
RENAMED_AND_REMOVED_LINTS,
SUPER_OR_SELF_IN_GLOBAL_PATH
)
}
}

View File

@ -167,6 +167,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
},
FutureIncompatibleInfo {
id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH),
reference: "PR #32403 <https://github.com/rust-lang/rust/pull/32403>",
},
FutureIncompatibleInfo {
id: LintId::of(MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT),
reference: "RFC 218 <https://github.com/rust-lang/rfcs/blob/\

View File

@ -23,13 +23,14 @@ use Resolver;
use {resolve_error, resolve_struct_error, ResolutionError};
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
use rustc::lint;
use rustc::middle::def::*;
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::ty::VariantKind;
use syntax::ast::Name;
use syntax::attr::AttrMetaMethods;
use syntax::parse::token::special_idents;
use syntax::parse::token::{special_idents, SELF_KEYWORD_NAME, SUPER_KEYWORD_NAME};
use syntax::codemap::{Span, DUMMY_SP};
use rustc_front::hir;
@ -116,8 +117,10 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path = match view_path.node {
let is_global;
let module_path: Vec<Name> = match view_path.node {
ViewPathSimple(_, ref full_path) => {
is_global = full_path.global;
full_path.segments
.split_last()
.unwrap()
@ -129,6 +132,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
ViewPathGlob(ref module_ident_path) |
ViewPathList(ref module_ident_path, _) => {
is_global = module_ident_path.global;
module_ident_path.segments
.iter()
.map(|seg| seg.identifier.name)
@ -136,6 +140,18 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
}
};
// Checking for special identifiers in path
// prevent `self` or `super` at beginning of global path
if is_global && (module_path.first() == Some(&SELF_KEYWORD_NAME) ||
module_path.first() == Some(&SUPER_KEYWORD_NAME)) {
self.session.add_lint(
lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
item.id,
item.span,
format!("expected identifier, found keyword `{}`",
module_path.first().unwrap().as_str()));
}
// Build up the import directives.
let is_prelude = item.attrs.iter().any(|attr| {
attr.name() == special_idents::prelude_import.name.as_str()

View File

@ -6124,7 +6124,7 @@ impl<'a> Parser<'a> {
// Allow a leading :: because the paths are absolute either way.
// This occurs with "use $crate::..." in macros.
self.eat(&token::ModSep);
let is_global = self.eat(&token::ModSep);
if self.check(&token::OpenDelim(token::Brace)) {
// use {foo,bar}
@ -6135,7 +6135,7 @@ impl<'a> Parser<'a> {
|p| p.parse_path_list_item())?;
let path = ast::Path {
span: mk_sp(lo, self.span.hi),
global: false,
global: is_global,
segments: Vec::new()
};
return Ok(P(spanned(lo, self.span.hi, ViewPathList(path, idents))));
@ -6164,7 +6164,7 @@ impl<'a> Parser<'a> {
)?;
let path = ast::Path {
span: mk_sp(lo, self.span.hi),
global: false,
global: is_global,
segments: path.into_iter().map(|identifier| {
ast::PathSegment {
identifier: identifier,
@ -6180,7 +6180,7 @@ impl<'a> Parser<'a> {
self.bump();
let path = ast::Path {
span: mk_sp(lo, self.span.hi),
global: false,
global: is_global,
segments: path.into_iter().map(|identifier| {
ast::PathSegment {
identifier: identifier,
@ -6203,7 +6203,7 @@ impl<'a> Parser<'a> {
let mut rename_to = path[path.len() - 1];
let path = ast::Path {
span: mk_sp(lo, self.last_span.hi),
global: false,
global: is_global,
segments: path.into_iter().map(|identifier| {
ast::PathSegment {
identifier: identifier,

View File

@ -514,7 +514,7 @@ macro_rules! declare_special_idents_and_keywords {(
// If the special idents get renumbered, remember to modify these two as appropriate
pub const SELF_KEYWORD_NAME: ast::Name = ast::Name(SELF_KEYWORD_NAME_NUM);
const STATIC_KEYWORD_NAME: ast::Name = ast::Name(STATIC_KEYWORD_NAME_NUM);
const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM);
pub const SUPER_KEYWORD_NAME: ast::Name = ast::Name(SUPER_KEYWORD_NAME_NUM);
const SELF_TYPE_KEYWORD_NAME: ast::Name = ast::Name(SELF_TYPE_KEYWORD_NAME_NUM);
pub const SELF_KEYWORD_NAME_NUM: u32 = 1;

View File

@ -0,0 +1,22 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(rustc_attrs)]
mod foo {
pub fn g() {
use ::super::main; //~ WARN expected identifier, found keyword `super`
//~^ WARN this was previously accepted by the compiler but is being phased out
main();
}
}
#[rustc_error]
fn main() { foo::g(); } //~ ERROR compilation successful