about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs11
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs24
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs4
-rw-r--r--compiler/rustc_lint/src/early.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs32
5 files changed, 44 insertions, 29 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index bf18e10e19f..7cceca3c24d 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -12,7 +12,7 @@
 //! - [`CombineAttributeParser`]: makes it easy to implement an attribute which should combine the
 //! contents of attributes, if an attribute appear multiple times in a list
 //!
-//! Attributes should be added to [`ATTRIBUTE_MAPPING`](crate::context::ATTRIBUTE_MAPPING) to be parsed.
+//! Attributes should be added to [`ATTRIBUTE_PARSERS`](crate::context::ATTRIBUTE_PARSERS) to be parsed.
 
 use std::marker::PhantomData;
 
@@ -51,6 +51,9 @@ type AcceptMapping<T> = &'static [(&'static [Symbol], AcceptFn<T>)];
 /// whether it has seen the attribute it has been looking for.
 ///
 /// The state machine is automatically reset to parse attributes on the next item.
+///
+/// For a simpler attribute parsing interface, consider using [`SingleAttributeParser`]
+/// or [`CombineAttributeParser`] instead.
 pub(crate) trait AttributeParser: Default + 'static {
     /// The symbols for the attributes that this parser is interested in.
     ///
@@ -59,6 +62,12 @@ pub(crate) trait AttributeParser: Default + 'static {
 
     /// The parser has gotten a chance to accept the attributes on an item,
     /// here it can produce an attribute.
+    ///
+    /// All finalize methods of all parsers are unconditionally called.
+    /// This means you can't unconditionally return `Some` here,
+    /// that'd be equivalent to unconditionally applying an attribute to
+    /// every single syntax item that could have attributes applied to it.
+    /// Your accept mappings should determine whether this returns something.
     fn finalize(self, cx: &FinalizeContext<'_>) -> Option<AttributeKind>;
 }
 
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index c02760d830c..35fb768ad0b 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -22,7 +22,7 @@ use crate::attributes::transparency::TransparencyParser;
 use crate::attributes::{AttributeParser as _, Combine, Single};
 use crate::parser::{ArgParser, MetaItemParser};
 
