diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 27e781a5a6385..bda1040771924 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -766,9 +766,6 @@ pub fn visit_token(t: &mut Token, vis: &mut T) { *span = ident.span; return; // Avoid visiting the span for the second time. } - token::NtIdent(ident, _is_raw) => { - vis.visit_ident(ident); - } token::NtLifetime(ident) => { vis.visit_ident(ident); } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index efe1956615216..8b2326ce44ac1 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -317,14 +317,7 @@ pub enum TokenKind { Literal(Lit), /// Identifier token. - /// Do not forget about `NtIdent` when you want to match on identifiers. - /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to - /// treat regular and interpolated identifiers in the same way. Ident(Symbol, IdentIsRaw), - /// This identifier (and its span) is the identifier passed to the - /// declarative macro. The span in the surrounding `Token` is the span of - /// the `ident` metavariable in the macro's RHS. - NtIdent(Ident, IdentIsRaw), /// Lifetime identifier token. /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers. @@ -457,7 +450,7 @@ impl Token { /// if they keep spans or perform edition checks. pub fn uninterpolated_span(&self) -> Span { match self.kind { - NtIdent(ident, _) | NtLifetime(ident) => ident.span, + NtLifetime(ident) => ident.span, Interpolated(ref nt) => nt.use_span(), _ => self.span, } @@ -476,7 +469,7 @@ impl Token { } OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) - | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false, + | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false, } } @@ -644,7 +637,6 @@ impl Token { /// otherwise returns the original token. pub fn uninterpolate(&self) -> Cow<'_, Token> { match self.kind { - NtIdent(ident, is_raw) => Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span)), NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)), _ => Cow::Borrowed(self), } @@ -656,7 +648,6 @@ impl Token { // We avoid using `Token::uninterpolate` here because it's slow. match self.kind { Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), - NtIdent(ident, is_raw) => Some((ident, is_raw)), _ => None, } } @@ -856,7 +847,7 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar - | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..) + | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof => { return None; } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index b4ddbe20689e2..15ad937e86565 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -484,9 +484,6 @@ impl TokenStream { fn flatten_token(token: &Token, spacing: Spacing) -> TokenTree { match token.kind { - token::NtIdent(ident, is_raw) => { - TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing) - } token::NtLifetime(ident) => TokenTree::Delimited( DelimSpan::from_single(token.span), DelimSpacing::new(Spacing::JointHidden, spacing), @@ -516,10 +513,9 @@ impl TokenStream { pub fn flattened(&self) -> TokenStream { fn can_skip(stream: &TokenStream) -> bool { stream.trees().all(|tree| match tree { - TokenTree::Token(token, _) => !matches!( - token.kind, - token::NtIdent(..) | token::NtLifetime(..) | token::Interpolated(..) - ), + TokenTree::Token(token, _) => { + !matches!(token.kind, token::NtLifetime(..) | token::Interpolated(..)) + } TokenTree::Delimited(.., inner) => can_skip(inner), }) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0225c95dca8e3..a6f718bac619d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -943,9 +943,6 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Ident(name, is_raw) => { IdentPrinter::new(name, is_raw.into(), convert_dollar_crate).to_string().into() } - token::NtIdent(ident, is_raw) => { - IdentPrinter::for_ast_ident(ident, is_raw.into()).to_string().into() - } token::Lifetime(name) => name.to_string().into(), token::NtLifetime(ident) => ident.name.to_string().into(), diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 93fac3181ba4b..487a82f802465 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -743,9 +743,11 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { // or // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); - if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) - && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() + let hir_id = def_id + .as_local() + .and_then(|def_id| self.infcx.tcx.hir().maybe_body_owned_by(def_id)) + .and_then(|body| (BindingFinder { span: pat_span }).visit_body(&body).break_value()); + if let Some(hir_id) = hir_id && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, @@ -767,8 +769,11 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return; } + let span = local_decl.source_info.span; + let span = + hir_id.map_or(span, |hir_id| span.with_neighbor(self.infcx.tcx.hir().span(hir_id))); err.span_suggestion_verbose( - local_decl.source_info.span.shrink_to_lo(), + span.shrink_to_lo(), "consider changing this to be mutable", "mut ", Applicability::MachineApplicable, diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 56cbb54fcecf7..df630a3d76cfc 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -203,13 +203,7 @@ impl<'a> StripUnconfigured<'a> { Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)).into_iter() } AttrTokenTree::Token( - Token { - kind: - TokenKind::NtIdent(..) - | TokenKind::NtLifetime(..) - | TokenKind::Interpolated(..), - .. - }, + Token { kind: TokenKind::NtLifetime(..) | TokenKind::Interpolated(..), .. }, _, ) => { panic!("Nonterminal should have been flattened: {:?}", tree); diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index f935f1b77e0b2..18dbcfcd7e0fb 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -274,11 +274,6 @@ pub(super) fn transcribe<'a>( // without wrapping them into groups. maybe_use_metavar_location(psess, &stack, sp, tt, &mut marker) } - MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => { - marker.visit_span(&mut sp); - let kind = token::NtIdent(*ident, *is_raw); - TokenTree::token_alone(kind, sp) - } MatchedSingle(ParseNtResult::Lifetime(ident)) => { marker.visit_span(&mut sp); let kind = token::NtLifetime(*ident); @@ -395,9 +390,22 @@ fn maybe_use_metavar_location( return orig_tt.clone(); } - let insert = |mspans: &mut FxHashMap<_, _>, s, ms| match mspans.try_insert(s, ms) { + let insert = |mspans: &mut FxHashMap<_, _>, s, ms: Span| match mspans.try_insert(s, ms) { Ok(_) => true, - Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success + Err(mut err) => { + let old_ms = *err.entry.get(); + if ms == old_ms { + // Tried to insert the same span, still success. + return true; + } + if !ms.eq_ctxt(old_ms) && ms.ctxt().outer_expn_data().call_site.eq_ctxt(old_ms) { + // This looks like a variable passed to an inner (possibly recursive) macro call. + // The innermost metavar span is the most useful, so override. + err.entry.insert(ms); + return true; + } + false + } }; marker.visit_span(&mut metavar_span); let no_collision = match orig_tt { @@ -411,16 +419,23 @@ fn maybe_use_metavar_location( }), }; if no_collision || psess.source_map().is_imported(metavar_span) { + // Add a whitespace for backward compatibility. + // FIXME: assign spacing to tokens from metavars in a more systematic way (#127123). + if let TokenTree::Token(token, _) = orig_tt { + return TokenTree::Token(token.clone(), Spacing::Alone); + } return orig_tt.clone(); } // Setting metavar spans for the heuristic spans gives better opportunities for combining them // with neighboring spans even despite their different syntactic contexts. match orig_tt { - TokenTree::Token(Token { kind, span }, spacing) => { + TokenTree::Token(Token { kind, span }, _spacing) => { let span = metavar_span.with_ctxt(span.ctxt()); with_metavar_spans(|mspans| insert(mspans, span, metavar_span)); - TokenTree::Token(Token { kind: kind.clone(), span }, *spacing) + // Add a whitespace for backward compatibility. + // FIXME: assign spacing to tokens from metavars in a more systematic way (#127123). + TokenTree::Token(Token { kind: kind.clone(), span }, Spacing::Alone) } TokenTree::Delimited(dspan, dspacing, delimiter, tts) => { let open = metavar_span.with_ctxt(dspan.open.ctxt()); @@ -735,12 +750,6 @@ fn extract_ident<'a>( interp: &FxHashMap, ) -> PResult<'a, String> { if let NamedMatch::MatchedSingle(pnr) = matched_from_ident(dcx, ident, interp)? { - if let ParseNtResult::Ident(nt_ident, is_raw) = pnr { - if let IdentIsRaw::Yes = is_raw { - return Err(dcx.struct_span_err(ident.span, RAW_IDENT_ERR)); - } - return Ok(nt_ident.to_string()); - } if let ParseNtResult::Tt(TokenTree::Token( Token { kind: TokenKind::Ident(token_ident, is_raw), .. }, _, diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5508358f53bb2..70209a3763972 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -221,11 +221,6 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { trees.push(TokenTree::Ident(Ident { sym, is_raw: is_raw.into(), span })) } - NtIdent(ident, is_raw) => trees.push(TokenTree::Ident(Ident { - sym: ident.name, - is_raw: is_raw.into(), - span: ident.span, - })), Lifetime(name) => { let ident = symbol::Ident::new(name, span).without_first_quote(); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 240a749de96a6..9ca7a8bed7cf8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -56,7 +56,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )); } - if self_ty.span.edition().at_least_rust_2021() { + if tcx.hir().span_in_context(self_ty.hir_id).edition().at_least_rust_2021() { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a385bc70e359b..7cee8221be745 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2454,7 +2454,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Path(QPath::Resolved(_, path)) => { // local binding if let hir::def::Res::Local(hir_id) = path.res { - let span = tcx.hir().span(hir_id); + let span = tcx.hir().span_in_context(hir_id); let filename = tcx.sess.source_map().span_to_filename(span); let parent_node = self.tcx.parent_hir_node(hir_id); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f3a904022e9ed..573236fbce570 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -718,8 +718,9 @@ fn lint_wide_pointer<'tcx>( return; }; + let (l_span, r_span) = (l.span.with_neighbor(e.span), r.span.with_neighbor(e.span)); let (Some(l_span), Some(r_span)) = - (l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span)) + (l_span.find_ancestor_inside(e.span), r_span.find_ancestor_inside(e.span)) else { return cx.emit_span_lint( AMBIGUOUS_WIDE_POINTER_COMPARISONS, diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 305ba1ef3bbc8..98b995f25a74a 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -935,6 +935,16 @@ impl<'hir> Map<'hir> { } } + /// Use regular `span` method when *showing* any diagnostics. + /// Use this method when suggesting *inserting* any code to the left or right from this node. + /// + /// If some piece of code is passed to a macro as an argument, then this method may move the + /// span from the argument into the macro body where that argument is emitted into the output. + pub fn span_in_context(self, hir_id: HirId) -> Span { + let parent_span = self.span(self.tcx.parent_hir_id(hir_id)); + self.span(hir_id).with_neighbor(parent_span) + } + /// Get a representation of this `id` for debugging purposes. /// NOTE: Do NOT use this in diagnostics! pub fn node_to_string(self, id: HirId) -> String { diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index b5480b6b7d210..e9143970ea41d 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -230,8 +230,7 @@ impl<'a> Parser<'a> { let (mut ret, trailing) = ret?; // When we're not in `capture-cfg` mode, then bail out early if: - // 1. Our target doesn't support tokens at all (e.g we're parsing an `NtIdent`) - // so there's nothing for us to do. + // 1. Our target doesn't support tokens at all, so there's nothing for us to do. // 2. Our target already has tokens set (e.g. we've parsed something // like `#[my_attr] $item`. The actual parsing code takes care of prepending // any attributes to the nonterminal, so we don't need to modify the diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b2df9a14eb01e..91d92a6bbd4db 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -249,10 +249,11 @@ impl<'a> Parser<'a> { continue; } + let op_span = op.span; let op = op.node; // Special cases: if op == AssocOp::As { - lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; + lhs = self.parse_assoc_op_cast(lhs, lhs_span, op_span, ExprKind::Cast)?; continue; } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to @@ -274,7 +275,7 @@ impl<'a> Parser<'a> { this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::Unparsed { attrs }) })?; - let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); + let span = self.mk_expr_sp(&lhs, lhs_span, op_span, rhs.span); lhs = match op { AssocOp::Add | AssocOp::Subtract @@ -453,7 +454,7 @@ impl<'a> Parser<'a> { None }; let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span); - let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span); + let span = self.mk_expr_sp(&lhs, lhs.span, cur_op_span, rhs_span); let limits = if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let range = self.mk_range(Some(lhs), rhs, limits); @@ -663,9 +664,7 @@ impl<'a> Parser<'a> { /// Returns the span of expr if it was not interpolated, or the span of the interpolated token. fn interpolated_or_expr_span(&self, expr: &Expr) -> Span { match self.prev_token.kind { - TokenKind::NtIdent(..) | TokenKind::NtLifetime(..) | TokenKind::Interpolated(..) => { - self.prev_token.span - } + TokenKind::NtLifetime(..) | TokenKind::Interpolated(..) => self.prev_token.span, _ => expr.span, } } @@ -674,10 +673,11 @@ impl<'a> Parser<'a> { &mut self, lhs: P, lhs_span: Span, + op_span: Span, expr_kind: fn(P, P) -> ExprKind, ) -> PResult<'a, P> { let mk_expr = |this: &mut Self, lhs: P, rhs: P| { - this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs)) + this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, op_span, rhs.span), expr_kind(lhs, rhs)) }; // Save the state of the parser before parsing type normally, in case there is a @@ -3852,11 +3852,13 @@ impl<'a> Parser<'a> { /// Create expression span ensuring the span of the parent node /// is larger than the span of lhs and rhs, including the attributes. - fn mk_expr_sp(&self, lhs: &P, lhs_span: Span, rhs_span: Span) -> Span { + fn mk_expr_sp(&self, lhs: &P, lhs_span: Span, op_span: Span, rhs_span: Span) -> Span { lhs.attrs .iter() .find(|a| a.style == AttrStyle::Outer) .map_or(lhs_span, |a| a.span) + // An approximation to #126763. + .to(op_span) .to(rhs_span) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index cfd0a72c056d5..be77cd84401fa 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -394,7 +394,6 @@ pub(super) fn token_descr(token: &Token) -> String { (Some(TokenDescription::Keyword), _) => Some("keyword"), (Some(TokenDescription::ReservedKeyword), _) => Some("reserved keyword"), (Some(TokenDescription::DocComment), _) => Some("doc comment"), - (None, TokenKind::NtIdent(..)) => Some("identifier"), (None, TokenKind::NtLifetime(..)) => Some("lifetime"), (None, TokenKind::Interpolated(node)) => Some(node.descr()), (None, _) => None, @@ -687,9 +686,9 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(0, &[kw::Const]) && self.look_ahead(1, |t| match &t.kind { // async closures do not work with const closures, so we do not parse that here. - token::Ident(kw::Move | kw::Static, _) | token::OrOr | token::BinOp(token::Or) => { - true - } + token::Ident(kw::Move | kw::Static, IdentIsRaw::No) + | token::OrOr + | token::BinOp(token::Or) => true, _ => false, }) } @@ -1623,7 +1622,6 @@ enum FlatToken { #[derive(Clone, Debug)] pub enum ParseNtResult { Tt(TokenTree), - Ident(Ident, IdentIsRaw), Lifetime(Ident), /// This case will eventually be removed, along with `Token::Interpolate`. diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 4a78b427832c5..d9aa5f368f93a 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -6,7 +6,7 @@ use rustc_ast::HasTokens; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::PResult; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::kw; use crate::errors::UnexpectedNonterminal; use crate::parser::pat::{CommaRecoveryMode, RecoverColon, RecoverComma}; @@ -51,13 +51,12 @@ impl<'a> Parser<'a> { && !token.is_keyword(kw::Let) } NonterminalKind::Ty => token.can_begin_type(), - NonterminalKind::Ident => get_macro_ident(token).is_some(), + NonterminalKind::Ident => is_macro_ident(token), NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), NonterminalKind::Vis => match token.kind { // The follow-set of :vis + "priv" keyword + interpolated token::Comma | token::Ident(..) - | token::NtIdent(..) | token::NtLifetime(..) | token::Interpolated(_) => true, _ => token.can_begin_type(), @@ -72,13 +71,13 @@ impl<'a> Parser<'a> { _ => false, }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { - token::PathSep | token::Ident(..) | token::NtIdent(..) => true, + token::PathSep | token::Ident(..) => true, token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::Pat(pat_kind) => match &token.kind { // box, ref, mut, and other identifiers (can stricten) - token::Ident(..) | token::NtIdent(..) | + token::Ident(..) | token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern token::OpenDelim(Delimiter::Bracket) | // slice pattern token::BinOp(token::And) | // reference @@ -114,8 +113,17 @@ impl<'a> Parser<'a> { // in advance whether or not a proc-macro will be (transitively) invoked, // we always capture tokens for any `Nonterminal` which needs them. let mut nt = match kind { - // Note that TT is treated differently to all the others. + // Note that `tt` and `ident` are treated differently to all the others. NonterminalKind::TT => return Ok(ParseNtResult::Tt(self.parse_token_tree())), + NonterminalKind::Ident if is_macro_ident(&self.token) => { + return Ok(ParseNtResult::Tt(self.parse_token_tree())); + } + NonterminalKind::Ident => { + return Err(self.dcx().create_err(UnexpectedNonterminal::Ident { + span: self.token.span, + token: self.token.clone(), + })); + } NonterminalKind::Item => match self.parse_item(ForceCollect::Yes)? { Some(item) => NtItem(item), None => { @@ -156,18 +164,6 @@ impl<'a> Parser<'a> { NonterminalKind::Ty => { NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?) } - // this could be handled like a token, since it is one - NonterminalKind::Ident => { - return if let Some((ident, is_raw)) = get_macro_ident(&self.token) { - self.bump(); - Ok(ParseNtResult::Ident(ident, is_raw)) - } else { - Err(self.dcx().create_err(UnexpectedNonterminal::Ident { - span: self.token.span, - token: self.token.clone(), - })) - }; - } NonterminalKind::Path => { NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) } @@ -204,6 +200,6 @@ impl<'a> Parser<'a> { /// The token is an identifier, but not `_`. /// We prohibit passing `_` to macros expecting `ident` for now. -fn get_macro_ident(token: &Token) -> Option<(Ident, token::IdentIsRaw)> { - token.ident().filter(|(ident, _)| ident.name != kw::Underscore) +fn is_macro_ident(token: &Token) -> bool { + token.ident().map_or(false, |(ident, _)| ident.name != kw::Underscore) } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index da8d1194325b4..0e1a83dc50e1c 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -211,7 +211,8 @@ impl<'a> Parser<'a> { if self.eat(&token::PathSep) { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } - self.parse_path_segments(&mut segments, style, ty_generics)?; + let sep_span = self.parse_path_segments(&mut segments, style, ty_generics)?; + let lo = sep_span.map_or(lo, |sep_span| lo.with_neighbor(sep_span)); Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None }) } @@ -220,7 +221,9 @@ impl<'a> Parser<'a> { segments: &mut ThinVec, style: PathStyle, ty_generics: Option<&Generics>, - ) -> PResult<'a, ()> { + ) -> PResult<'a, Option> { + // An approximation to #126763. + let mut sep_span = None; loop { let segment = self.parse_path_segment(style, ty_generics)?; if style.has_generic_ambiguity() { @@ -268,7 +271,9 @@ impl<'a> Parser<'a> { continue; } - return Ok(()); + return Ok(sep_span); + } else { + sep_span = Some(self.prev_token.span); } } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 3d5e6371f4ce6..5402d6a714150 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -37,8 +37,9 @@ pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) { // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the // `unsafe(`, `)` right after and right before the opening and closing // square bracket respectively. - let diag_span = if attr_item.span().can_be_used_for_suggestions() { - attr_item.span() + let diag_span = attr_item.span(); + let diag_span = if diag_span.can_be_used_for_suggestions() { + diag_span.with_neighbor(attr.span) } else { attr.span .with_lo(attr.span.lo() + BytePos(2)) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 266956d63d710..7968f27c13970 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -876,6 +876,9 @@ impl Span { /// Check if you can select metavar spans for the given spans to get matching contexts. fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) { + // `macro_rules` expansion fills the metavar span table with parentless spans as keys, + // but they may get parents later and we need to remove them before the table lookup. + let (a_orig, b_orig) = (a_orig.with_parent(None), b_orig.with_parent(None)); let get = |mspans: &FxHashMap<_, _>, s| mspans.get(&s).copied(); match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) { (None, None) => {} @@ -938,7 +941,7 @@ impl Span { pub fn with_neighbor(self, neighbor: Span) -> Span { match Span::prepare_to_combine(self, neighbor) { Ok((this, ..)) => this.span(), - Err(_) => self, + Err(fallback) => self.with_ctxt(fallback.ctxt()), } } diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs index fb0b0cba6a662..f4510466a8611 100644 --- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs @@ -144,7 +144,7 @@ pub(super) fn check<'tcx>( if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) { if let Some(id) = path_to_local(cast_expr) - && !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span) + && !cx.tcx.hir().span_in_context(id).eq_ctxt(cast_expr.span) { // Binding context is different than the identifiers context. // Weird macro wizardry could be involved here. diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 4bfc30fa5cf80..c847379445e7b 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -108,7 +108,7 @@ struct LocalAssign { impl LocalAssign { fn from_expr(expr: &Expr<'_>, span: Span) -> Option { if let ExprKind::Assign(lhs, rhs, _) = expr.kind { - if lhs.span.from_expansion() { + if lhs.span.with_neighbor(expr.span).from_expansion() { return None; } diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 80f5fd0b49441..58490fa609a27 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -114,7 +114,8 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { return; }; - if pat.span.desugaring_kind().is_some() || pat.span.from_expansion() { + let pat_span = cx.tcx.hir().span_in_context(pat.hir_id); + if pat_span.desugaring_kind().is_some() || pat_span.from_expansion() { return; } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 6319c7bfa6b81..672eeca3563c0 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -53,7 +53,7 @@ impl<'a> Sugg<'a> { /// Prepare a suggestion from an expression. pub fn hir_opt(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option { let get_snippet = |span| snippet(cx, span, ""); - snippet_opt(cx, expr.span).map(|_| Self::hir_from_snippet(expr, get_snippet)) + snippet_opt(cx, expr.span).map(|_| Self::hir_from_snippet(cx, expr, get_snippet)) } /// Convenience function around `hir_opt` for suggestions with a default @@ -100,7 +100,7 @@ impl<'a> Sugg<'a> { applicability: &mut Applicability, ) -> Self { if expr.span.ctxt() == ctxt { - Self::hir_from_snippet(expr, |span| snippet(cx, span, default)) + Self::hir_from_snippet(cx, expr, |span| snippet(cx, span, default)) } else { let (snip, _) = snippet_with_context(cx, expr.span, ctxt, default, applicability); Sugg::NonParen(snip) @@ -109,7 +109,11 @@ impl<'a> Sugg<'a> { /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*` /// function variants of `Sugg`, since these use different snippet functions. - fn hir_from_snippet(expr: &hir::Expr<'_>, get_snippet: impl Fn(Span) -> Cow<'a, str>) -> Self { + fn hir_from_snippet( + cx: &LateContext<'_>, + expr: &hir::Expr<'_>, + get_snippet: impl Fn(Span) -> Cow<'a, str>, + ) -> Self { if let Some(range) = higher::Range::hir(expr) { let op = match range.limits { ast::RangeLimits::HalfOpen => AssocOp::DotDot, @@ -148,8 +152,8 @@ impl<'a> Sugg<'a> { | ExprKind::Become(..) | ExprKind::Struct(..) | ExprKind::Tup(..) - | ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)), - ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet), + | ExprKind::Err(_) => Sugg::NonParen(get_snippet(cx.tcx.hir().span_in_context(expr.hir_id))), + ExprKind::DropTemps(inner) => Self::hir_from_snippet(cx, inner, get_snippet), ExprKind::Assign(lhs, rhs, _) => { Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) }, diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr index 55a410982adfd..3a863efb71995 100644 --- a/src/tools/clippy/tests/ui/manual_let_else.stderr +++ b/src/tools/clippy/tests/ui/manual_let_else.stderr @@ -367,7 +367,7 @@ error: this could be rewritten as `let...else` --> tests/ui/manual_let_else.rs:214:13 | LL | let $n = if let Some(v) = $e { v } else { return }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(w) = g() else { return };` ... LL | create_binding_if_some!(w, g()); | ------------------------------- in this macro invocation diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed index 72fc4cb7333ec..c9f4f67ccbbbf 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.fixed +++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed @@ -71,7 +71,7 @@ fn main() { let _ = S { v }; let _ = S { $i: v }; let _ = S { v: $i }; - let _ = S { $i: $i }; + let _ = S { v }; }; } internal!(v); diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr index 38c021fdba370..e2ed3d7641660 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.stderr +++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr @@ -54,11 +54,17 @@ LL | internal!(v); | = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info) +error: redundant field names in struct initialization + --> tests/ui/redundant_field_names.rs:74:25 + | +LL | let _ = S { $i: $i }; + | ^^^^^^ help: replace it with: `v` + error: redundant field names in struct initialization --> tests/ui/redundant_field_names.rs:99:25 | LL | let _ = RangeFrom { start: start }; | ^^^^^^^^^^^^ help: replace it with: `start` -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr index fdd149a2216f2..cd5b85858d8a8 100644 --- a/src/tools/clippy/tests/ui/shadow.stderr +++ b/src/tools/clippy/tests/ui/shadow.stderr @@ -256,18 +256,6 @@ note: previous binding is here LL | let y = Some(1); | ^ -error: `_b` shadows a previous, unrelated binding - --> tests/ui/shadow.rs:112:9 - | -LL | let _b = _a; - | ^^ - | -note: previous binding is here - --> tests/ui/shadow.rs:111:28 - | -LL | pub async fn foo2(_a: i32, _b: i64) { - | ^^ - error: `x` shadows a previous, unrelated binding --> tests/ui/shadow.rs:118:21 | @@ -280,5 +268,5 @@ note: previous binding is here LL | let x = 1; | ^ -error: aborting due to 23 previous errors +error: aborting due to 22 previous errors diff --git a/tests/ui/borrowck/move-error-snippets.stderr b/tests/ui/borrowck/move-error-snippets.stderr index 97d140515184a..d16bf08458cb6 100644 --- a/tests/ui/borrowck/move-error-snippets.stderr +++ b/tests/ui/borrowck/move-error-snippets.stderr @@ -1,11 +1,9 @@ error[E0507]: cannot move out of static item `D` - --> $DIR/move-error-snippets-ext.rs:5:17 - | -LL | let a = $c; - | ^^ move occurs because `D` has type `A`, which does not implement the `Copy` trait - | - ::: $DIR/move-error-snippets.rs:21:1 + --> $DIR/move-error-snippets.rs:16:18 | +LL | aaa!(D); + | ^ move occurs because `D` has type `A`, which does not implement the `Copy` trait +... LL | sss!(); | ------ in this macro invocation | @@ -14,16 +12,14 @@ note: if `A` implemented `Clone`, you could clone the value | LL | struct A; | ^^^^^^^^ consider implementing `Clone` for this type - | - ::: $DIR/move-error-snippets-ext.rs:5:17 - | -LL | let a = $c; - | -- you could clone this value - = note: this error originates in the macro `aaa` which comes from the expansion of the macro `sss` (in Nightly builds, run with -Z macro-backtrace for more info) +... +LL | aaa!(D); + | - you could clone this value + = note: this error originates in the macro `sss` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider borrowing here | -LL | let a = &$c; - | + +LL | aaa!(&D); + | + error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr index 1de27a072cf73..25b7a93ffe3f3 100644 --- a/tests/ui/consts/const-float-classify.stderr +++ b/tests/ui/consts/const-float-classify.stderr @@ -29,7 +29,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -53,7 +53,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -77,7 +77,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -101,7 +101,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -125,7 +125,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -149,7 +149,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -173,7 +173,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] @@ -197,7 +197,7 @@ error[E0284]: type annotations needed --> $DIR/const-float-classify.rs:21:35 | LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` + | ^^^^^ cannot infer the value of the constant `_` ... LL | / suite! { LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] diff --git a/tests/ui/deriving/multiple-defaults.stderr b/tests/ui/deriving/multiple-defaults.stderr index 05fb6fecffaec..2fd1b209a8b25 100644 --- a/tests/ui/deriving/multiple-defaults.stderr +++ b/tests/ui/deriving/multiple-defaults.stderr @@ -45,14 +45,12 @@ error: multiple declared defaults LL | #[derive(Default)] | ^^^^^^^ ... -LL | $id, - | --- - | | - | first default - | additional default -... LL | m! { A B } - | ---------- in this macro invocation + | ---------- + | | | | + | | | additional default + | | first default + | in this macro invocation | = note: only one variant can be default = note: this error originates in the derive macro `Default` which comes from the expansion of the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs index 5918454327409..0a0fae1de0d9f 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -21,7 +21,7 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved + if passes_ident!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if passes_ident!(r#async) == 1 {} // OK if passes_tt!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if passes_tt!(r#async) == 1 {} // OK diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr index 42db75f665973..9fd259d459859 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -45,15 +45,10 @@ LL | (r#async) => (1) | ^^^^^^^ error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/auxiliary/edition-kw-macro-2015.rs:27:23 + --> $DIR/edition-keywords-2018-2015-parsing.rs:24:27 | -LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` - | - ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8 - | -LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved - | -------------------- in this macro invocation +LL | if passes_ident!(async) == 1 {} + | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` --> $DIR/edition-keywords-2018-2015-parsing.rs:26:24 diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs index 4975246fa9423..e2aef5c87f172 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -13,7 +13,7 @@ mod module { } macro_rules! local_passes_ident { - ($i: ident) => ($i) //~ ERROR macro expansion ends with an incomplete expression + ($i: ident) => ($i) } macro_rules! local_passes_tt { ($i: tt) => ($i) @@ -28,11 +28,11 @@ pub fn check_async() { r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` r#async = consumes_async_raw!(r#async); // OK - if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved + if passes_ident!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if passes_ident!(r#async) == 1 {} // OK if passes_tt!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if passes_tt!(r#async) == 1 {} // OK - if local_passes_ident!(async) == 1 {} // Error reported above in the macro + if local_passes_ident!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if local_passes_ident!(r#async) == 1 {} // OK if local_passes_tt!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression if local_passes_tt!(r#async) == 1 {} // OK diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr index 4bbe1597233cf..0b196ec72cc41 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -45,15 +45,10 @@ LL | (r#async) => (1) | ^^^^^^^ error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/auxiliary/edition-kw-macro-2018.rs:27:23 + --> $DIR/edition-keywords-2018-2018-parsing.rs:31:27 | -LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` - | - ::: $DIR/edition-keywords-2018-2018-parsing.rs:31:8 - | -LL | if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved - | -------------------- in this macro invocation +LL | if passes_ident!(async) == 1 {} + | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` --> $DIR/edition-keywords-2018-2018-parsing.rs:33:24 @@ -62,10 +57,10 @@ LL | if passes_tt!(async) == 1 {} | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` - --> $DIR/edition-keywords-2018-2018-parsing.rs:16:23 + --> $DIR/edition-keywords-2018-2018-parsing.rs:35:33 | -LL | ($i: ident) => ($i) - | ^ expected one of `move`, `|`, or `||` +LL | if local_passes_ident!(async) == 1 {} + | ^ expected one of `move`, `|`, or `||` error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||` --> $DIR/edition-keywords-2018-2018-parsing.rs:37:30 diff --git a/tests/ui/hygiene/generate-mod.rs b/tests/ui/hygiene/generate-mod.rs index 8826293542c97..9238c07ac2a27 100644 --- a/tests/ui/hygiene/generate-mod.rs +++ b/tests/ui/hygiene/generate-mod.rs @@ -7,7 +7,9 @@ macro genmod($FromOutside: ident, $Outer: ident) { struct $Outer; mod inner { type A = $FromOutside; // `FromOutside` shouldn't be available from here + //~^ ERROR cannot find type `FromOutside` in this scope type Inner = $Outer; // `Outer` shouldn't be available from here + //~^ ERROR cannot find type `Outer` in this scope } } @@ -32,8 +34,7 @@ macro_rules! genmod_legacy { () => { fn check() { struct FromOutside; - genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `Outer` in this scope + genmod!(FromOutside, Outer); } fn check_transparent() { diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr index 32a2e145ca942..1b420724c1d2e 100644 --- a/tests/ui/hygiene/generate-mod.stderr +++ b/tests/ui/hygiene/generate-mod.stderr @@ -1,17 +1,17 @@ error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:35:13 + --> $DIR/generate-mod.rs:9:18 | -LL | genmod!(FromOutside, Outer); - | ^^^^^^^^^^^ not found in this scope +LL | type A = $FromOutside; // `FromOutside` shouldn't be available from here + | ^^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `Outer` in this scope - --> $DIR/generate-mod.rs:35:26 + --> $DIR/generate-mod.rs:11:22 | -LL | genmod!(FromOutside, Outer); - | ^^^^^ not found in this scope +LL | type Inner = $Outer; // `Outer` shouldn't be available from here + | ^^^^^^ not found in this scope error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:19:18 + --> $DIR/generate-mod.rs:21:18 | LL | type A = FromOutside; | ^^^^^^^^^^^ not found in this scope @@ -22,7 +22,7 @@ LL | genmod_transparent!(); = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope - --> $DIR/generate-mod.rs:20:22 + --> $DIR/generate-mod.rs:22:22 | LL | type Inner = Outer; | ^^^^^ not found in this scope @@ -33,7 +33,7 @@ LL | genmod_transparent!(); = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:28:18 + --> $DIR/generate-mod.rs:30:18 | LL | type A = FromOutside; | ^^^^^^^^^^^ not found in this scope @@ -44,7 +44,7 @@ LL | genmod_legacy!(); = note: this error originates in the macro `genmod_legacy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope - --> $DIR/generate-mod.rs:29:22 + --> $DIR/generate-mod.rs:31:22 | LL | type Inner = Outer; | ^^^^^ not found in this scope diff --git a/tests/ui/issues/issue-39848.rs b/tests/ui/issues/issue-39848.rs index 2a059120e8175..ec054de95bf21 100644 --- a/tests/ui/issues/issue-39848.rs +++ b/tests/ui/issues/issue-39848.rs @@ -1,9 +1,9 @@ macro_rules! get_opt { ($tgt:expr, $field:ident) => { - if $tgt.has_$field() {} //~ ERROR expected `{`, found identifier `foo` + if $tgt.has_$field() {} } } fn main() { - get_opt!(bar, foo); + get_opt!(bar, foo); //~ ERROR expected `{`, found `foo` } diff --git a/tests/ui/issues/issue-39848.stderr b/tests/ui/issues/issue-39848.stderr index a6c6c61f17095..04577e3500598 100644 --- a/tests/ui/issues/issue-39848.stderr +++ b/tests/ui/issues/issue-39848.stderr @@ -1,11 +1,8 @@ -error: expected `{`, found identifier `foo` - --> $DIR/issue-39848.rs:3:21 +error: expected `{`, found `foo` + --> $DIR/issue-39848.rs:8:19 | -LL | if $tgt.has_$field() {} - | ^^^^^^ expected `{` -... LL | get_opt!(bar, foo); - | ------------------ in this macro invocation + | ^^^ expected `{` | note: the `if` expression is missing a block after this condition --> $DIR/issue-39848.rs:3:12 diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index 4dd41519455c6..1b79f6fa6e45c 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -2,9 +2,9 @@ warning: non-local `impl` definition, `impl` blocks should be written at the sam --> $DIR/cargo-update.rs:19:1 | LL | non_local_macro::non_local_impl!(LocalStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | `LocalStruct` is not local + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^ + | | | + | | `LocalStruct` is not local | `Debug` is not local | move the `impl` block outside of this constant `_IMPL_DEBUG` | diff --git a/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr b/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr index 84efaa4f3687b..f6df1d59fbe27 100644 --- a/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr +++ b/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr @@ -2,22 +2,13 @@ error: unused variable: `var` --> $DIR/issue-117284-arg-in-macro.rs:15:18 | LL | make_var!(s, var); - | ^^^ + | ^^^ help: if this is intentional, prefix it with an underscore: `_var` | -help: `var` is captured in macro and introduced a unused variable - --> $DIR/issue-117284-arg-in-macro.rs:4:13 - | -LL | let $var = $struct.$var; - | ^^^^ -... -LL | make_var!(s, var); - | ----------------- in this macro invocation note: the lint level is defined here --> $DIR/issue-117284-arg-in-macro.rs:1:9 | LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `make_var` (in Nightly builds, run with -Z macro-backtrace for more info) error: unused variable: `a` --> $DIR/issue-117284-arg-in-macro.rs:16:9 diff --git a/tests/ui/lint/wide_pointer_comparisons.rs b/tests/ui/lint/wide_pointer_comparisons.rs index 05097cbf1e3de..a5e3f4754b8f5 100644 --- a/tests/ui/lint/wide_pointer_comparisons.rs +++ b/tests/ui/lint/wide_pointer_comparisons.rs @@ -146,12 +146,10 @@ fn main() { { macro_rules! cmp { ($a:tt, $b:tt) => { $a == $b } + //~^ WARN ambiguous wide pointer comparison } - // FIXME: This lint uses some custom span combination logic. - // Rewrite it to adapt to the new metavariable span rules. cmp!(a, b); - //~^ WARN ambiguous wide pointer comparison } { diff --git a/tests/ui/lint/wide_pointer_comparisons.stderr b/tests/ui/lint/wide_pointer_comparisons.stderr index 81a221c0ee640..3a743623fb17d 100644 --- a/tests/ui/lint/wide_pointer_comparisons.stderr +++ b/tests/ui/lint/wide_pointer_comparisons.stderr @@ -586,18 +586,22 @@ LL | std::ptr::eq(*a, *b) | ~~~~~~~~~~~~~ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:153:14 + --> $DIR/wide_pointer_comparisons.rs:148:33 | +LL | ($a:tt, $b:tt) => { $a == $b } + | ^^^^^^^^ +... LL | cmp!(a, b); - | ^^^^ + | ---------- in this macro invocation | + = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info) help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses | -LL | cmp!(std::ptr::addr_eq(a, b)); - | ++++++++++++++++++ ~ + +LL | ($a:tt, $b:tt) => { std::ptr::addr_eq($a, $b) } + | ++++++++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:159:39 + --> $DIR/wide_pointer_comparisons.rs:157:39 | LL | ($a:ident, $b:ident) => { $a == $b } | ^^^^^^^^ @@ -612,10 +616,10 @@ LL | ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) } | ++++++++++++++++++ ~ + warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected - --> $DIR/wide_pointer_comparisons.rs:169:37 + --> $DIR/wide_pointer_comparisons.rs:167:37 | LL | ($a:expr, $b:expr) => { $a == $b } - | ^^ + | ^^^^^ ... LL | cmp!(&a, &b); | ------------ in this macro invocation diff --git a/tests/ui/macros/auxiliary/recursive-macro.rs b/tests/ui/macros/auxiliary/recursive-macro.rs new file mode 100644 index 0000000000000..012cf768584e5 --- /dev/null +++ b/tests/ui/macros/auxiliary/recursive-macro.rs @@ -0,0 +1,5 @@ +#[macro_export] +macro_rules! recursive_macro { + (outer $tt:tt) => { $crate::recursive_macro!(inner $tt) }; + (inner $tt:tt) => { $tt + 2 }; +} diff --git a/tests/ui/macros/metavar-span-collision-recursive.rs b/tests/ui/macros/metavar-span-collision-recursive.rs new file mode 100644 index 0000000000000..cc9bd8177f88b --- /dev/null +++ b/tests/ui/macros/metavar-span-collision-recursive.rs @@ -0,0 +1,6 @@ +//@ compile-flags: -Z macro-backtrace +//@ aux-crate: recursive_macro=recursive-macro.rs + +fn main() { + let _: () = recursive_macro::recursive_macro!(outer 1); //~ ERROR mismatched types +} diff --git a/tests/ui/macros/metavar-span-collision-recursive.stderr b/tests/ui/macros/metavar-span-collision-recursive.stderr new file mode 100644 index 0000000000000..80891c8ec1c57 --- /dev/null +++ b/tests/ui/macros/metavar-span-collision-recursive.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/auxiliary/recursive-macro.rs:4:25 + | +LL | macro_rules! recursive_macro { + | ---------------------------- + | | + | in this expansion of `recursive_macro::recursive_macro!` (#1) + | in this expansion of `$crate::recursive_macro!` (#2) +LL | (outer $tt:tt) => { $crate::recursive_macro!(inner $tt) }; + | ----------------------------------- in this macro invocation (#2) +LL | (inner $tt:tt) => { $tt + 2 }; + | ^^^^^^^ expected `()`, found integer + | + ::: $DIR/metavar-span-collision-recursive.rs:5:12 + | +LL | let _: () = recursive_macro::recursive_macro!(outer 1); + | -- ------------------------------------------ in this macro invocation (#1) + | | + | expected due to this + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/methods/method-on-ambiguous-numeric-type.stderr b/tests/ui/methods/method-on-ambiguous-numeric-type.stderr index 124270402727d..060595e1d406b 100644 --- a/tests/ui/methods/method-on-ambiguous-numeric-type.stderr +++ b/tests/ui/methods/method-on-ambiguous-numeric-type.stderr @@ -47,8 +47,8 @@ LL | local_bar_tt.pow(2); | help: you must specify a type for this binding, like `i32` | -LL | local_mac_tt!(local_bar_tt: i32); - | +++++ +LL | ($tt:tt) => { let $tt: i32 = 42; } + | +++++ error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}` --> $DIR/method-on-ambiguous-numeric-type.rs:37:9 diff --git a/tests/ui/modules/issue-56411.stderr b/tests/ui/modules/issue-56411.stderr index 6732a8a3d7324..5632e76138496 100644 --- a/tests/ui/modules/issue-56411.stderr +++ b/tests/ui/modules/issue-56411.stderr @@ -4,16 +4,17 @@ error[E0255]: the name `issue_56411_aux` is defined multiple times LL | mod $name; | ---------- previous definition of the module `issue_56411_aux` here LL | pub use self::$name; - | ^^^^^^^^^^^ - | | - | `issue_56411_aux` reimported here - | you can use `as` to change the binding name of the import + | ^^^^^^^^^^^ `issue_56411_aux` reimported here ... LL | import!(("issue-56411-aux.rs", issue_56411_aux)); | ------------------------------------------------ in this macro invocation | = note: `issue_56411_aux` must be defined only once in the type namespace of this module = note: this error originates in the macro `import` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you can use `as` to change the binding name of the import + | +LL | pub use self::$name as other_issue_56411_aux; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0365]: `issue_56411_aux` is only public within the crate, and cannot be re-exported outside --> $DIR/issue-56411.rs:6:21 diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.rs b/tests/ui/parser/attribute/attr-unquoted-ident.rs index 5b15b8d69fcf8..78684c31124d2 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.rs +++ b/tests/ui/parser/attribute/attr-unquoted-ident.rs @@ -19,7 +19,8 @@ fn main() { macro_rules! make { ($name:ident) => { #[doc(alias = $name)] pub struct S; } - //~^ ERROR expected unsuffixed literal, found `nickname` + } -make!(nickname); //~ NOTE in this expansion +make!(nickname); //~ ERROR expected unsuffixed literal, found `nickname` + //~| HELP surround the identifier with quotation marks diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index e0f99459c44e7..5304bbf3e6d61 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -21,15 +21,15 @@ LL | #[cfg(key="foo bar baz")] | + + error: expected unsuffixed literal, found `nickname` - --> $DIR/attr-unquoted-ident.rs:21:38 + --> $DIR/attr-unquoted-ident.rs:25:7 | -LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } - | ^^^^^ -... LL | make!(nickname); - | --------------- in this macro invocation + | ^^^^^^^^ | - = note: this error originates in the macro `make` (in Nightly builds, run with -Z macro-backtrace for more info) +help: surround the identifier with quotation marks to make it into a string literal + | +LL | make!("nickname"); + | + + error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/input-interpolated.stdout b/tests/ui/proc-macro/input-interpolated.stdout index 1bccd8806be91..7510445fe2be1 100644 --- a/tests/ui/proc-macro/input-interpolated.stdout +++ b/tests/ui/proc-macro/input-interpolated.stdout @@ -13,7 +13,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ }, Ident { ident: "A", - span: #0 bytes(506..507), + span: #0 bytes(425..427), }, Punct { ch: ':', @@ -49,7 +49,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ }, Ident { ident: "A", - span: #0 bytes(506..507), + span: #0 bytes(478..480), }, Group { delimiter: Brace, diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed index 6ebdff0334c8b..82701ed74801f 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed @@ -12,8 +12,6 @@ macro_rules! tt { macro_rules! ident { ($e:ident) => { #[unsafe($e)] - //~^ ERROR: unsafe attribute used without unsafe - //~| WARN this is accepted in the current edition extern fn bar() {} } } @@ -21,8 +19,6 @@ macro_rules! ident { macro_rules! ident2 { ($e:ident, $l:literal) => { #[unsafe($e = $l)] - //~^ ERROR: unsafe attribute used without unsafe - //~| WARN this is accepted in the current edition extern fn bars() {} } } @@ -45,6 +41,8 @@ tt!([unsafe(no_mangle)]); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition ident!(no_mangle); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition meta!(unsafe(no_mangle)); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition @@ -52,6 +50,8 @@ meta2!(unsafe(export_name = "baw")); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition ident2!(export_name, "bars"); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition #[unsafe(no_mangle)] //~^ ERROR: unsafe attribute used without unsafe diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs index c78ff45ea4cdf..903fcfe8371f5 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs @@ -12,8 +12,6 @@ macro_rules! tt { macro_rules! ident { ($e:ident) => { #[$e] - //~^ ERROR: unsafe attribute used without unsafe - //~| WARN this is accepted in the current edition extern fn bar() {} } } @@ -21,8 +19,6 @@ macro_rules! ident { macro_rules! ident2 { ($e:ident, $l:literal) => { #[$e = $l] - //~^ ERROR: unsafe attribute used without unsafe - //~| WARN this is accepted in the current edition extern fn bars() {} } } @@ -45,6 +41,8 @@ tt!([no_mangle]); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition ident!(no_mangle); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition meta!(no_mangle); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition @@ -52,6 +50,8 @@ meta2!(export_name = "baw"); //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition ident2!(export_name, "bars"); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition #[no_mangle] //~^ ERROR: unsafe attribute used without unsafe diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr index c95984f58ecf7..62d4a76223fc7 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr @@ -1,5 +1,5 @@ error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:44:6 + --> $DIR/unsafe-attributes-fix.rs:40:6 | LL | tt!([no_mangle]); | ^^^^^^^^^ usage of unsafe attribute @@ -17,24 +17,20 @@ LL | tt!([unsafe(no_mangle)]); | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:14:11 + --> $DIR/unsafe-attributes-fix.rs:43:8 | -LL | #[$e] - | ^^ usage of unsafe attribute -... LL | ident!(no_mangle); - | ----------------- in this macro invocation + | ^^^^^^^^^ usage of unsafe attribute | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! = note: for more information, see issue #123757 - = note: this error originates in the macro `ident` (in Nightly builds, run with -Z macro-backtrace for more info) help: wrap the attribute in `unsafe(...)` | LL | #[unsafe($e)] | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:48:7 + --> $DIR/unsafe-attributes-fix.rs:46:7 | LL | meta!(no_mangle); | ^^^^^^^^^ usage of unsafe attribute @@ -47,7 +43,7 @@ LL | meta!(unsafe(no_mangle)); | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:51:8 + --> $DIR/unsafe-attributes-fix.rs:49:8 | LL | meta2!(export_name = "baw"); | ^^^^^^^^^^^ usage of unsafe attribute @@ -60,17 +56,13 @@ LL | meta2!(unsafe(export_name = "baw")); | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:23:11 + --> $DIR/unsafe-attributes-fix.rs:52:9 | -LL | #[$e = $l] - | ^^ usage of unsafe attribute -... LL | ident2!(export_name, "bars"); - | ---------------------------- in this macro invocation + | ^^^^^^^^^^^ usage of unsafe attribute | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! = note: for more information, see issue #123757 - = note: this error originates in the macro `ident2` (in Nightly builds, run with -Z macro-backtrace for more info) help: wrap the attribute in `unsafe(...)` | LL | #[unsafe($e = $l)] diff --git a/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs b/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs index cc66b5fd6f2b8..ba9f9227aac8e 100644 --- a/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs +++ b/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.rs @@ -71,12 +71,12 @@ macro_rules! nested2_tt_args_in_first_macro { // instead of the enum variant macro_rules! nested1_ident_args_in_first_macro { () => (nested2_ident_args_in_first_macro!(i32, u32)); + //~^ ERROR type arguments are not allowed on this type } macro_rules! nested2_ident_args_in_first_macro { ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} - //~^ ERROR type arguments are not allowed on this type - //~| ERROR mismatched types + //~^ ERROR mismatched types = 5 { true } else { false }); } diff --git a/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr b/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr index cb7666657ef4a..9e18830cfa3eb 100644 --- a/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr +++ b/tests/ui/typeck/issue-116473-ice-wrong-span-variant-args.stderr @@ -173,18 +173,19 @@ LL | nested1_tt_args_in_first_macro!(); = note: this error originates in the macro `nested2_tt_args_in_first_macro` which comes from the expansion of the macro `nested1_tt_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0109]: type arguments are not allowed on this type - --> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:64 + --> $DIR/issue-116473-ice-wrong-span-variant-args.rs:73:47 | +LL | () => (nested2_ident_args_in_first_macro!(i32, u32)); + | ^^^ ^^^ type argument not allowed +... LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} - | -------- ^^^^^ ^^^^^ type argument not allowed - | | - | not allowed on this type + | -------- not allowed on this type ... LL | nested1_ident_args_in_first_macro!(); | ------------------------------------ in this macro invocation | = note: enum variants can't have type parameters - = note: this error originates in the macro `nested2_ident_args_in_first_macro` which comes from the expansion of the macro `nested1_ident_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `nested1_ident_args_in_first_macro` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to specify type parameters on enum `Enum` | LL - ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} @@ -192,11 +193,11 @@ LL + ($arg1:ident, $arg2:ident) => (if let EnumUnit::<$arg1, $arg2>::Variant | error[E0308]: mismatched types - --> $DIR/issue-116473-ice-wrong-span-variant-args.rs:77:43 + --> $DIR/issue-116473-ice-wrong-span-variant-args.rs:78:43 | LL | ($arg1:ident, $arg2:ident) => (if let EnumUnit::VariantB::<$arg1, $arg2> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>` -... +LL | LL | = 5 { true } else { false }); | - this expression has type `{integer}` ...