mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
parent
211c35afcb
commit
6c73134fc7
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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/\
|
||||
|
@ -24,13 +24,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, NodeId};
|
||||
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;
|
||||
@ -117,8 +118,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()
|
||||
@ -130,6 +133,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)
|
||||
@ -137,6 +141,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()
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
22
src/test/compile-fail/use-super-global-path.rs
Normal file
22
src/test/compile-fail/use-super-global-path.rs
Normal 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
|
Loading…
Reference in New Issue
Block a user