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"
|
"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
|
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||||
/// which are used by other parts of the compiler.
|
/// which are used by other parts of the compiler.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -213,7 +219,8 @@ impl LintPass for HardwiredLints {
|
|||||||
RAW_POINTER_DERIVE,
|
RAW_POINTER_DERIVE,
|
||||||
TRANSMUTE_FROM_FN_ITEM_TYPES,
|
TRANSMUTE_FROM_FN_ITEM_TYPES,
|
||||||
OVERLAPPING_INHERENT_IMPLS,
|
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),
|
id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
|
||||||
reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
|
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 {
|
FutureIncompatibleInfo {
|
||||||
id: LintId::of(MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT),
|
id: LintId::of(MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT),
|
||||||
reference: "RFC 218 <https://github.com/rust-lang/rfcs/blob/\
|
reference: "RFC 218 <https://github.com/rust-lang/rfcs/blob/\
|
||||||
|
@ -24,13 +24,14 @@ use Resolver;
|
|||||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||||
|
|
||||||
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
|
use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
|
||||||
|
use rustc::lint;
|
||||||
use rustc::middle::def::*;
|
use rustc::middle::def::*;
|
||||||
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
|
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
|
||||||
use rustc::ty::VariantKind;
|
use rustc::ty::VariantKind;
|
||||||
|
|
||||||
use syntax::ast::{Name, NodeId};
|
use syntax::ast::{Name, NodeId};
|
||||||
use syntax::attr::AttrMetaMethods;
|
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 syntax::codemap::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use rustc_front::hir;
|
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
|
// Extract and intern the module part of the path. For
|
||||||
// globs and lists, the path is found directly in the AST;
|
// globs and lists, the path is found directly in the AST;
|
||||||
// for simple paths we have to munge the path a little.
|
// 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) => {
|
ViewPathSimple(_, ref full_path) => {
|
||||||
|
is_global = full_path.global;
|
||||||
full_path.segments
|
full_path.segments
|
||||||
.split_last()
|
.split_last()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -130,6 +133,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
|
|||||||
|
|
||||||
ViewPathGlob(ref module_ident_path) |
|
ViewPathGlob(ref module_ident_path) |
|
||||||
ViewPathList(ref module_ident_path, _) => {
|
ViewPathList(ref module_ident_path, _) => {
|
||||||
|
is_global = module_ident_path.global;
|
||||||
module_ident_path.segments
|
module_ident_path.segments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|seg| seg.identifier.name)
|
.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.
|
// Build up the import directives.
|
||||||
let is_prelude = item.attrs.iter().any(|attr| {
|
let is_prelude = item.attrs.iter().any(|attr| {
|
||||||
attr.name() == special_idents::prelude_import.name.as_str()
|
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.
|
// Allow a leading :: because the paths are absolute either way.
|
||||||
// This occurs with "use $crate::..." in macros.
|
// 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)) {
|
if self.check(&token::OpenDelim(token::Brace)) {
|
||||||
// use {foo,bar}
|
// use {foo,bar}
|
||||||
@ -6135,7 +6135,7 @@ impl<'a> Parser<'a> {
|
|||||||
|p| p.parse_path_list_item())?;
|
|p| p.parse_path_list_item())?;
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: is_global,
|
||||||
segments: Vec::new()
|
segments: Vec::new()
|
||||||
};
|
};
|
||||||
return Ok(P(spanned(lo, self.span.hi, ViewPathList(path, idents))));
|
return Ok(P(spanned(lo, self.span.hi, ViewPathList(path, idents))));
|
||||||
@ -6164,7 +6164,7 @@ impl<'a> Parser<'a> {
|
|||||||
)?;
|
)?;
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: is_global,
|
||||||
segments: path.into_iter().map(|identifier| {
|
segments: path.into_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
@ -6180,7 +6180,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.bump();
|
self.bump();
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.span.hi),
|
span: mk_sp(lo, self.span.hi),
|
||||||
global: false,
|
global: is_global,
|
||||||
segments: path.into_iter().map(|identifier| {
|
segments: path.into_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
identifier: identifier,
|
||||||
@ -6203,7 +6203,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut rename_to = path[path.len() - 1];
|
let mut rename_to = path[path.len() - 1];
|
||||||
let path = ast::Path {
|
let path = ast::Path {
|
||||||
span: mk_sp(lo, self.last_span.hi),
|
span: mk_sp(lo, self.last_span.hi),
|
||||||
global: false,
|
global: is_global,
|
||||||
segments: path.into_iter().map(|identifier| {
|
segments: path.into_iter().map(|identifier| {
|
||||||
ast::PathSegment {
|
ast::PathSegment {
|
||||||
identifier: identifier,
|
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
|
// 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);
|
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 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);
|
const SELF_TYPE_KEYWORD_NAME: ast::Name = ast::Name(SELF_TYPE_KEYWORD_NAME_NUM);
|
||||||
|
|
||||||
pub const SELF_KEYWORD_NAME_NUM: u32 = 1;
|
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