-macro_rules! attribute_groups {
+macro_rules! attribute_parsers {
     (
         pub(crate) static $name: ident = [$($names: ty),* $(,)?];
     ) => {
@@ -63,8 +63,8 @@ macro_rules! attribute_groups {
     };
 }
 
-attribute_groups!(
-    pub(crate) static ATTRIBUTE_MAPPING = [
+attribute_parsers!(
+    pub(crate) static ATTRIBUTE_PARSERS = [
         // tidy-alphabetical-start
         BodyStabilityParser,
         ConfusablesParser,
@@ -90,7 +90,7 @@ attribute_groups!(
 ///
 /// Gives [`AttributeParser`]s enough information to create errors, for example.
 pub(crate) struct AcceptContext<'a> {
-    pub(crate) group_cx: &'a FinalizeContext<'a>,
+    pub(crate) finalize_cx: &'a FinalizeContext<'a>,
     /// The span of the attribute currently being parsed
     pub(crate) attr_span: Span,
 }
@@ -109,7 +109,7 @@ impl<'a> Deref for AcceptContext<'a> {
     type Target = FinalizeContext<'a>;
 
     fn deref(&self) -> &Self::Target {
-        &self.group_cx
+        &self.finalize_cx
     }
 }
 
@@ -219,7 +219,7 @@ impl<'sess> AttributeParser<'sess> {
     ) -> Vec<Attribute> {
         let mut attributes = Vec::new();
 
-        let group_cx = FinalizeContext { cx: self, target_span };
+        let finalize_cx = FinalizeContext { cx: self, target_span };
 
         for attr in attrs {
             // If we're only looking for a single attribute, skip all the ones we don't care about.
@@ -268,9 +268,11 @@ impl<'sess> AttributeParser<'sess> {
                     let args = parser.args();
                     let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
 
-                    if let Some(accept) = ATTRIBUTE_MAPPING.0.get(parts.as_slice()) {
-                        let cx =
-                            AcceptContext { group_cx: &group_cx, attr_span: lower_span(attr.span) };
+                    if let Some(accept) = ATTRIBUTE_PARSERS.0.get(parts.as_slice()) {
+                        let cx = AcceptContext {
+                            finalize_cx: &finalize_cx,
+                            attr_span: lower_span(attr.span),
+                        };
 
                         accept(&cx, &args)
                     } else {
@@ -302,8 +304,8 @@ impl<'sess> AttributeParser<'sess> {
         }
 
         let mut parsed_attributes = Vec::new();
-        for f in &ATTRIBUTE_MAPPING.1 {
-            if let Some(attr) = f(&group_cx) {
+        for f in &ATTRIBUTE_PARSERS.1 {
+            if let Some(attr) = f(&finalize_cx) {
                 parsed_attributes.push(Attribute::Parsed(attr));
             }
         }
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 83a17092619..99add01f95c 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -58,9 +58,9 @@ pub enum MaybeEnteredSpan {
 macro_rules! enter_trace_span {
     ($machine:ident, $($tt:tt)*) => {
         if $machine::TRACING_ENABLED {
-            $crate::interpret::tracing_utils::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered())
+            $crate::interpret::util::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered())
         } else {
-            $crate::interpret::tracing_utils::MaybeEnteredSpan::None
+            $crate::interpret::util::MaybeEnteredSpan::None
         }
     }
 }
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 4978f293ab7..12666d383f9 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -136,7 +136,6 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
         // the AST struct that they wrap (e.g. an item)
         self.with_lint_attrs(s.id, s.attrs(), |cx| {
             lint_callback!(cx, check_stmt, s);
-            cx.check_id(s.id);
         });
         // The visitor for the AST struct wrapped
         // by the statement (e.g. `Item`) will call
@@ -147,7 +146,6 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
 
     fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) {
         lint_callback!(self, check_fn, fk, span, id);
-        self.check_id(id);
         ast_visit::walk_fn(self, fk);
     }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index a298c4d4dec..93489aa8ee9 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1520,22 +1520,20 @@ impl<'a> Parser<'a> {
                 Ok(this.mk_expr(this.prev_token.span, ExprKind::Underscore))
             } else if this.token_uninterpolated_span().at_least_rust_2018() {
                 // `Span::at_least_rust_2018()` is somewhat expensive; don't get it repeatedly.
+                let at_async = this.check_keyword(exp!(Async));
+                // check for `gen {}` and `gen move {}`
+                // or `async gen {}` and `async gen move {}`
+                // FIXME: (async) gen closures aren't yet parsed.
+                // FIXME(gen_blocks): Parse `gen async` and suggest swap
                 if this.token_uninterpolated_span().at_least_rust_2024()
-                    // check for `gen {}` and `gen move {}`
-                    // or `async gen {}` and `async gen move {}`
-                    && (this.is_gen_block(kw::Gen, 0)
-                        || (this.check_keyword(exp!(Async)) && this.is_gen_block(kw::Gen, 1)))
+                    && this.is_gen_block(kw::Gen, at_async as usize)
                 {
-                    // FIXME: (async) gen closures aren't yet parsed.
                     this.parse_gen_block()
-                } else if this.check_keyword(exp!(Async)) {
-                    // FIXME(gen_blocks): Parse `gen async` and suggest swap
-                    if this.is_gen_block(kw::Async, 0) {
-                        // Check for `async {` and `async move {`,
-                        this.parse_gen_block()
-                    } else {
-                        this.parse_expr_closure()
-                    }
+                // Check for `async {` and `async move {`,
+                } else if this.is_gen_block(kw::Async, 0) {
+                    this.parse_gen_block()
+                } else if at_async {
+                    this.parse_expr_closure()
                 } else if this.eat_keyword_noexpect(kw::Await) {
                     this.recover_incorrect_await_syntax(lo)
                 } else {
@@ -2407,6 +2405,14 @@ impl<'a> Parser<'a> {
             None
         };
 
+        if let ClosureBinder::NotPresent = binder
+            && coroutine_kind.is_some()
+        {
+            // coroutine closures and generators can have the same qualifiers, so we might end up
+            // in here if there is a missing `|` but also no `{`. Adjust the expectations in that case.
+            self.expected_token_types.insert(TokenType::OpenBrace);
+        }
+
         let capture_clause = self.parse_capture_clause()?;
         let (fn_decl, fn_arg_span) = self.parse_fn_block_decl()?;
         let decl_hi = self.prev_token.span;