From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_expand/src/expand.rs | 72 ++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'compiler/rustc_expand/src/expand.rs') diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index c2add852a..57713fb3c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -50,6 +50,7 @@ macro_rules! ast_fragments { /// Can also serve as an input and intermediate result for macro expansion operations. pub enum AstFragment { OptExpr(Option>), + MethodReceiverExpr(P), $($Kind($AstTy),)* } @@ -57,6 +58,7 @@ macro_rules! ast_fragments { #[derive(Copy, Clone, PartialEq, Eq)] pub enum AstFragmentKind { OptExpr, + MethodReceiverExpr, $($Kind,)* } @@ -64,6 +66,7 @@ macro_rules! ast_fragments { pub fn name(self) -> &'static str { match self { AstFragmentKind::OptExpr => "expression", + AstFragmentKind::MethodReceiverExpr => "expression", $(AstFragmentKind::$Kind => $kind_name,)* } } @@ -72,6 +75,8 @@ macro_rules! ast_fragments { match self { AstFragmentKind::OptExpr => result.make_expr().map(Some).map(AstFragment::OptExpr), + AstFragmentKind::MethodReceiverExpr => + result.make_expr().map(AstFragment::MethodReceiverExpr), $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)* } } @@ -98,6 +103,13 @@ macro_rules! ast_fragments { } } + pub fn make_method_receiver_expr(self) -> P { + match self { + AstFragment::MethodReceiverExpr(expr) => expr, + _ => panic!("AstFragment::make_* called on the wrong kind of fragment"), + } + } + $(pub fn $make_ast(self) -> $AstTy { match self { AstFragment::$Kind(ast) => ast, @@ -120,6 +132,7 @@ macro_rules! ast_fragments { } }); } + AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr), $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)* $($(AstFragment::$Kind(ast) => ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)* @@ -130,6 +143,7 @@ macro_rules! ast_fragments { match *self { AstFragment::OptExpr(Some(ref expr)) => visitor.visit_expr(expr), AstFragment::OptExpr(None) => {} + AstFragment::MethodReceiverExpr(ref expr) => visitor.visit_method_receiver_expr(expr), $($(AstFragment::$Kind(ref ast) => visitor.$visit_ast(ast),)?)* $($(AstFragment::$Kind(ref ast) => for ast_elt in &ast[..] { visitor.$visit_ast_elt(ast_elt, $($args)*); @@ -222,6 +236,7 @@ impl AstFragmentKind { match self { AstFragmentKind::OptExpr | AstFragmentKind::Expr + | AstFragmentKind::MethodReceiverExpr | AstFragmentKind::Stmts | AstFragmentKind::Ty | AstFragmentKind::Pat => SupportsMacroExpansion::Yes { supports_inner_attrs: false }, @@ -285,6 +300,9 @@ impl AstFragmentKind { AstFragmentKind::Expr => AstFragment::Expr( items.next().expect("expected exactly one expression").expect_expr(), ), + AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr( + items.next().expect("expected exactly one expression").expect_expr(), + ), AstFragmentKind::OptExpr => { AstFragment::OptExpr(items.next().map(Annotatable::expect_expr)) } @@ -327,7 +345,7 @@ impl InvocationKind { fn placeholder_visibility(&self) -> Option { // HACK: For unnamed fields placeholders should have the same visibility as the actual // fields because for tuple structs/variants resolve determines visibilities of their - // constructor using these field visibilities before attributes on them are are expanded. + // constructor using these field visibilities before attributes on them are expanded. // The assumption is that the attribute expansion cannot change field visibilities, // and it holds because only inert attributes are supported in this position. match self { @@ -893,6 +911,7 @@ pub fn parse_ast_fragment<'a>( AstFragment::Stmts(stmts) } AstFragmentKind::Expr => AstFragment::Expr(this.parse_expr()?), + AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr(this.parse_expr()?), AstFragmentKind::OptExpr => { if this.token != token::Eof { AstFragment::OptExpr(Some(this.parse_expr()?)) @@ -937,13 +956,12 @@ pub fn ensure_complete_parse<'a>( kind_name, ); err.note(&msg); - let semi_span = this.sess.source_map().next_point(span); - let semi_full_span = semi_span.to(this.sess.source_map().next_point(semi_span)); - match this.sess.source_map().span_to_snippet(semi_full_span) { + let semi_span = this.sess.source_map().next_point(span); + match this.sess.source_map().span_to_snippet(semi_span) { Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => { err.span_suggestion( - semi_span, + span.shrink_to_hi(), "you might be missing a semicolon here", ";", Applicability::MaybeIncorrect, @@ -1478,6 +1496,42 @@ impl InvocationCollectorNode for AstNodeWrapper, OptExprTag> { } } +/// This struct is a hack to workaround unstable of `stmt_expr_attributes`. +/// It can be removed once that feature is stabilized. +struct MethodReceiverTag; +impl DummyAstNode for MethodReceiverTag { + fn dummy() -> MethodReceiverTag { + MethodReceiverTag + } +} +impl InvocationCollectorNode for AstNodeWrapper, MethodReceiverTag> { + type OutputTy = Self; + type AttrsTy = ast::AttrVec; + const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr; + fn descr() -> &'static str { + "an expression" + } + fn to_annotatable(self) -> Annotatable { + Annotatable::Expr(self.wrapped) + } + fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { + AstNodeWrapper::new(fragment.make_method_receiver_expr(), MethodReceiverTag) + } + fn noop_visit(&mut self, visitor: &mut V) { + noop_visit_expr(&mut self.wrapped, visitor) + } + fn is_mac_call(&self) -> bool { + matches!(self.wrapped.kind, ast::ExprKind::MacCall(..)) + } + fn take_mac_call(self) -> (P, Self::AttrsTy, AddSemicolon) { + let node = self.wrapped.into_inner(); + match node.kind { + ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No), + _ => unreachable!(), + } + } +} + struct InvocationCollector<'a, 'b> { cx: &'a mut ExtCtxt<'b>, invocations: Vec<(Invocation, Option>)>, @@ -1841,6 +1895,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.visit_node(node) } + fn visit_method_receiver_expr(&mut self, node: &mut P) { + visit_clobber(node, |node| { + let mut wrapper = AstNodeWrapper::new(node, MethodReceiverTag); + self.visit_node(&mut wrapper); + wrapper.wrapped + }) + } + fn filter_map_expr(&mut self, node: P) -> Option> { self.flat_map_node(AstNodeWrapper::new(node, OptExprTag)) } -- cgit v1.2.3