Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Apr 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
)
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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/\
Expand Down
20 changes: 18 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -130,13 +133,26 @@ 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)
.collect()
}
};

// 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()
Expand Down
10 changes: 5 additions & 5 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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))));
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions src/test/compile-fail/use-super-global-path.rs
Original file line number Diff line number Diff line change
@@ -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