From b18f3e11fa9c2d6fb8a6c4807229bebc3608d3ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 1 Feb 2024 10:13:24 +1100 Subject: Prefer `DiagnosticBuilder` over `Diagnostic` in diagnostic modifiers. There are lots of functions that modify a diagnostic. This can be via a `&mut Diagnostic` or a `&mut DiagnosticBuilder`, because the latter type wraps the former and impls `DerefMut`. This commit converts all the `&mut Diagnostic` occurrences to `&mut DiagnosticBuilder`. This is a step towards greatly simplifying `Diagnostic`. Some of the relevant function are made generic, because they deal with both errors and warnings. No function bodies are changed, because all the modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. --- compiler/rustc_parse/src/parser/attr.rs | 4 ++-- compiler/rustc_parse/src/parser/diagnostics.rs | 12 ++++++------ compiler/rustc_parse/src/parser/expr.rs | 8 +++----- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 98e062dd784..6545429b95b 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -8,7 +8,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Delimiter, Nonterminal}; -use rustc_errors::{codes::*, Diagnostic, PResult}; +use rustc_errors::{codes::*, DiagnosticBuilder, PResult}; use rustc_span::{sym, BytePos, Span}; use thin_vec::ThinVec; use tracing::debug; @@ -141,7 +141,7 @@ impl<'a> Parser<'a> { fn annotate_following_item_if_applicable( &self, - err: &mut Diagnostic, + err: &mut DiagnosticBuilder<'_>, span: Span, attr_type: OuterAttributeType, ) -> Option { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 659716548d9..0cc2170714c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -34,8 +34,8 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, FatalError, PErr, PResult, + pluralize, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed, + FatalError, PErr, PResult, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -208,11 +208,11 @@ struct MultiSugg { } impl MultiSugg { - fn emit(self, err: &mut Diagnostic) { + fn emit(self, err: &mut DiagnosticBuilder<'_>) { err.multipart_suggestion(self.msg, self.patches, self.applicability); } - fn emit_verbose(self, err: &mut Diagnostic) { + fn emit_verbose(self, err: &mut DiagnosticBuilder<'_>) { err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability); } } @@ -846,7 +846,7 @@ impl<'a> Parser<'a> { err.emit(); } - fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool { + fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { let sm = self.sess.source_map(); match (&self.prev_token.kind, &self.token.kind) { ( @@ -2179,7 +2179,7 @@ impl<'a> Parser<'a> { pub(super) fn parameter_without_type( &mut self, - err: &mut Diagnostic, + err: &mut DiagnosticBuilder<'_>, pat: P, require_name: bool, first_param: bool, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 20b9581f2ef..8826c06bebd 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -25,9 +25,7 @@ use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLim use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{ - AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey, -}; +use rustc_errors::{AddToDiagnostic, Applicability, DiagnosticBuilder, PResult, StashKey}; use rustc_lexer::unescape::unescape_char; use rustc_macros::Subdiagnostic; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; @@ -865,7 +863,7 @@ impl<'a> Parser<'a> { ); let mut err = self.dcx().struct_span_err(span, msg); - let suggest_parens = |err: &mut Diagnostic| { + let suggest_parens = |err: &mut DiagnosticBuilder<'_>| { let suggestions = vec![ (span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string()), @@ -3437,7 +3435,7 @@ impl<'a> Parser<'a> { let mut recover_async = false; let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD); - let mut async_block_err = |e: &mut Diagnostic, span: Span| { + let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| { recover_async = true; errors::AsyncBlockIn2015 { span }.add_to_diagnostic(e); errors::HelpUseLatestEdition::new().add_to_diagnostic(e); -- cgit 1.4.1-3-g733a5 From 9c8b107955194b80941ce825646bc2f34edc5dd5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 20 Feb 2024 16:09:03 +0000 Subject: Support async trait bounds in macros --- compiler/rustc_parse/messages.ftl | 2 + compiler/rustc_parse/src/errors.rs | 7 ++++ compiler/rustc_parse/src/parser/item.rs | 9 +++++ compiler/rustc_parse/src/parser/ty.rs | 9 +++-- tests/ui/async-await/async-fn/impl-header.rs | 6 ++- tests/ui/async-await/async-fn/impl-header.stderr | 45 +++++++++++++++++++-- ...mbe-async-trait-bound-theoretical-regression.rs | 21 ++++++++++ ...async-trait-bound-theoretical-regression.stderr | 47 ++++++++++++++++++++++ .../async-await/async-fn/trait-bounds-in-macro.rs | 12 ++++++ .../async-fn/trait-bounds-in-macro.stderr | 14 +++++++ tests/ui/parser/bad-recover-kw-after-impl.rs | 4 +- tests/ui/parser/bad-recover-kw-after-impl.stderr | 23 +++++++++++ tests/ui/parser/trait-object-delimiters.rs | 2 +- tests/ui/parser/trait-object-delimiters.stderr | 4 +- ...mbe-const-trait-bound-theoretical-regression.rs | 13 +++--- ...const-trait-bound-theoretical-regression.stderr | 40 ++++++++++++------ 16 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs create mode 100644 tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr create mode 100644 tests/ui/async-await/async-fn/trait-bounds-in-macro.rs create mode 100644 tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr create mode 100644 tests/ui/parser/bad-recover-kw-after-impl.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 7c2ecf34c17..55baf6f9f2e 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -27,6 +27,8 @@ parse_async_bound_modifier_in_2015 = `async` trait bounds are only allowed in Ru parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015 .label = to use `async fn`, switch to Rust 2018 or later +parse_async_impl = `async` trait implementations are unsupported + parse_async_move_block_in_2015 = `async move` blocks are only allowed in Rust 2018 or later parse_async_move_order_incorrect = the order of `move` and `async` is incorrect diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index fde67ac089a..2d4447a42c2 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2975,3 +2975,10 @@ pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span); #[derive(Diagnostic)] #[diag(parse_invalid_offset_of)] pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span); + +#[derive(Diagnostic)] +#[diag(parse_async_impl)] +pub(crate) struct AsyncImpl { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e7b9076bd3c..71453a88e2c 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -562,6 +562,15 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::const_trait_impl, span); } + // Parse stray `impl async Trait` + if (self.token.uninterpolated_span().at_least_rust_2018() + && self.token.is_keyword(kw::Async)) + || self.is_kw_followed_by_ident(kw::Async) + { + self.bump(); + self.dcx().emit_err(errors::AsyncImpl { span: self.prev_token.span }); + } + let polarity = self.parse_polarity(); // Parse both types and traits as a type, then reinterpret if necessary. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index f79f2a813b2..23a92e6dd3d 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -778,9 +778,10 @@ impl<'a> Parser<'a> { || self.check(&token::Not) || self.check(&token::Question) || self.check(&token::Tilde) - || self.check_keyword(kw::Const) || self.check_keyword(kw::For) || self.check(&token::OpenDelim(Delimiter::Parenthesis)) + || self.check_keyword(kw::Const) + || self.check_keyword(kw::Async) } /// Parses a bound according to the grammar: @@ -882,11 +883,13 @@ impl<'a> Parser<'a> { BoundConstness::Never }; - let asyncness = if self.token.span.at_least_rust_2018() && self.eat_keyword(kw::Async) { + let asyncness = if self.token.uninterpolated_span().at_least_rust_2018() + && self.eat_keyword(kw::Async) + { self.sess.gated_spans.gate(sym::async_closure, self.prev_token.span); BoundAsyncness::Async(self.prev_token.span) } else if self.may_recover() - && self.token.span.is_rust_2015() + && self.token.uninterpolated_span().is_rust_2015() && self.is_kw_followed_by_ident(kw::Async) { self.bump(); // eat `async` diff --git a/tests/ui/async-await/async-fn/impl-header.rs b/tests/ui/async-await/async-fn/impl-header.rs index b9ae90292bb..9af5f1f42a9 100644 --- a/tests/ui/async-await/async-fn/impl-header.rs +++ b/tests/ui/async-await/async-fn/impl-header.rs @@ -3,6 +3,10 @@ struct F; impl async Fn<()> for F {} -//~^ ERROR expected type, found keyword `async` +//~^ ERROR `async` trait implementations are unsupported +//~| ERROR the precise format of `Fn`-family traits' type parameters is subject to change +//~| ERROR manual implementations of `Fn` are experimental +//~| ERROR expected a `FnMut()` closure, found `F` +//~| ERROR not all trait items implemented, missing: `call` fn main() {} diff --git a/tests/ui/async-await/async-fn/impl-header.stderr b/tests/ui/async-await/async-fn/impl-header.stderr index 02cb4326242..2fb862af04e 100644 --- a/tests/ui/async-await/async-fn/impl-header.stderr +++ b/tests/ui/async-await/async-fn/impl-header.stderr @@ -1,8 +1,47 @@ -error: expected type, found keyword `async` +error: `async` trait implementations are unsupported --> $DIR/impl-header.rs:5:6 | LL | impl async Fn<()> for F {} - | ^^^^^ expected type + | ^^^^^ -error: aborting due to 1 previous error +error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change + --> $DIR/impl-header.rs:5:12 + | +LL | impl async Fn<()> for F {} + | ^^^^^^ + | + = note: see issue #29625 for more information + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0183]: manual implementations of `Fn` are experimental + --> $DIR/impl-header.rs:5:12 + | +LL | impl async Fn<()> for F {} + | ^^^^^^ manual implementations of `Fn` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error[E0277]: expected a `FnMut()` closure, found `F` + --> $DIR/impl-header.rs:5:23 + | +LL | impl async Fn<()> for F {} + | ^ expected an `FnMut()` closure, found `F` + | + = help: the trait `FnMut<()>` is not implemented for `F` + = note: wrap the `F` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Fn` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error[E0046]: not all trait items implemented, missing: `call` + --> $DIR/impl-header.rs:5:1 + | +LL | impl async Fn<()> for F {} + | ^^^^^^^^^^^^^^^^^^^^^^^ missing `call` in implementation + | + = help: implement the missing item: `fn call(&self, _: ()) -> >::Output { todo!() }` + +error: aborting due to 5 previous errors +Some errors have detailed explanations: E0046, E0183, E0277, E0658. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs new file mode 100644 index 00000000000..abc429772fd --- /dev/null +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.rs @@ -0,0 +1,21 @@ +// Demonstrates and records a theoretical regressions / breaking changes caused by the +// introduction of async trait bounds. + +// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018. +//@ edition:2018 + +macro_rules! demo { + ($ty:ty) => { compile_error!("ty"); }; + //~^ ERROR ty + //~| ERROR ty + (impl $c:ident Trait) => {}; + (dyn $c:ident Trait) => {}; +} + +demo! { impl async Trait } +//~^ ERROR async closures are unstable + +demo! { dyn async Trait } +//~^ ERROR async closures are unstable + +fn main() {} diff --git a/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr new file mode 100644 index 00000000000..13b8e72b49d --- /dev/null +++ b/tests/ui/async-await/async-fn/mbe-async-trait-bound-theoretical-regression.stderr @@ -0,0 +1,47 @@ +error: ty + --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { impl async Trait } + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: ty + --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:8:19 + | +LL | ($ty:ty) => { compile_error!("ty"); }; + | ^^^^^^^^^^^^^^^^^^^^ +... +LL | demo! { dyn async Trait } + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0658]: async closures are unstable + --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:15:14 + | +LL | demo! { impl async Trait } + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error[E0658]: async closures are unstable + --> $DIR/mbe-async-trait-bound-theoretical-regression.rs:18:13 + | +LL | demo! { dyn async Trait } + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs new file mode 100644 index 00000000000..329a1528e8b --- /dev/null +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.rs @@ -0,0 +1,12 @@ +//@ edition: 2021 + +macro_rules! x { + ($x:item) => {} +} + +x! { + async fn foo() -> impl async Fn() { } + //~^ ERROR async closures are unstable +} + +fn main() {} diff --git a/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr new file mode 100644 index 00000000000..f68c09737db --- /dev/null +++ b/tests/ui/async-await/async-fn/trait-bounds-in-macro.stderr @@ -0,0 +1,14 @@ +error[E0658]: async closures are unstable + --> $DIR/trait-bounds-in-macro.rs:8:28 + | +LL | async fn foo() -> impl async Fn() { } + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/bad-recover-kw-after-impl.rs b/tests/ui/parser/bad-recover-kw-after-impl.rs index 23abceaf493..15c0b377c8a 100644 --- a/tests/ui/parser/bad-recover-kw-after-impl.rs +++ b/tests/ui/parser/bad-recover-kw-after-impl.rs @@ -1,4 +1,4 @@ -//@ check-pass +// This is just `mbe-async-trait-bound-theoretical-regression.rs` in practice. //@ edition:2021 // for the `impl` + keyword test @@ -11,5 +11,7 @@ macro_rules! impl_primitive { } impl_primitive!(impl async); +//~^ ERROR expected identifier, found `` +//~| ERROR async closures are unstable fn main() {} diff --git a/tests/ui/parser/bad-recover-kw-after-impl.stderr b/tests/ui/parser/bad-recover-kw-after-impl.stderr new file mode 100644 index 00000000000..f617cf65498 --- /dev/null +++ b/tests/ui/parser/bad-recover-kw-after-impl.stderr @@ -0,0 +1,23 @@ +error: expected identifier, found `` + --> $DIR/bad-recover-kw-after-impl.rs:13:22 + | +LL | ($ty:ty) => { + | ------ while parsing argument for this `ty` macro fragment +... +LL | impl_primitive!(impl async); + | ^^^^^ expected identifier + +error[E0658]: async closures are unstable + --> $DIR/bad-recover-kw-after-impl.rs:13:22 + | +LL | impl_primitive!(impl async); + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/trait-object-delimiters.rs b/tests/ui/parser/trait-object-delimiters.rs index 84cd16c2796..d6bc629aa11 100644 --- a/tests/ui/parser/trait-object-delimiters.rs +++ b/tests/ui/parser/trait-object-delimiters.rs @@ -8,7 +8,7 @@ fn foo2(_: &dyn (Drop + AsRef)) {} //~ ERROR incorrect parentheses around t fn foo2_no_space(_: &dyn(Drop + AsRef)) {} //~ ERROR incorrect parentheses around trait bounds fn foo3(_: &dyn {Drop + AsRef}) {} //~ ERROR expected parameter name, found `{` -//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{` +//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `async`, `const`, `for`, `~`, lifetime, or path, found `{` //~| ERROR at least one trait is required for an object type fn foo4(_: &dyn >) {} //~ ERROR expected identifier, found `<` diff --git a/tests/ui/parser/trait-object-delimiters.stderr b/tests/ui/parser/trait-object-delimiters.stderr index 2ddb734cee0..2b1f8df991f 100644 --- a/tests/ui/parser/trait-object-delimiters.stderr +++ b/tests/ui/parser/trait-object-delimiters.stderr @@ -34,11 +34,11 @@ error: expected parameter name, found `{` LL | fn foo3(_: &dyn {Drop + AsRef}) {} | ^ expected parameter name -error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{` +error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `async`, `const`, `for`, `~`, lifetime, or path, found `{` --> $DIR/trait-object-delimiters.rs:10:17 | LL | fn foo3(_: &dyn {Drop + AsRef}) {} - | -^ expected one of 11 possible tokens + | -^ expected one of 12 possible tokens | | | help: missing `,` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs index 99806922ba5..3dcdb0cad94 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.rs @@ -6,15 +6,16 @@ macro_rules! demo { ($ty:ty) => { compile_error!("ty"); }; - (impl $c:ident) => {}; - (dyn $c:ident) => {}; + //~^ ERROR ty + //~| ERROR ty + (impl $c:ident Trait) => {}; + (dyn $c:ident Trait) => {}; } -demo! { impl const } -//~^ ERROR expected identifier, found `` +demo! { impl const Trait } +//~^ ERROR const trait impls are experimental -demo! { dyn const } +demo! { dyn const Trait } //~^ ERROR const trait impls are experimental -//~| ERROR expected identifier, found `` fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr index fd9184b9dff..f4b401b7386 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/mbe-const-trait-bound-theoretical-regression.stderr @@ -1,31 +1,45 @@ -error: expected identifier, found `` - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:13:14 +error: ty + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19 | LL | ($ty:ty) => { compile_error!("ty"); }; - | ------ while parsing argument for this `ty` macro fragment + | ^^^^^^^^^^^^^^^^^^^^ ... -LL | demo! { impl const } - | ^^^^^ expected identifier +LL | demo! { impl const Trait } + | -------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: expected identifier, found `` - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13 +error: ty + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:8:19 | LL | ($ty:ty) => { compile_error!("ty"); }; - | ------ while parsing argument for this `ty` macro fragment + | ^^^^^^^^^^^^^^^^^^^^ ... -LL | demo! { dyn const } - | ^^^^^ expected identifier +LL | demo! { dyn const Trait } + | ------------------------- in this macro invocation + | + = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0658]: const trait impls are experimental + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:15:14 + | +LL | demo! { impl const Trait } + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: const trait impls are experimental - --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:16:13 + --> $DIR/mbe-const-trait-bound-theoretical-regression.rs:18:13 | -LL | demo! { dyn const } +LL | demo! { dyn const Trait } | ^^^^^ | = note: see issue #67792 for more information = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From 09ca866738711331609811da2d8399531bda66c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 21 Feb 2024 14:23:46 +1100 Subject: Remove an `unchecked_error_guaranteed` call. If we abort immediately after complaining about the obsolete `impl Trait for ..` syntax, then we avoid reaching HIR lowering. This means we can use `TyKind::Dummy` instead of `TyKind::Err`. --- compiler/rustc_ast_passes/src/ast_validation.rs | 7 ++++--- compiler/rustc_parse/src/parser/item.rs | 20 ++++---------------- 2 files changed, 8 insertions(+), 19 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index fa0f5326196..8c9ad836087 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -881,9 +881,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, errors::VisibilityNotPermittedNote::TraitImpl, ); - // njn: use Dummy here - if let TyKind::Err(_) = self_ty.kind { - this.dcx().emit_err(errors::ObsoleteAuto { span: item.span }); + if let TyKind::Dummy = self_ty.kind { + // Abort immediately otherwise the `TyKind::Dummy` will reach HIR lowering, + // which isn't allowed. Not a problem for this obscure, obsolete syntax. + this.dcx().emit_fatal(errors::ObsoleteAuto { span: item.span }); } if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity) { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e7b9076bd3c..755a70667ed 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -592,22 +592,10 @@ impl<'a> Parser<'a> { // We need to report this error after `cfg` expansion for compatibility reasons self.bump(); // `..`, do not add it to expected tokens - // FIXME(nnethercote): AST validation later detects this - // `TyKind::Err` and emits an errors. So why the unchecked - // ErrorGuaranteed? - // - A `span_delayed_bug` doesn't work here, because rustfmt can - // hit this path but then not hit the follow-up path in the AST - // validator that issues the error, which results in ICEs. - // - `TyKind::Dummy` doesn't work, because it ends up reaching HIR - // lowering, which results in ICEs. Changing `TyKind::Dummy` to - // `TyKind::Err` during AST validation might fix that, but that's - // not possible because AST validation doesn't allow mutability. - // - // #121072 will hopefully remove all this special handling of the - // obsolete `impl Trait for ..` and then this can go away. - #[allow(deprecated)] - let guar = rustc_errors::ErrorGuaranteed::unchecked_error_guaranteed(); - Some(self.mk_ty(self.prev_token.span, TyKind::Err(guar))) + // AST validation later detects this `TyKind::Dummy` and emits an + // error. (#121072 will hopefully remove all this special handling + // of the obsolete `impl Trait for ..` and then this can go away.) + Some(self.mk_ty(self.prev_token.span, TyKind::Dummy)) } else if has_for || self.token.can_begin_type() { Some(self.parse_ty()?) } else { -- cgit 1.4.1-3-g733a5