diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index cab51fbd98775..798c289ac2f9f 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -44,9 +44,13 @@ extern crate syntax_pos; use rustc::lint; use rustc::lint::{LateContext, LateLintPass, LintPass, LintArray}; -use rustc::lint::builtin::{BARE_TRAIT_OBJECTS, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, - ELIDED_LIFETIMES_IN_PATHS}; -use rustc::lint::builtin::MACRO_USE_EXTERN_CRATE; +use rustc::lint::builtin::{ + BARE_TRAIT_OBJECTS, + ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, + MACRO_USE_EXTERN_CRATE, + ELIDED_LIFETIMES_IN_PATHS, + parser::QUESTION_MARK_MACRO_SEP +}; use rustc::session; use rustc::util; use rustc::hir; @@ -321,6 +325,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #50504 ", edition: None, }, + FutureIncompatibleInfo { + id: LintId::of(QUESTION_MARK_MACRO_SEP), + reference: "issue #48075 ", + edition: Some(Edition::Edition2018), + } ]); // Register renamed and removed lints diff --git a/src/libsyntax/early_buffered_lints.rs b/src/libsyntax/early_buffered_lints.rs index 204e07625adef..a976af1435d23 100644 --- a/src/libsyntax/early_buffered_lints.rs +++ b/src/libsyntax/early_buffered_lints.rs @@ -1,3 +1,13 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! Allows the buffering of lints for later. //! //! Since we cannot have a dependency on `librustc`, we implement some types here that are somewhat diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 8912be5f69d11..c9ec2c7d1e86a 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -247,6 +247,7 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: features, &def.attrs, edition, + def.id, ) .pop() .unwrap(); @@ -272,6 +273,7 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: features, &def.attrs, edition, + def.id, ).pop() .unwrap(); } diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index e209e077bf4db..357fc77a3a79d 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use ast::NodeId; +use early_buffered_lints::BufferedEarlyLintId; use ext::tt::macro_parser; use feature_gate::{self, emit_feature_err, Features, GateIssue}; use parse::{token, ParseSess}; @@ -175,6 +177,7 @@ impl TokenTree { /// - `features`, `attrs`: language feature flags and attributes so that we know whether to use /// unstable features or not. /// - `edition`: which edition are we in. +/// - `macro_node_id`: the NodeId of the macro we are parsing. /// /// # Returns /// @@ -186,6 +189,7 @@ pub fn parse( features: &Features, attrs: &[ast::Attribute], edition: Edition, + macro_node_id: NodeId, ) -> Vec { // Will contain the final collection of `self::TokenTree` let mut result = Vec::new(); @@ -204,6 +208,7 @@ pub fn parse( features, attrs, edition, + macro_node_id, ); match tree { TokenTree::MetaVar(start_sp, ident) if expect_matchers => { @@ -265,6 +270,7 @@ fn parse_tree( features: &Features, attrs: &[ast::Attribute], edition: Edition, + macro_node_id: NodeId, ) -> TokenTree where I: Iterator, @@ -290,10 +296,19 @@ where features, attrs, edition, + macro_node_id, ); // Get the Kleene operator and optional separator let (separator, op) = - parse_sep_and_kleene_op(trees, span, sess, features, attrs, edition); + parse_sep_and_kleene_op( + trees, + span, + sess, + features, + attrs, + edition, + macro_node_id, + ); // Count the number of captured "names" (i.e. named metavars) let name_captures = macro_parser::count_names(&sequence); TokenTree::Sequence( @@ -350,6 +365,7 @@ where features, attrs, edition, + macro_node_id, ), }), ), @@ -413,12 +429,20 @@ fn parse_sep_and_kleene_op( features: &Features, attrs: &[ast::Attribute], edition: Edition, + macro_node_id: NodeId, ) -> (Option, KleeneOp) where I: Iterator, { match edition { - Edition::Edition2015 => parse_sep_and_kleene_op_2015(input, span, sess, features, attrs), + Edition::Edition2015 => parse_sep_and_kleene_op_2015( + input, + span, + sess, + features, + attrs, + macro_node_id, + ), Edition::Edition2018 => parse_sep_and_kleene_op_2018(input, span, sess, features, attrs), _ => unimplemented!(), } @@ -431,6 +455,7 @@ fn parse_sep_and_kleene_op_2015( sess: &ParseSess, _features: &Features, _attrs: &[ast::Attribute], + macro_node_id: NodeId, ) -> (Option, KleeneOp) where I: Iterator, @@ -474,8 +499,10 @@ where // #2 is a Kleene op, which is the the only valid option Ok(Ok((op, _))) => { // Warn that `?` as a separator will be deprecated - sess.span_diagnostic.span_warn( + sess.buffer_lint( + BufferedEarlyLintId::QuestionMarkMacroSep, op1_span, + macro_node_id, "using `?` as a separator is deprecated and will be \ a hard error in an upcoming edition", );