From eb55cdce4bc1c03e1ce805af633dac611a948d43 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 22:53:09 +0200 Subject: [PATCH 01/14] use `ParseSess` instead of `Session` in `into_diagnostic` --- .../rustc_macros/src/session_diagnostic.rs | 6 ++++-- compiler/rustc_session/src/parse.rs | 18 +++++++++++++++++- compiler/rustc_session/src/session.rs | 14 +++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index ff7506979fc34..5661451f52071 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -119,7 +119,9 @@ fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnost /// Emit a diagnostic on span `$span` with msg `$msg` (optionally performing additional decoration /// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. macro_rules! throw_span_err { - ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }}; + ($span:expr, $msg:expr) => {{ + throw_span_err!($span, $msg, |diag| diag) + }}; ($span:expr, $msg:expr, $f:expr) => {{ return Err(_throw_span_err($span, $msg, $f)); }}; @@ -308,7 +310,7 @@ impl<'a> SessionDiagnosticDerive<'a> { { fn into_diagnostic( self, - #sess: &'__session_diagnostic_sess rustc_session::Session + #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, #param_ty> { use rustc_errors::IntoDiagnosticArg; #implementation diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 6a36ae63c6834..dd7682ebacef5 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -3,13 +3,14 @@ use crate::config::CheckCfg; use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId}; +use crate::SessionDiagnostic; use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ error_code, fallback_fluent_bundle, Applicability, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, MultiSpan, + DiagnosticMessage, ErrorGuaranteed, MultiSpan, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -287,4 +288,19 @@ impl ParseSess { pub fn proc_macro_quoted_spans(&self) -> Vec { self.proc_macro_quoted_spans.lock().clone() } + + pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { + err.into_diagnostic(self).emit() + } + + pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { + warning.into_diagnostic(self).emit() + } + + pub fn struct_err( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + self.span_diagnostic.struct_err(msg) + } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b4548129689b1..2bc0c5f1228e0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -212,7 +212,7 @@ pub struct PerfStats { pub trait SessionDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { /// Write out as a diagnostic out of `sess`. #[must_use] - fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a, T>; + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, T>; } impl Session { @@ -334,7 +334,7 @@ impl Session { &self, msg: impl Into, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - self.diagnostic().struct_err(msg) + self.parse_sess.struct_err(msg) } pub fn struct_err_with_code( &self, @@ -414,10 +414,10 @@ impl Session { self.diagnostic().err(msg) } pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { - err.into_diagnostic(self).emit() + self.parse_sess.emit_err(err) } pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { - warning.into_diagnostic(self).emit() + self.parse_sess.emit_warning(warning) } #[inline] pub fn err_count(&self) -> usize { @@ -783,7 +783,11 @@ impl Session { Path::new(&rustlib_path), Path::new("bin"), ]); - if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } + if self_contained { + vec![p.clone(), p.join("self-contained")] + } else { + vec![p] + } } pub fn init_incr_comp_session( From 519dd8e9de1a85e18b3033a007a3bf01c6e79560 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 22:55:15 +0200 Subject: [PATCH 02/14] migrate ambiguous plus diagnostic --- .../locales/en-US/parser.ftl | 3 ++ compiler/rustc_parse/Cargo.toml | 1 + .../rustc_parse/src/parser/diagnostics.rs | 32 +++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 24e59a93cea6c..fd7daadb1ab42 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -1,3 +1,6 @@ parser-struct-literal-body-without-path = struct literal body without path .suggestion = you might have forgotten to add the struct literal inside the block +parser-maybe-report-ambiguous-plus = + ambiguous `+` in a type + .suggestion = use parentheses to disambiguate diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index a823607ab0ec2..c6ca260e9831e 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -13,6 +13,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_feature = { path = "../rustc_feature" } rustc_lexer = { path = "../rustc_lexer" } +rustc_macros = { path = "../rustc_macros" } rustc_errors = { path = "../rustc_errors" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index ed2640451705b..d270f3606d760 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -21,6 +21,7 @@ use rustc_errors::{pluralize, struct_span_err, Diagnostic, EmissionGuarantee, Er use rustc_errors::{ Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult, }; +use rustc_macros::SessionDiagnostic; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, Ident}; use rustc_span::{Span, SpanSnippetError, DUMMY_SP}; @@ -1170,16 +1171,29 @@ impl<'a> Parser<'a> { impl_dyn_multi: bool, ty: &Ty, ) { + #[derive(SessionDiagnostic)] + #[error(slug = "parser-maybe-report-ambiguous-plus")] + struct AmbiguousPlus { + pub sum_with_parens: String, + #[primary_span] + #[suggestion(code = "{sum_with_parens}")] + pub span: Span, + } + if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi { - let sum_with_parens = format!("({})", pprust::ty_to_string(&ty)); - self.struct_span_err(ty.span, "ambiguous `+` in a type") - .span_suggestion( - ty.span, - "use parentheses to disambiguate", - sum_with_parens, - Applicability::MachineApplicable, - ) - .emit(); + self.sess.emit_err(AmbiguousPlus { + sum_with_parens: format!("({})", pprust::ty_to_string(&ty)), + span: ty.span, + }); + // let sum_with_parens = format!("({})", pprust::ty_to_string(&ty)); + // self.struct_span_err(ty.span, "ambiguous `+` in a type") + // .span_suggestion( + // ty.span, + // "use parentheses to disambiguate", + // sum_with_parens, + // Applicability::MachineApplicable, + // ) + // .emit(); } } From d6da5fb3532bd44f3baa6eff0011bd20c6323e6b Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 22:55:24 +0200 Subject: [PATCH 03/14] update lockfile --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 30175ae3561ab..567cef4c51eba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4181,6 +4181,7 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_lexer", + "rustc_macros", "rustc_session", "rustc_span", "tracing", From 5874b09806e40e4791ab8d50d956fedcca9df91d Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 23:17:32 +0200 Subject: [PATCH 04/14] fix formatting --- compiler/rustc_macros/src/session_diagnostic.rs | 4 +--- compiler/rustc_session/src/session.rs | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index 5661451f52071..9466d0f34bc07 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -119,9 +119,7 @@ fn span_err(span: impl proc_macro::MultiSpan, msg: &str) -> proc_macro::Diagnost /// Emit a diagnostic on span `$span` with msg `$msg` (optionally performing additional decoration /// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. macro_rules! throw_span_err { - ($span:expr, $msg:expr) => {{ - throw_span_err!($span, $msg, |diag| diag) - }}; + ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }}; ($span:expr, $msg:expr, $f:expr) => {{ return Err(_throw_span_err($span, $msg, $f)); }}; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 2bc0c5f1228e0..e8279f6fed24f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -783,11 +783,7 @@ impl Session { Path::new(&rustlib_path), Path::new("bin"), ]); - if self_contained { - vec![p.clone(), p.join("self-contained")] - } else { - vec![p] - } + if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } } pub fn init_incr_comp_session( From 530f4dce291371e0b1d567b47a1888aa8c806410 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 23:26:52 +0200 Subject: [PATCH 05/14] remove old code --- compiler/rustc_parse/src/parser/diagnostics.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d270f3606d760..23c4d67ebd797 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1185,15 +1185,6 @@ impl<'a> Parser<'a> { sum_with_parens: format!("({})", pprust::ty_to_string(&ty)), span: ty.span, }); - // let sum_with_parens = format!("({})", pprust::ty_to_string(&ty)); - // self.struct_span_err(ty.span, "ambiguous `+` in a type") - // .span_suggestion( - // ty.span, - // "use parentheses to disambiguate", - // sum_with_parens, - // Applicability::MachineApplicable, - // ) - // .emit(); } } From 2e261a82f3ba99e6d11a35ead9da95007530187a Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 25 Apr 2022 23:49:53 +0200 Subject: [PATCH 06/14] add `struct_warn` method --- compiler/rustc_session/src/parse.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index dd7682ebacef5..e933fe1cb2412 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -303,4 +303,8 @@ impl ParseSess { ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { self.span_diagnostic.struct_err(msg) } + + pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { + self.span_diagnostic.struct_warn(msg) + } } From 35b42cb9ecc61bb36a23e53ff4913865d3ab1e80 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 26 Apr 2022 11:11:23 +0200 Subject: [PATCH 07/14] avoid `format!` --- compiler/rustc_parse/src/parser/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 23c4d67ebd797..f0a053d88b5db 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1176,13 +1176,13 @@ impl<'a> Parser<'a> { struct AmbiguousPlus { pub sum_with_parens: String, #[primary_span] - #[suggestion(code = "{sum_with_parens}")] + #[suggestion(code = "({sum_with_parens})")] pub span: Span, } if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi { self.sess.emit_err(AmbiguousPlus { - sum_with_parens: format!("({})", pprust::ty_to_string(&ty)), + sum_with_parens: pprust::ty_to_string(&ty), span: ty.span, }); } From 6c3e793fb3303878790a6e872e8fa8bc1e4ef4e9 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 26 Apr 2022 11:12:48 +0200 Subject: [PATCH 08/14] move `AmbigousPlus` outside --- .../rustc_parse/src/parser/diagnostics.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f0a053d88b5db..e8dc0b3a68436 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -242,6 +242,16 @@ impl MultiSugg { err.multipart_suggestions(msg, suggestions.map(|s| s.patches), applicability); } } + +#[derive(SessionDiagnostic)] +#[error(slug = "parser-maybe-report-ambiguous-plus")] +struct AmbiguousPlus { + pub sum_with_parens: String, + #[primary_span] + #[suggestion(code = "({sum_with_parens})")] + pub span: Span, +} + // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1171,15 +1181,6 @@ impl<'a> Parser<'a> { impl_dyn_multi: bool, ty: &Ty, ) { - #[derive(SessionDiagnostic)] - #[error(slug = "parser-maybe-report-ambiguous-plus")] - struct AmbiguousPlus { - pub sum_with_parens: String, - #[primary_span] - #[suggestion(code = "({sum_with_parens})")] - pub span: Span, - } - if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi { self.sess.emit_err(AmbiguousPlus { sum_with_parens: pprust::ty_to_string(&ty), From 1e35bab1047a9969e363d55159c466f965e7c726 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 26 Apr 2022 11:13:23 +0200 Subject: [PATCH 09/14] separate messages by a newline --- compiler/rustc_error_messages/locales/en-US/parser.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index fd7daadb1ab42..3143b81b6098f 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -1,6 +1,7 @@ parser-struct-literal-body-without-path = struct literal body without path .suggestion = you might have forgotten to add the struct literal inside the block + parser-maybe-report-ambiguous-plus = ambiguous `+` in a type .suggestion = use parentheses to disambiguate From e7ae9eb3f272a96c2c73363539ca31986e5d5e88 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 27 Apr 2022 12:03:16 +0200 Subject: [PATCH 10/14] rename `sum_with_parens` --- compiler/rustc_parse/src/parser/diagnostics.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e8dc0b3a68436..4edc9b39efcc7 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -246,9 +246,9 @@ impl MultiSugg { #[derive(SessionDiagnostic)] #[error(slug = "parser-maybe-report-ambiguous-plus")] struct AmbiguousPlus { - pub sum_with_parens: String, + pub sum_ty: String, #[primary_span] - #[suggestion(code = "({sum_with_parens})")] + #[suggestion(code = "({sum_ty})")] pub span: Span, } @@ -1182,10 +1182,7 @@ impl<'a> Parser<'a> { ty: &Ty, ) { if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi { - self.sess.emit_err(AmbiguousPlus { - sum_with_parens: pprust::ty_to_string(&ty), - span: ty.span, - }); + self.sess.emit_err(AmbiguousPlus { sum_ty: pprust::ty_to_string(&ty), span: ty.span }); } } From 332f326334b256477d252c1927524cbdb1eb6048 Mon Sep 17 00:00:00 2001 From: Simon <48656638+user-simon@users.noreply.github.com> Date: Wed, 27 Apr 2022 17:27:02 +0200 Subject: [PATCH 11/14] Fixed grammatical error in example comment --- library/core/src/iter/sources/repeat_with.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/sources/repeat_with.rs b/library/core/src/iter/sources/repeat_with.rs index 44bc6890c55b5..6f62662d88066 100644 --- a/library/core/src/iter/sources/repeat_with.rs +++ b/library/core/src/iter/sources/repeat_with.rs @@ -27,7 +27,7 @@ use crate::iter::{FusedIterator, TrustedLen}; /// use std::iter; /// /// // let's assume we have some value of a type that is not `Clone` -/// // or which don't want to have in memory just yet because it is expensive: +/// // or which we don't want to have in memory just yet because it is expensive: /// #[derive(PartialEq, Debug)] /// struct Expensive; /// From 2c9421823815cd6ce91afef0b4c7580483863416 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Tue, 26 Apr 2022 00:17:25 +0200 Subject: [PATCH 12/14] Recover suggestions to introduce named lifetime under NLL --- .../src/diagnostics/region_errors.rs | 35 ++++- .../nice_region_error/different_lifetimes.rs | 148 +++++++++--------- .../nice_region_error/find_anon_type.rs | 2 +- .../error_reporting/nice_region_error/mod.rs | 2 + .../issue-90170-elision-mismatch.nll.stderr | 15 ++ .../ex3-both-anon-regions-2.nll.stderr | 5 + .../ex3-both-anon-regions-3.nll.stderr | 10 ++ ...non-regions-return-type-is-anon.nll.stderr | 5 + ...-both-anon-regions-self-is-anon.nll.stderr | 5 + ...oth-anon-regions-using-fn-items.nll.stderr | 5 + ...h-anon-regions-using-impl-items.nll.stderr | 5 + ...non-regions-using-trait-objects.nll.stderr | 5 + .../ex3-both-anon-regions.nll.stderr | 5 + ...elf_types_pin_lifetime_mismatch.nll.stderr | 10 ++ .../ui/self/elision/lt-ref-self.nll.stderr | 30 ++++ .../ui/self/elision/ref-mut-self.nll.stderr | 30 ++++ .../ui/self/elision/ref-mut-struct.nll.stderr | 25 +++ src/test/ui/self/elision/ref-self.nll.stderr | 35 +++++ .../ui/self/elision/ref-struct.nll.stderr | 25 +++ ...rscore-lifetime-elison-mismatch.nll.stderr | 5 + 20 files changed, 331 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index b5ee4a5edce7d..30fe4ea8662eb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -2,7 +2,10 @@ use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_infer::infer::{ - error_reporting::nice_region_error::{self, find_param_with_region, NiceRegionError}, + error_reporting::nice_region_error::{ + self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params, + NiceRegionError, + }, error_reporting::unexpected_hidden_region_diagnostic, NllRegionVariableOrigin, RelateParamBound, }; @@ -630,6 +633,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); + self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); diag } @@ -694,4 +698,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); } } + + fn suggest_adding_lifetime_params( + &self, + diag: &mut Diagnostic, + sub: RegionVid, + sup: RegionVid, + ) { + let (Some(sub), Some(sup)) = (self.to_error_region(sub), self.to_error_region(sup)) else { + return + }; + + let Some((ty_sub, _)) = self + .infcx + .tcx + .is_suitable_region(sub) + .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sub, &anon_reg.boundregion)) else { + return + }; + + let Some((ty_sup, _)) = self + .infcx + .tcx + .is_suitable_region(sup) + .and_then(|anon_reg| find_anon_type(self.infcx.tcx, sup, &anon_reg.boundregion)) else { + return + }; + + suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag); + } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 7721e00c141d7..be9db6aa25b75 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -6,6 +6,7 @@ use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::SubregionOrigin; +use crate::infer::TyCtxt; use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; @@ -145,84 +146,83 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } - self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err); + if suggest_adding_lifetime_params(self.tcx(), sub, ty_sup, ty_sub, &mut err) { + err.note("each elided lifetime in input position becomes a distinct lifetime"); + } let reported = err.emit(); Some(reported) } +} - fn suggest_adding_lifetime_params( - &self, - sub: Region<'tcx>, - ty_sup: &Ty<'_>, - ty_sub: &Ty<'_>, - err: &mut Diagnostic, - ) { - if let ( - hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. }, - hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. }, - ) = (ty_sub, ty_sup) - { - if lifetime_sub.name.is_elided() && lifetime_sup.name.is_elided() { - if let Some(anon_reg) = self.tcx().is_suitable_region(sub) { - let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id); - - let node = self.tcx().hir().get(hir_id); - let is_impl = matches!(&node, hir::Node::ImplItem(_)); - let generics = match node { - hir::Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(_, ref generics, ..), - .. - }) - | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) - | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics, - _ => return, - }; - - let (suggestion_param_name, introduce_new) = generics - .params - .iter() - .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) - .and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok()) - .map(|name| (name, false)) - .unwrap_or_else(|| ("'a".to_string(), true)); - - let mut suggestions = vec![ - if let hir::LifetimeName::Underscore = lifetime_sub.name { - (lifetime_sub.span, suggestion_param_name.clone()) - } else { - (lifetime_sub.span.shrink_to_hi(), suggestion_param_name.clone() + " ") - }, - if let hir::LifetimeName::Underscore = lifetime_sup.name { - (lifetime_sup.span, suggestion_param_name.clone()) - } else { - (lifetime_sup.span.shrink_to_hi(), suggestion_param_name.clone() + " ") - }, - ]; - - if introduce_new { - let new_param_suggestion = match &generics.params { - [] => (generics.span, format!("<{}>", suggestion_param_name)), - [first, ..] => { - (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) - } - }; - - suggestions.push(new_param_suggestion); - } - - let mut sugg = String::from("consider introducing a named lifetime parameter"); - if is_impl { - sugg.push_str(" and update trait if needed"); - } - err.multipart_suggestion( - sugg.as_str(), - suggestions, - Applicability::MaybeIncorrect, - ); - err.note("each elided lifetime in input position becomes a distinct lifetime"); - } - } - } +pub fn suggest_adding_lifetime_params<'tcx>( + tcx: TyCtxt<'tcx>, + sub: Region<'tcx>, + ty_sup: &Ty<'_>, + ty_sub: &Ty<'_>, + err: &mut Diagnostic, +) -> bool { + let ( + hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. }, + hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. }, + ) = (ty_sub, ty_sup) else { + return false; + }; + + if !lifetime_sub.name.is_elided() || !lifetime_sup.name.is_elided() { + return false; + }; + + let Some(anon_reg) = tcx.is_suitable_region(sub) else { + return false; + }; + + let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id); + + let node = tcx.hir().get(hir_id); + let is_impl = matches!(&node, hir::Node::ImplItem(_)); + let generics = match node { + hir::Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, ref generics, ..), .. }) + | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) + | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics, + _ => return false, + }; + + let (suggestion_param_name, introduce_new) = generics + .params + .iter() + .find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) + .and_then(|p| tcx.sess.source_map().span_to_snippet(p.span).ok()) + .map(|name| (name, false)) + .unwrap_or_else(|| ("'a".to_string(), true)); + + let mut suggestions = vec![ + if let hir::LifetimeName::Underscore = lifetime_sub.name { + (lifetime_sub.span, suggestion_param_name.clone()) + } else { + (lifetime_sub.span.shrink_to_hi(), suggestion_param_name.clone() + " ") + }, + if let hir::LifetimeName::Underscore = lifetime_sup.name { + (lifetime_sup.span, suggestion_param_name.clone()) + } else { + (lifetime_sup.span.shrink_to_hi(), suggestion_param_name.clone() + " ") + }, + ]; + + if introduce_new { + let new_param_suggestion = match &generics.params { + [] => (generics.span, format!("<{}>", suggestion_param_name)), + [first, ..] => (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)), + }; + + suggestions.push(new_param_suggestion); } + + let mut sugg = String::from("consider introducing a named lifetime parameter"); + if is_impl { + sugg.push_str(" and update trait if needed"); + } + err.multipart_suggestion(sugg.as_str(), suggestions, Applicability::MaybeIncorrect); + + true } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index 135714af2a6c1..da4c2b41f09c3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{self, Region, TyCtxt}; /// ``` /// The function returns the nested type corresponding to the anonymous region /// for e.g., `&u8` and `Vec<&u8>`. -pub(crate) fn find_anon_type<'tcx>( +pub fn find_anon_type<'tcx>( tcx: TyCtxt<'tcx>, region: Region<'tcx>, br: &ty::BoundRegionKind, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 79f852d8a95e7..9948d15c43115 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -14,6 +14,8 @@ mod static_impl_trait; mod trait_impl_difference; mod util; +pub use different_lifetimes::suggest_adding_lifetime_params; +pub use find_anon_type::find_anon_type; pub use static_impl_trait::suggest_new_region_bound; pub use util::find_param_with_region; diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr b/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr index a5bc7450bbff0..48fb3fb4a2293 100644 --- a/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr +++ b/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/issue-90170-elision-mismatch.rs:5:44 @@ -15,6 +20,11 @@ LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ~~ ++ error: lifetime may not live long enough --> $DIR/issue-90170-elision-mismatch.rs:7:63 @@ -24,6 +34,11 @@ LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++ ++ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr index a94f9a799061a..5a23f1e0e9d99 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { | let's call the lifetime of this reference `'2` LL | *v = x; | ^^^^^^ assignment requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr index 2ed4d6d4401aa..6ba130308a33a 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | let's call the lifetime of this reference `'2` LL | z.push((x,y)); | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-3.rs:2:5 @@ -17,6 +22,11 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | let's call the lifetime of this reference `'4` LL | z.push((x,y)); | ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) { + | ++++ ++ ++ error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr index 1a19e81f235ba..5601335d275c3 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo<'a>(&self, x: &i32) -> &i32 { | let's call the lifetime of this reference `'2` LL | x | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { + | ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr index 87b13dc15914b..e221902c4a907 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | let's call the lifetime of this reference `'2` LL | if true { x } else { self } | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo { + | ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr index 825c45b243441..a909c5fa82351 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { | let's call the lifetime of this reference `'2` LL | y.push(z); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) { + | ++++ ++ ++ error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr index f3502674849ef..9661f1e5144b4 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | let's call the lifetime of this reference `'2` LL | x.push(y); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr index 78a828dde866f..cce0a31bfbbf1 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x:Box , y: Vec<&u8>, z: &u8) { | let's call the lifetime of this reference `'2` LL | y.push(z); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x:Box , y: Vec<&u8>, z: &u8) { + | ++++ ++ ++ error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr index 6989acfa1963b..ec9fac0c288e0 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | let's call the lifetime of this reference `'2` LL | x.push(y); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr index b06ebf7047737..057146e7cb0ad 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:14:69 @@ -15,6 +20,11 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:21:58 diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr index 1934207527b9c..2e26c703b6573 100644 --- a/src/test/ui/self/elision/lt-ref-self.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:23:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:29:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:35:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:41:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:47:9 @@ -57,6 +82,11 @@ LL | fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr index f1f4d341b2bd8..fd4ecae3cfe32 100644 --- a/src/test/ui/self/elision/ref-mut-self.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&mut self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:23:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:29:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:35:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:41:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:47:9 @@ -57,6 +82,11 @@ LL | fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr index de7eb02d7a7fe..ede790c061143 100644 --- a/src/test/ui/self/elision/ref-mut-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:21:9 @@ -17,6 +22,11 @@ LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:27:9 @@ -27,6 +37,11 @@ LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:33:9 @@ -37,6 +52,11 @@ LL | fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:39:9 @@ -47,6 +67,11 @@ LL | fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr index f2b7b0ad01957..c0efc35fa6c8e 100644 --- a/src/test/ui/self/elision/ref-self.nll.stderr +++ b/src/test/ui/self/elision/ref-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:33:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:39:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:45:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:51:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:57:9 @@ -57,6 +82,11 @@ LL | fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Self<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:63:9 @@ -67,6 +97,11 @@ LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 { + | ++++ ++ ++ error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr index 70453b0ddfc71..226923f59ff37 100644 --- a/src/test/ui/self/elision/ref-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-struct.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:21:9 @@ -17,6 +22,11 @@ LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:27:9 @@ -27,6 +37,11 @@ LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:33:9 @@ -37,6 +52,11 @@ LL | fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:39:9 @@ -47,6 +67,11 @@ LL | fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_Struct<'a>(self: Box>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr index 8e10242cb1331..a4dece320ec26 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ~~ ~~ error: aborting due to previous error From d9240d72ea2f050c45b1772e6de005a1ee4aed47 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Fri, 25 Mar 2022 18:26:55 +0100 Subject: [PATCH 13/14] Ensure that `'_` and GAT yields errors --- .../generic-associated-types/issue-95305.rs | 17 +++++++++++++ .../issue-95305.stderr | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/test/ui/generic-associated-types/issue-95305.rs create mode 100644 src/test/ui/generic-associated-types/issue-95305.stderr diff --git a/src/test/ui/generic-associated-types/issue-95305.rs b/src/test/ui/generic-associated-types/issue-95305.rs new file mode 100644 index 0000000000000..9ead347984b0c --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-95305.rs @@ -0,0 +1,17 @@ +// It's not yet clear how '_ and GATs should interact. +// Forbid it for now but proper support might be added +// at some point in the future. + +#![feature(generic_associated_types)] + +trait Foo { + type Item<'a>; +} + +fn foo(x: &impl Foo = u32>) { } + //~^ ERROR missing lifetime specifier + +fn bar(x: &impl for<'a> Foo = &'_ u32>) { } + //~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-95305.stderr b/src/test/ui/generic-associated-types/issue-95305.stderr new file mode 100644 index 0000000000000..2b48378dc4350 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-95305.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/issue-95305.rs:11:26 + | +LL | fn foo(x: &impl Foo = u32>) { } + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &impl Foo = u32>) { } + | ++++ ~~ + +error[E0106]: missing lifetime specifier + --> $DIR/issue-95305.rs:14:41 + | +LL | fn bar(x: &impl for<'a> Foo = &'_ u32>) { } + | ^^ expected named lifetime parameter + | +help: consider using the `'a` lifetime + | +LL | fn bar(x: &impl for<'a> Foo = &'a u32>) { } + | ~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. From 2733ec1be34b1ae9f22c70c901bb89229adf9def Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 26 Apr 2022 15:40:14 +0300 Subject: [PATCH 14/14] rustc_ast: Harmonize delimiter naming with `proc_macro::Delimiter` --- compiler/rustc_ast/src/ast.rs | 22 ++--- compiler/rustc_ast/src/attr/mod.rs | 10 +-- compiler/rustc_ast/src/token.rs | 43 +++++---- compiler/rustc_ast/src/tokenstream.rs | 8 +- compiler/rustc_ast_lowering/src/lib.rs | 4 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 28 +++--- compiler/rustc_builtin_macros/src/asm.rs | 20 ++--- compiler/rustc_expand/src/config.rs | 4 +- compiler/rustc_expand/src/expand.rs | 4 +- compiler/rustc_expand/src/mbe.rs | 8 +- compiler/rustc_expand/src/mbe/macro_check.rs | 8 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 6 +- compiler/rustc_expand/src/mbe/metavar_expr.rs | 4 +- compiler/rustc_expand/src/mbe/quoted.rs | 12 +-- compiler/rustc_expand/src/mbe/transcribe.rs | 25 ++---- compiler/rustc_expand/src/parse/tests.rs | 14 +-- .../rustc_expand/src/proc_macro_server.rs | 30 +++---- compiler/rustc_parse/src/lexer/mod.rs | 18 ++-- compiler/rustc_parse/src/lexer/tokentrees.rs | 12 +-- .../rustc_parse/src/lexer/unicode_chars.rs | 14 +-- compiler/rustc_parse/src/parser/attr.rs | 8 +- .../rustc_parse/src/parser/attr_wrapper.rs | 28 +++--- .../rustc_parse/src/parser/diagnostics.rs | 85 +++++++++--------- compiler/rustc_parse/src/parser/expr.rs | 90 ++++++++++--------- compiler/rustc_parse/src/parser/item.rs | 85 +++++++++--------- compiler/rustc_parse/src/parser/mod.rs | 52 +++++------ .../rustc_parse/src/parser/nonterminal.rs | 8 +- compiler/rustc_parse/src/parser/pat.rs | 30 +++---- compiler/rustc_parse/src/parser/path.rs | 11 +-- compiler/rustc_parse/src/parser/stmt.rs | 16 ++-- compiler/rustc_parse/src/parser/ty.rs | 28 +++--- compiler/rustc_session/src/utils.rs | 4 +- library/proc_macro/src/lib.rs | 4 +- src/librustdoc/clean/render_macro_matchers.rs | 12 +-- src/test/ui/proc-macro/nodelim-groups.rs | 2 +- src/tools/rustfmt/src/expr.rs | 4 +- src/tools/rustfmt/src/macros.rs | 70 +++++++-------- src/tools/rustfmt/src/overflow.rs | 8 +- src/tools/rustfmt/src/parse/macros/cfg_if.rs | 8 +- src/tools/rustfmt/src/parse/macros/mod.rs | 8 +- src/tools/rustfmt/src/visitor.rs | 4 +- 41 files changed, 433 insertions(+), 426 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4233f7806248b..a310828b9fbfa 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -23,7 +23,7 @@ pub use GenericArgs::*; pub use UnsafeSource::*; use crate::ptr::P; -use crate::token::{self, CommentKind, DelimToken, Token}; +use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -1542,7 +1542,7 @@ pub enum MacArgs { } impl MacArgs { - pub fn delim(&self) -> Option { + pub fn delim(&self) -> Option { match self { MacArgs::Delimited(_, delim, _) => Some(delim.to_token()), MacArgs::Empty | MacArgs::Eq(..) => None, @@ -1582,20 +1582,20 @@ pub enum MacDelimiter { } impl MacDelimiter { - pub fn to_token(self) -> DelimToken { + pub fn to_token(self) -> Delimiter { match self { - MacDelimiter::Parenthesis => DelimToken::Paren, - MacDelimiter::Bracket => DelimToken::Bracket, - MacDelimiter::Brace => DelimToken::Brace, + MacDelimiter::Parenthesis => Delimiter::Parenthesis, + MacDelimiter::Bracket => Delimiter::Bracket, + MacDelimiter::Brace => Delimiter::Brace, } } - pub fn from_token(delim: DelimToken) -> Option { + pub fn from_token(delim: Delimiter) -> Option { match delim { - token::Paren => Some(MacDelimiter::Parenthesis), - token::Bracket => Some(MacDelimiter::Bracket), - token::Brace => Some(MacDelimiter::Brace), - token::NoDelim => None, + Delimiter::Parenthesis => Some(MacDelimiter::Parenthesis), + Delimiter::Bracket => Some(MacDelimiter::Bracket), + Delimiter::Brace => Some(MacDelimiter::Brace), + Delimiter::Invisible => None, } } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 9a6d12faa605d..b14367aa1c2c2 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -5,7 +5,7 @@ use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; use crate::ast::{Lit, LitKind}; use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Path, PathSegment}; -use crate::token::{self, CommentKind, Token}; +use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree, TreeAndSpacing}; use crate::tokenstream::{LazyTokenStream, TokenStream}; @@ -513,7 +513,7 @@ impl MetaItemKind { vec![ TokenTree::Delimited( DelimSpan::from_single(span), - token::Paren, + Delimiter::Parenthesis, TokenStream::new(tokens), ) .into(), @@ -540,7 +540,7 @@ impl MetaItemKind { tokens: &mut impl Iterator, ) -> Option { match tokens.next() { - Some(TokenTree::Delimited(_, token::NoDelim, inner_tokens)) => { + Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { MetaItemKind::name_value_from_tokens(&mut inner_tokens.trees()) } Some(TokenTree::Token(token)) => { @@ -565,7 +565,7 @@ impl MetaItemKind { tokens: &mut iter::Peekable>, ) -> Option { match tokens.peek() { - Some(TokenTree::Delimited(_, token::Paren, inner_tokens)) => { + Some(TokenTree::Delimited(_, Delimiter::Parenthesis, inner_tokens)) => { let inner_tokens = inner_tokens.clone(); tokens.next(); MetaItemKind::list_from_tokens(inner_tokens) @@ -606,7 +606,7 @@ impl NestedMetaItem { tokens.next(); return Some(NestedMetaItem::Literal(lit)); } - Some(TokenTree::Delimited(_, token::NoDelim, inner_tokens)) => { + Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => { let inner_tokens = inner_tokens.clone(); tokens.next(); return NestedMetaItem::from_tokens(&mut inner_tokens.into_trees().peekable()); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 5aa8011ca5eb6..1589a882f0892 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -1,5 +1,4 @@ pub use BinOpToken::*; -pub use DelimToken::*; pub use LitKind::*; pub use Nonterminal::*; pub use TokenKind::*; @@ -37,18 +36,26 @@ pub enum BinOpToken { Shr, } -/// A delimiter token. -#[derive(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, Copy)] -#[derive(HashStable_Generic)] -pub enum DelimToken { - /// A round parenthesis (i.e., `(` or `)`). - Paren, - /// A square bracket (i.e., `[` or `]`). - Bracket, - /// A curly brace (i.e., `{` or `}`). +/// Describes how a sequence of token trees is delimited. +/// Cannot use `proc_macro::Delimiter` directly because this +/// structure should implement some additional traits. +/// The `None` variant is also renamed to `Invisible` to be +/// less confusing and better convey the semantics. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Encodable, Decodable, Hash, HashStable_Generic)] +pub enum Delimiter { + /// `( ... )` + Parenthesis, + /// `{ ... }` Brace, - /// An empty delimiter. - NoDelim, + /// `[ ... ]` + Bracket, + /// `Ø ... Ø` + /// An invisible delimiter, that may, for example, appear around tokens coming from a + /// "macro variable" `$var`. It is important to preserve operator priorities in cases like + /// `$var * 3` where `$var` is `1 + 2`. + /// Invisible delimiters might not survive roundtrip of a token stream through a string. + Invisible, } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] @@ -212,9 +219,9 @@ pub enum TokenKind { /// Used by proc macros for representing lifetimes, not generated by lexer right now. SingleQuote, /// An opening delimiter (e.g., `{`). - OpenDelim(DelimToken), + OpenDelim(Delimiter), /// A closing delimiter (e.g., `}`). - CloseDelim(DelimToken), + CloseDelim(Delimiter), /* Literals */ Literal(Lit), @@ -387,8 +394,8 @@ impl Token { match self.uninterpolate().kind { Ident(name, is_raw) => ident_can_begin_type(name, self.span, is_raw), // type name or keyword - OpenDelim(Paren) | // tuple - OpenDelim(Bracket) | // array + OpenDelim(Delimiter::Parenthesis) | // tuple + OpenDelim(Delimiter::Bracket) | // array Not | // never BinOp(Star) | // raw pointer BinOp(And) | // reference @@ -405,7 +412,7 @@ impl Token { /// Returns `true` if the token can appear at the start of a const param. pub fn can_begin_const_arg(&self) -> bool { match self.kind { - OpenDelim(Brace) => true, + OpenDelim(Delimiter::Brace) => true, Interpolated(ref nt) => matches!(**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), _ => self.can_begin_literal_maybe_minus(), } @@ -417,7 +424,7 @@ impl Token { || self.is_lifetime() || self.is_keyword(kw::For) || self == &Question - || self == &OpenDelim(Paren) + || self == &OpenDelim(Delimiter::Parenthesis) } /// Returns `true` if the token is any literal. diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index d609fa6720502..a8f29f334070e 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -13,7 +13,7 @@ //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. -use crate::token::{self, DelimToken, Token, TokenKind}; +use crate::token::{self, Delimiter, Token, TokenKind}; use crate::AttrVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -42,7 +42,7 @@ pub enum TokenTree { /// A single token. Token(Token), /// A delimited sequence of token trees. - Delimited(DelimSpan, DelimToken, TokenStream), + Delimited(DelimSpan, Delimiter, TokenStream), } #[derive(Copy, Clone)] @@ -57,7 +57,7 @@ fn _dummy() where Token: Send + Sync, DelimSpan: Send + Sync, - DelimToken: Send + Sync, + Delimiter: Send + Sync, TokenStream: Send + Sync, { } @@ -175,7 +175,7 @@ pub struct AttrAnnotatedTokenStream(pub Lrc LoweringContext<'a, 'hir> { match tokens.into_trees().next() { Some(TokenTree::Token(token)) => token, Some(TokenTree::Delimited(_, delim, tokens)) => { - if delim != token::NoDelim { + if delim != Delimiter::Invisible { sess.diagnostic().delay_span_bug( span, "unexpected delimiter in key-value attribute's value", diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 39824095e8663..a2ebe3048ceee 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -6,7 +6,7 @@ use crate::pp::Breaks::{Consistent, Inconsistent}; use crate::pp::{self, Breaks}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, BinOpToken, CommentKind, DelimToken, Nonterminal, Token, TokenKind}; +use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; @@ -155,10 +155,10 @@ fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool { } match tt { TokenTree::Token(token) => !matches!(token.kind, token::Comma | token::Not | token::Dot), - TokenTree::Delimited(_, DelimToken::Paren, _) => { + TokenTree::Delimited(_, Delimiter::Parenthesis, _) => { !matches!(prev, TokenTree::Token(Token { kind: token::Ident(..), .. })) } - TokenTree::Delimited(_, DelimToken::Bracket, _) => { + TokenTree::Delimited(_, Delimiter::Bracket, _) => { !matches!(prev, TokenTree::Token(Token { kind: token::Pound, .. })) } TokenTree::Delimited(..) => true, @@ -556,12 +556,12 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere header: Option>, has_bang: bool, ident: Option, - delim: Option, + delim: Option, tts: &TokenStream, convert_dollar_crate: bool, span: Span, ) { - if delim == Some(DelimToken::Brace) { + if delim == Some(Delimiter::Brace) { self.cbox(INDENT_UNIT); } match header { @@ -577,7 +577,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.print_ident(ident); } match delim { - Some(DelimToken::Brace) => { + Some(Delimiter::Brace) => { if header.is_some() || has_bang || ident.is_some() { self.nbsp(); } @@ -758,13 +758,15 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::RArrow => "->".into(), token::LArrow => "<-".into(), token::FatArrow => "=>".into(), - token::OpenDelim(token::Paren) => "(".into(), - token::CloseDelim(token::Paren) => ")".into(), - token::OpenDelim(token::Bracket) => "[".into(), - token::CloseDelim(token::Bracket) => "]".into(), - token::OpenDelim(token::Brace) => "{".into(), - token::CloseDelim(token::Brace) => "}".into(), - token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => "".into(), + token::OpenDelim(Delimiter::Parenthesis) => "(".into(), + token::CloseDelim(Delimiter::Parenthesis) => ")".into(), + token::OpenDelim(Delimiter::Bracket) => "[".into(), + token::CloseDelim(Delimiter::Bracket) => "]".into(), + token::OpenDelim(Delimiter::Brace) => "{".into(), + token::CloseDelim(Delimiter::Brace) => "}".into(), + token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) => { + "".into() + } token::Pound => "#".into(), token::Dollar => "$".into(), token::Question => "?".into(), diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 030295d3d8dc3..e9e3307ca95da 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -1,6 +1,6 @@ use rustc_ast as ast; use rustc_ast::ptr::P; -use rustc_ast::token; +use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Applicability, PResult}; @@ -395,9 +395,9 @@ fn parse_options<'a>( ) -> PResult<'a, ()> { let span_start = p.prev_token.span; - p.expect(&token::OpenDelim(token::DelimToken::Paren))?; + p.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - while !p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { if !is_global_asm && p.eat_keyword(sym::pure) { try_set_option(p, args, sym::pure, ast::InlineAsmOptions::PURE); } else if !is_global_asm && p.eat_keyword(sym::nomem) { @@ -421,7 +421,7 @@ fn parse_options<'a>( } // Allow trailing commas - if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { break; } p.expect(&token::Comma)?; @@ -436,9 +436,9 @@ fn parse_options<'a>( fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, ()> { let span_start = p.prev_token.span; - p.expect(&token::OpenDelim(token::DelimToken::Paren))?; + p.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { let err = p.sess.span_diagnostic.struct_span_err( p.token.span, "at least one abi must be provided as an argument to `clobber_abi`", @@ -454,7 +454,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, } Err(opt_lit) => { // If the non-string literal is a closing paren then it's the end of the list and is fine - if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { break; } let span = opt_lit.map_or(p.token.span, |lit| lit.span); @@ -466,7 +466,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, }; // Allow trailing commas - if p.eat(&token::CloseDelim(token::DelimToken::Paren)) { + if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) { break; } p.expect(&token::Comma)?; @@ -501,7 +501,7 @@ fn parse_reg<'a>( p: &mut Parser<'a>, explicit_reg: &mut bool, ) -> PResult<'a, ast::InlineAsmRegOrRegClass> { - p.expect(&token::OpenDelim(token::DelimToken::Paren))?; + p.expect(&token::OpenDelim(Delimiter::Parenthesis))?; let result = match p.token.uninterpolate().kind { token::Ident(name, false) => ast::InlineAsmRegOrRegClass::RegClass(name), token::Literal(token::Lit { kind: token::LitKind::Str, symbol, suffix: _ }) => { @@ -515,7 +515,7 @@ fn parse_reg<'a>( } }; p.bump(); - p.expect(&token::CloseDelim(token::DelimToken::Paren))?; + p.expect(&token::CloseDelim(Delimiter::Parenthesis))?; Ok(result) } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index fa628cd9ebd0b..a9c7ba5d072d2 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -1,7 +1,7 @@ //! Conditional compilation stripping. use rustc_ast::ptr::P; -use rustc_ast::token::{DelimToken, Token, TokenKind}; +use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; use rustc_ast::tokenstream::{DelimSpan, Spacing}; use rustc_ast::tokenstream::{LazyTokenStream, TokenTree}; @@ -418,7 +418,7 @@ impl<'a> StripUnconfigured<'a> { // in `#[attr]`, so just use the span of the `#` token. let bracket_group = AttrAnnotatedTokenTree::Delimited( DelimSpan::from_single(pound_span), - DelimToken::Bracket, + Delimiter::Bracket, item.tokens .as_ref() .unwrap_or_else(|| panic!("Missing tokens for {:?}", item)) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 9b224a733568b..5bd89f3f42fa5 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -8,7 +8,7 @@ use crate::placeholders::{placeholder, PlaceholderExpander}; use rustc_ast as ast; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; -use rustc_ast::token; +use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::{AssocItemKind, AstLike, AstLikeWrapper, AttrStyle, ExprKind, ForeignItemKind}; @@ -884,7 +884,7 @@ pub fn parse_ast_fragment<'a>( AstFragmentKind::Stmts => { let mut stmts = SmallVec::new(); // Won't make progress on a `}`. - while this.token != token::Eof && this.token != token::CloseDelim(token::Brace) { + while this.token != token::Eof && this.token != token::CloseDelim(Delimiter::Brace) { if let Some(stmt) = this.parse_full_stmt(AttemptLocalParseRecovery::Yes)? { stmts.push(stmt); } diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index a5b8571fefe54..36295da74adc5 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -11,16 +11,16 @@ crate mod quoted; crate mod transcribe; use metavar_expr::MetaVarExpr; -use rustc_ast::token::{self, NonterminalKind, Token, TokenKind}; +use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind}; use rustc_ast::tokenstream::DelimSpan; use rustc_span::symbol::Ident; use rustc_span::Span; -/// Contains the sub-token-trees of a "delimited" token tree such as `(a b c)`. The delimiters -/// might be `NoDelim`, but they are not represented explicitly. +/// Contains the sub-token-trees of a "delimited" token tree such as `(a b c)`. +/// The delimiters are not represented explicitly in the `tts` vector. #[derive(PartialEq, Encodable, Decodable, Debug)] struct Delimited { - delim: token::DelimToken, + delim: Delimiter, /// FIXME: #67062 has details about why this is sub-optimal. tts: Vec, } diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index c6a6e3d125f70..35b5e0d0f2f61 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -106,7 +106,7 @@ //! bound. use crate::mbe::{KleeneToken, TokenTree}; -use rustc_ast::token::{DelimToken, Token, TokenKind}; +use rustc_ast::token::{Delimiter, Token, TokenKind}; use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::MultiSpan; @@ -439,7 +439,7 @@ fn check_nested_occurrences( } (NestedMacroState::MacroRulesNotName, &TokenTree::Delimited(_, ref del)) | (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) - if del.delim == DelimToken::Brace => + if del.delim == Delimiter::Brace => { let macro_rules = state == NestedMacroState::MacroRulesNotName; state = NestedMacroState::Empty; @@ -469,7 +469,7 @@ fn check_nested_occurrences( check_occurrences(sess, node_id, tt, macros, binders, ops, valid); } (NestedMacroState::MacroName, &TokenTree::Delimited(_, ref del)) - if del.delim == DelimToken::Paren => + if del.delim == Delimiter::Parenthesis => { state = NestedMacroState::MacroNameParen; nested_binders = Binders::default(); @@ -484,7 +484,7 @@ fn check_nested_occurrences( ); } (NestedMacroState::MacroNameParen, &TokenTree::Delimited(_, ref del)) - if del.delim == DelimToken::Brace => + if del.delim == Delimiter::Brace => { state = NestedMacroState::Empty; check_occurrences( diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index f3dcdbf93c5f1..050710097c331 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -8,7 +8,7 @@ use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc}; use crate::mbe::transcribe::transcribe; use rustc_ast as ast; -use rustc_ast::token::{self, NonterminalKind, Token, TokenKind, TokenKind::*}; +use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*}; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; @@ -1250,8 +1250,8 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { ]; match tok { TokenTree::Token(token) => match token.kind { - OpenDelim(token::DelimToken::Brace) - | OpenDelim(token::DelimToken::Bracket) + OpenDelim(Delimiter::Brace) + | OpenDelim(Delimiter::Bracket) | Comma | FatArrow | Colon diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 52a656e1d1c14..cdc5e204236fb 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -1,4 +1,4 @@ -use rustc_ast::token; +use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::{Cursor, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; use rustc_ast_pretty::pprust; @@ -35,7 +35,7 @@ impl MetaVarExpr { ) -> PResult<'sess, MetaVarExpr> { let mut tts = input.trees(); let ident = parse_ident(&mut tts, sess, outer_span)?; - let Some(TokenTree::Delimited(_, token::Paren, args)) = tts.next() else { + let Some(TokenTree::Delimited(_, Delimiter::Parenthesis, args)) = tts.next() else { let msg = "meta-variable expression parameter must be wrapped in parentheses"; return Err(sess.span_diagnostic.struct_span_err(ident.span, msg)); }; diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 0bce6967a10dd..d52de24c393b7 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -1,7 +1,7 @@ use crate::mbe::macro_parser::count_metavar_decls; use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree}; -use rustc_ast::token::{self, Token}; +use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::{tokenstream, NodeId}; use rustc_ast_pretty::pprust; use rustc_feature::Features; @@ -147,11 +147,11 @@ fn parse_tree( match tree { // `tree` is a `$` token. Look at the next token in `trees` tokenstream::TokenTree::Token(Token { kind: token::Dollar, span }) => { - // FIXME: Handle `None`-delimited groups in a more systematic way + // FIXME: Handle `Invisible`-delimited groups in a more systematic way // during parsing. let mut next = outer_trees.next(); let mut trees: Box>; - if let Some(tokenstream::TokenTree::Delimited(_, token::NoDelim, tts)) = next { + if let Some(tokenstream::TokenTree::Delimited(_, Delimiter::Invisible, tts)) = next { trees = Box::new(tts.into_trees()); next = trees.next(); } else { @@ -162,7 +162,7 @@ fn parse_tree( // `tree` is followed by a delimited set of token trees. Some(tokenstream::TokenTree::Delimited(delim_span, delim, tts)) => { if parsing_patterns { - if delim != token::Paren { + if delim != Delimiter::Parenthesis { span_dollar_dollar_or_metavar_in_the_lhs_err( sess, &Token { kind: token::OpenDelim(delim), span: delim_span.entire() }, @@ -170,7 +170,7 @@ fn parse_tree( } } else { match delim { - token::Brace => { + Delimiter::Brace => { // The delimiter is `{`. This indicates the beginning // of a meta-variable expression (e.g. `${count(ident)}`). // Try to parse the meta-variable expression. @@ -191,7 +191,7 @@ fn parse_tree( } } } - token::Paren => {} + Delimiter::Parenthesis => {} _ => { let tok = pprust::token_kind_to_string(&token::OpenDelim(delim)); let msg = format!("expected `(` or `{{`, found `{}`", tok); diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index d5b1913e1440c..94b6c3153ca30 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -2,7 +2,7 @@ use crate::base::ExtCtxt; use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch}; use crate::mbe::{self, MetaVarExpr}; use rustc_ast::mut_visit::{self, MutVisitor}; -use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, PResult}; @@ -27,23 +27,14 @@ impl MutVisitor for Marker { /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame<'a> { - Delimited { - tts: &'a [mbe::TokenTree], - idx: usize, - delim_token: token::DelimToken, - span: DelimSpan, - }, - Sequence { - tts: &'a [mbe::TokenTree], - idx: usize, - sep: Option, - }, + Delimited { tts: &'a [mbe::TokenTree], idx: usize, delim: Delimiter, span: DelimSpan }, + Sequence { tts: &'a [mbe::TokenTree], idx: usize, sep: Option }, } impl<'a> Frame<'a> { /// Construct a new frame around the delimited set of tokens. fn new(src: &'a mbe::Delimited, span: DelimSpan) -> Frame<'a> { - Frame::Delimited { tts: &src.tts, idx: 0, delim_token: src.delim, span } + Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span } } } @@ -150,14 +141,14 @@ pub(super) fn transcribe<'a>( // We are done processing a Delimited. If this is the top-level delimited, we are // done. Otherwise, we unwind the result_stack to append what we have produced to // any previous results. - Frame::Delimited { delim_token, span, .. } => { + Frame::Delimited { delim, span, .. } => { if result_stack.is_empty() { // No results left to compute! We are back at the top-level. return Ok(TokenStream::new(result)); } // Step back into the parent Delimited. - let tree = TokenTree::Delimited(span, delim_token, TokenStream::new(result)); + let tree = TokenTree::Delimited(span, delim, TokenStream::new(result)); result = result_stack.pop().unwrap(); result.push(tree.into()); } @@ -240,7 +231,7 @@ pub(super) fn transcribe<'a>( } MatchedNonterminal(ref nt) => { // Other variables are emitted into the output stream as groups with - // `Delimiter::None` to maintain parsing priorities. + // `Delimiter::Invisible` to maintain parsing priorities. // `Interpolated` is currently used for such groups in rustc parser. marker.visit_span(&mut sp); let token = TokenTree::token(token::Interpolated(nt.clone()), sp); @@ -278,7 +269,7 @@ pub(super) fn transcribe<'a>( mut_visit::visit_delim_span(&mut span, &mut marker); stack.push(Frame::Delimited { tts: &delimited.tts, - delim_token: delimited.delim, + delim: delimited.delim, idx: 0, span, }); diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 4a8236b2cf38d..5d447d911e7f4 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -1,7 +1,7 @@ use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token}; +use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::visit; use rustc_ast::{self as ast, PatKind}; @@ -77,13 +77,14 @@ fn string_to_tts_macro() { TokenTree::Delimited(_, first_delim, first_tts), TokenTree::Token(Token { kind: token::FatArrow, .. }), TokenTree::Delimited(_, second_delim, second_tts), - ] if macro_delim == &token::Paren => { + ] if macro_delim == &Delimiter::Parenthesis => { let tts = &first_tts.trees().collect::>(); match &tts[..] { [ TokenTree::Token(Token { kind: token::Dollar, .. }), TokenTree::Token(Token { kind: token::Ident(name, false), .. }), - ] if first_delim == &token::Paren && name.as_str() == "a" => {} + ] if first_delim == &Delimiter::Parenthesis && name.as_str() == "a" => { + } _ => panic!("value 3: {:?} {:?}", first_delim, first_tts), } let tts = &second_tts.trees().collect::>(); @@ -91,7 +92,8 @@ fn string_to_tts_macro() { [ TokenTree::Token(Token { kind: token::Dollar, .. }), TokenTree::Token(Token { kind: token::Ident(name, false), .. }), - ] if second_delim == &token::Paren && name.as_str() == "a" => {} + ] if second_delim == &Delimiter::Parenthesis + && name.as_str() == "a" => {} _ => panic!("value 4: {:?} {:?}", second_delim, second_tts), } } @@ -113,7 +115,7 @@ fn string_to_tts_1() { TokenTree::token(token::Ident(Symbol::intern("a"), false), sp(3, 4)).into(), TokenTree::Delimited( DelimSpan::from_pair(sp(5, 6), sp(13, 14)), - token::DelimToken::Paren, + Delimiter::Parenthesis, TokenStream::new(vec![ TokenTree::token(token::Ident(Symbol::intern("b"), false), sp(6, 7)).into(), TokenTree::token(token::Colon, sp(8, 9)).into(), @@ -124,7 +126,7 @@ fn string_to_tts_1() { .into(), TokenTree::Delimited( DelimSpan::from_pair(sp(15, 16), sp(20, 21)), - token::DelimToken::Brace, + Delimiter::Brace, TokenStream::new(vec![ TokenTree::token(token::Ident(Symbol::intern("b"), false), sp(17, 18)).into(), TokenTree::token(token::Semi, sp(18, 19)).into(), diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index bd6f0b77ebf6b..b7230cec3e4a9 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -28,24 +28,24 @@ trait ToInternal { fn to_internal(self) -> T; } -impl FromInternal for Delimiter { - fn from_internal(delim: token::DelimToken) -> Delimiter { +impl FromInternal for Delimiter { + fn from_internal(delim: token::Delimiter) -> Delimiter { match delim { - token::Paren => Delimiter::Parenthesis, - token::Brace => Delimiter::Brace, - token::Bracket => Delimiter::Bracket, - token::NoDelim => Delimiter::None, + token::Delimiter::Parenthesis => Delimiter::Parenthesis, + token::Delimiter::Brace => Delimiter::Brace, + token::Delimiter::Bracket => Delimiter::Bracket, + token::Delimiter::Invisible => Delimiter::None, } } } -impl ToInternal for Delimiter { - fn to_internal(self) -> token::DelimToken { +impl ToInternal for Delimiter { + fn to_internal(self) -> token::Delimiter { match self { - Delimiter::Parenthesis => token::Paren, - Delimiter::Brace => token::Brace, - Delimiter::Bracket => token::Bracket, - Delimiter::None => token::NoDelim, + Delimiter::Parenthesis => token::Delimiter::Parenthesis, + Delimiter::Brace => token::Delimiter::Brace, + Delimiter::Bracket => token::Delimiter::Bracket, + Delimiter::None => token::Delimiter::Invisible, } } } @@ -61,7 +61,7 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec, &mut Rustc<'_, '_>)> let joint = spacing == Joint; let Token { kind, span } = match tree { tokenstream::TokenTree::Delimited(span, delim, tts) => { - let delimiter = Delimiter::from_internal(delim); + let delimiter = pm::Delimiter::from_internal(delim); return TokenTree::Group(Group { delimiter, stream: tts, span, flatten: false }); } tokenstream::TokenTree::Token(token) => token, @@ -164,7 +164,7 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec, &mut Rustc<'_, '_>)> .map(|kind| tokenstream::TokenTree::token(kind, span)) .collect(); stack.push(TokenTree::Group(Group { - delimiter: Delimiter::Bracket, + delimiter: pm::Delimiter::Bracket, stream, span: DelimSpan::from_single(span), flatten: false, @@ -181,7 +181,7 @@ impl FromInternal<(TreeAndSpacing, &'_ mut Vec, &mut Rustc<'_, '_>)> Interpolated(nt) => { let stream = nt_to_tokenstream(&nt, rustc.sess(), CanSynthesizeMissingTokens::No); TokenTree::Group(Group { - delimiter: Delimiter::None, + delimiter: pm::Delimiter::None, stream, span: DelimSpan::from_single(span), flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess()), diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index bfa13ce79bab4..e585c61bf2ee1 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -1,6 +1,6 @@ use crate::lexer::unicode_chars::UNICODE_ARRAY; use rustc_ast::ast::{self, AttrStyle}; -use rustc_ast::token::{self, CommentKind, Token, TokenKind}; +use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{Spacing, TokenStream}; use rustc_ast::util::unicode::contains_text_flow_control_chars; use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; @@ -24,8 +24,8 @@ use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[derive(Clone, Debug)] pub struct UnmatchedBrace { - pub expected_delim: token::DelimToken, - pub found_delim: Option, + pub expected_delim: Delimiter, + pub found_delim: Option, pub found_span: Span, pub unclosed_span: Option, pub candidate_span: Option, @@ -284,12 +284,12 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::Semi => token::Semi, rustc_lexer::TokenKind::Comma => token::Comma, rustc_lexer::TokenKind::Dot => token::Dot, - rustc_lexer::TokenKind::OpenParen => token::OpenDelim(token::Paren), - rustc_lexer::TokenKind::CloseParen => token::CloseDelim(token::Paren), - rustc_lexer::TokenKind::OpenBrace => token::OpenDelim(token::Brace), - rustc_lexer::TokenKind::CloseBrace => token::CloseDelim(token::Brace), - rustc_lexer::TokenKind::OpenBracket => token::OpenDelim(token::Bracket), - rustc_lexer::TokenKind::CloseBracket => token::CloseDelim(token::Bracket), + rustc_lexer::TokenKind::OpenParen => token::OpenDelim(Delimiter::Parenthesis), + rustc_lexer::TokenKind::CloseParen => token::CloseDelim(Delimiter::Parenthesis), + rustc_lexer::TokenKind::OpenBrace => token::OpenDelim(Delimiter::Brace), + rustc_lexer::TokenKind::CloseBrace => token::CloseDelim(Delimiter::Brace), + rustc_lexer::TokenKind::OpenBracket => token::OpenDelim(Delimiter::Bracket), + rustc_lexer::TokenKind::CloseBracket => token::CloseDelim(Delimiter::Bracket), rustc_lexer::TokenKind::At => token::At, rustc_lexer::TokenKind::Pound => token::Pound, rustc_lexer::TokenKind::Tilde => token::Tilde, diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 8318aec8726dc..ef84f95ec8380 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -1,6 +1,6 @@ use super::{StringReader, UnmatchedBrace}; -use rustc_ast::token::{self, DelimToken, Token}; +use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{ DelimSpan, Spacing::{self, *}, @@ -32,15 +32,15 @@ struct TokenTreesReader<'a> { string_reader: StringReader<'a>, token: Token, /// Stack of open delimiters and their spans. Used for error message. - open_braces: Vec<(token::DelimToken, Span)>, + open_braces: Vec<(Delimiter, Span)>, unmatched_braces: Vec, /// The type and spans for all braces /// /// Used only for error recovery when arriving to EOF with mismatched braces. - matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, + matching_delim_spans: Vec<(Delimiter, Span, Span)>, last_unclosed_found_span: Option, /// Collect empty block spans that might have been auto-inserted by editors. - last_delim_empty_block_spans: FxHashMap, + last_delim_empty_block_spans: FxHashMap, /// Collect the spans of braces (Open, Close). Used only /// for detecting if blocks are empty and only braces. matching_block_spans: Vec<(Span, Span)>, @@ -88,7 +88,7 @@ impl<'a> TokenTreesReader<'a> { for &(_, sp) in &self.open_braces { err.span_label(sp, "unclosed delimiter"); self.unmatched_braces.push(UnmatchedBrace { - expected_delim: token::DelimToken::Brace, + expected_delim: Delimiter::Brace, found_delim: None, found_span: self.token.span, unclosed_span: Some(sp), @@ -150,7 +150,7 @@ impl<'a> TokenTreesReader<'a> { } //only add braces - if let (DelimToken::Brace, DelimToken::Brace) = (open_brace, delim) { + if let (Delimiter::Brace, Delimiter::Brace) = (open_brace, delim) { self.matching_block_spans.push((open_brace_span, close_brace_span)); } diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index 2e8e23a50eb0a..faa686c3e57a3 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -2,7 +2,7 @@ // https://www.unicode.org/Public/security/10.0.0/confusables.txt use super::StringReader; -use crate::token; +use crate::token::{self, Delimiter}; use rustc_errors::{Applicability, Diagnostic}; use rustc_span::{symbol::kw, BytePos, Pos, Span}; @@ -312,12 +312,12 @@ const ASCII_ARRAY: &[(char, &str, Option)] = &[ ('!', "Exclamation Mark", Some(token::Not)), ('?', "Question Mark", Some(token::Question)), ('.', "Period", Some(token::Dot)), - ('(', "Left Parenthesis", Some(token::OpenDelim(token::Paren))), - (')', "Right Parenthesis", Some(token::CloseDelim(token::Paren))), - ('[', "Left Square Bracket", Some(token::OpenDelim(token::Bracket))), - (']', "Right Square Bracket", Some(token::CloseDelim(token::Bracket))), - ('{', "Left Curly Brace", Some(token::OpenDelim(token::Brace))), - ('}', "Right Curly Brace", Some(token::CloseDelim(token::Brace))), + ('(', "Left Parenthesis", Some(token::OpenDelim(Delimiter::Parenthesis))), + (')', "Right Parenthesis", Some(token::CloseDelim(Delimiter::Parenthesis))), + ('[', "Left Square Bracket", Some(token::OpenDelim(Delimiter::Bracket))), + (']', "Right Square Bracket", Some(token::CloseDelim(Delimiter::Bracket))), + ('{', "Left Curly Brace", Some(token::OpenDelim(Delimiter::Brace))), + ('}', "Right Curly Brace", Some(token::CloseDelim(Delimiter::Brace))), ('*', "Asterisk", Some(token::BinOp(token::Star))), ('/', "Slash", Some(token::BinOp(token::Slash))), ('\\', "Backslash", None), diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 1724bab5caa43..358b01df3b983 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,7 +1,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle}; use rustc_ast as ast; use rustc_ast::attr; -use rustc_ast::token::{self, Nonterminal}; +use rustc_ast::token::{self, Delimiter, Nonterminal}; use rustc_ast_pretty::pprust; use rustc_errors::{error_code, Diagnostic, PResult}; use rustc_span::{sym, BytePos, Span}; @@ -130,9 +130,9 @@ impl<'a> Parser<'a> { ast::AttrStyle::Outer }; - this.expect(&token::OpenDelim(token::Bracket))?; + this.expect(&token::OpenDelim(Delimiter::Bracket))?; let item = this.parse_attr_item(false)?; - this.expect(&token::CloseDelim(token::Bracket))?; + this.expect(&token::CloseDelim(Delimiter::Bracket))?; let attr_sp = lo.to(this.prev_token.span); // Emit error if inner attribute is encountered and forbidden. @@ -403,7 +403,7 @@ impl<'a> Parser<'a> { crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { Ok(if self.eat(&token::Eq) { ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?) - } else if self.check(&token::OpenDelim(token::Paren)) { + } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Matches `meta_seq = ( COMMASEP(meta_item_inner) )`. let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?; ast::MetaItemKind::List(list) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 575b01180df77..a12621564ab70 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -1,5 +1,5 @@ use super::{Capturing, FlatToken, ForceCollect, Parser, ReplaceRange, TokenCursor, TrailingToken}; -use rustc_ast::token::{self, DelimToken, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttributesData, CreateTokenStream}; use rustc_ast::tokenstream::{AttrAnnotatedTokenTree, DelimSpan, LazyTokenStream, Spacing}; use rustc_ast::{self as ast}; @@ -388,11 +388,11 @@ impl<'a> Parser<'a> { /// Converts a flattened iterator of tokens (including open and close delimiter tokens) /// into a `TokenStream`, creating a `TokenTree::Delimited` for each matching pair /// of open and close delims. -// FIXME(#67062): Currently, we don't parse `None`-delimited groups correctly, -// which can cause us to end up with mismatched `None` delimiters in our +// FIXME(#67062): Currently, we don't parse `Invisible`-delimited groups correctly, +// which can cause us to end up with mismatched `Invisible` delimiters in our // captured tokens. This function contains several hacks to work around this - -// essentially, we throw away mismatched `None` delimiters when we encounter them. -// Once we properly parse `None` delimiters, they can be captured just like any +// essentially, we throw away mismatched `Invisible` delimiters when we encounter them. +// Once we properly parse `Invisible` delimiters, they can be captured just like any // other tokens, and these hacks can be removed. fn make_token_stream( mut iter: impl Iterator, @@ -401,7 +401,7 @@ fn make_token_stream( #[derive(Debug)] struct FrameData { // This is `None` for the first frame, `Some` for all others. - open_delim_sp: Option<(DelimToken, Span)>, + open_delim_sp: Option<(Delimiter, Span)>, inner: Vec<(AttrAnnotatedTokenTree, Spacing)>, } let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }]; @@ -412,13 +412,13 @@ fn make_token_stream( stack.push(FrameData { open_delim_sp: Some((delim, span)), inner: vec![] }); } FlatToken::Token(Token { kind: TokenKind::CloseDelim(delim), span }) => { - // HACK: If we encounter a mismatched `None` delimiter at the top + // HACK: If we encounter a mismatched `Invisible` delimiter at the top // level, just ignore it. - if matches!(delim, DelimToken::NoDelim) + if matches!(delim, Delimiter::Invisible) && (stack.len() == 1 || !matches!( stack.last_mut().unwrap().open_delim_sp.unwrap().0, - DelimToken::NoDelim + Delimiter::Invisible )) { token_and_spacing = iter.next(); @@ -428,11 +428,11 @@ fn make_token_stream( .pop() .unwrap_or_else(|| panic!("Token stack was empty for token: {:?}", token)); - // HACK: If our current frame has a mismatched opening `None` delimiter, + // HACK: If our current frame has a mismatched opening `Invisible` delimiter, // merge our current frame with the one above it. That is, transform // `[ { < first second } third ]` into `[ { first second } third ]` - if !matches!(delim, DelimToken::NoDelim) - && matches!(frame_data.open_delim_sp.unwrap().0, DelimToken::NoDelim) + if !matches!(delim, Delimiter::Invisible) + && matches!(frame_data.open_delim_sp.unwrap().0, Delimiter::Invisible) { stack.last_mut().unwrap().inner.extend(frame_data.inner); // Process our closing delimiter again, this time at the previous @@ -472,10 +472,10 @@ fn make_token_stream( } token_and_spacing = iter.next(); } - // HACK: If we don't have a closing `None` delimiter for our last + // HACK: If we don't have a closing `Invisible` delimiter for our last // frame, merge the frame with the top-level frame. That is, // turn `< first second` into `first second` - if stack.len() == 2 && stack[1].open_delim_sp.unwrap().0 == DelimToken::NoDelim { + if stack.len() == 2 && stack[1].open_delim_sp.unwrap().0 == Delimiter::Invisible { let temp_buf = stack.pop().unwrap(); stack.last_mut().unwrap().inner.extend(temp_buf.inner); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index acc0d7a6ee05e..fff1895b69fde 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -8,7 +8,7 @@ use super::{ use crate::lexer::UnmatchedBrace; use rustc_ast as ast; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Lit, LitKind, TokenKind}; +use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast::{ AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block, @@ -326,10 +326,10 @@ impl<'a> Parser<'a> { TokenKind::Comma, TokenKind::Semi, TokenKind::ModSep, - TokenKind::OpenDelim(token::DelimToken::Brace), - TokenKind::OpenDelim(token::DelimToken::Paren), - TokenKind::CloseDelim(token::DelimToken::Brace), - TokenKind::CloseDelim(token::DelimToken::Paren), + TokenKind::OpenDelim(Delimiter::Brace), + TokenKind::OpenDelim(Delimiter::Parenthesis), + TokenKind::CloseDelim(Delimiter::Brace), + TokenKind::CloseDelim(Delimiter::Parenthesis), ]; match self.token.ident() { Some((ident, false)) @@ -402,7 +402,7 @@ impl<'a> Parser<'a> { } else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) { // The current token is in the same line as the prior token, not recoverable. } else if [token::Comma, token::Colon].contains(&self.token.kind) - && self.prev_token.kind == token::CloseDelim(token::Paren) + && self.prev_token.kind == token::CloseDelim(Delimiter::Parenthesis) { // Likely typo: The current token is on a new line and is expected to be // `.`, `;`, `?`, or an operator after a close delimiter token. @@ -413,7 +413,7 @@ impl<'a> Parser<'a> { // ^ // https://github.com/rust-lang/rust/issues/72253 } else if self.look_ahead(1, |t| { - t == &token::CloseDelim(token::Brace) + t == &token::CloseDelim(Delimiter::Brace) || t.can_begin_expr() && t.kind != token::Colon }) && [token::Comma, token::Colon].contains(&self.token.kind) { @@ -430,7 +430,7 @@ impl<'a> Parser<'a> { .emit(); return Ok(true); } else if self.look_ahead(0, |t| { - t == &token::CloseDelim(token::Brace) + t == &token::CloseDelim(Delimiter::Brace) || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound) // Avoid triggering with too many trailing `#` in raw string. || (sm.is_multiline( @@ -644,7 +644,7 @@ impl<'a> Parser<'a> { (Err(snapshot_err), Err(err)) => { // We don't know what went wrong, emit the normal error. snapshot_err.cancel(); - self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); Err(err) } (Ok(_), Ok(mut tail)) => { @@ -855,7 +855,7 @@ impl<'a> Parser<'a> { trailing_span = trailing_span.to(self.token.span); self.bump(); } - if self.token.kind == token::OpenDelim(token::Paren) { + if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) { // Recover from bad turbofish: `foo.collect::Vec<_>()`. let args = AngleBracketedArgs { args, span }.into(); segment.args = args; @@ -1087,7 +1087,7 @@ impl<'a> Parser<'a> { [(token::Lt, 1), (token::Gt, -1), (token::BinOp(token::Shr), -2)]; self.consume_tts(1, &modifiers); - if !&[token::OpenDelim(token::Paren), token::ModSep] + if !&[token::OpenDelim(Delimiter::Parenthesis), token::ModSep] .contains(&self.token.kind) { // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the @@ -1121,7 +1121,7 @@ impl<'a> Parser<'a> { Err(err) } } - } else if token::OpenDelim(token::Paren) == self.token.kind { + } else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind { // We have high certainty that this was a bad turbofish at this point. // `foo< bar >(` suggest(&mut err); @@ -1175,8 +1175,10 @@ impl<'a> Parser<'a> { self.bump(); // `(` // Consume the fn call arguments. - let modifiers = - [(token::OpenDelim(token::Paren), 1), (token::CloseDelim(token::Paren), -1)]; + let modifiers = [ + (token::OpenDelim(Delimiter::Parenthesis), 1), + (token::CloseDelim(Delimiter::Parenthesis), -1), + ]; self.consume_tts(1, &modifiers); if self.token.kind == token::Eof { @@ -1576,15 +1578,15 @@ impl<'a> Parser<'a> { fn recover_await_macro(&mut self) -> PResult<'a, (Span, P, bool)> { self.expect(&token::Not)?; - self.expect(&token::OpenDelim(token::Paren))?; + self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; let expr = self.parse_expr()?; - self.expect(&token::CloseDelim(token::Paren))?; + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; Ok((self.prev_token.span, expr, false)) } fn recover_await_prefix(&mut self, await_sp: Span) -> PResult<'a, (Span, P, bool)> { let is_question = self.eat(&token::Question); // Handle `await? `. - let expr = if self.token == token::OpenDelim(token::Brace) { + let expr = if self.token == token::OpenDelim(Delimiter::Brace) { // Handle `await { }`. // This needs to be handled separately from the next arm to avoid // interpreting `await { }?` as `?.await`. @@ -1616,8 +1618,8 @@ impl<'a> Parser<'a> { /// If encountering `future.await()`, consumes and emits an error. pub(super) fn recover_from_await_method_call(&mut self) { - if self.token == token::OpenDelim(token::Paren) - && self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren)) + if self.token == token::OpenDelim(Delimiter::Parenthesis) + && self.look_ahead(1, |t| t == &token::CloseDelim(Delimiter::Parenthesis)) { // future.await() let lo = self.token.span; @@ -1638,7 +1640,7 @@ impl<'a> Parser<'a> { pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P> { let is_try = self.token.is_keyword(kw::Try); let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for ! - let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for ( + let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(Delimiter::Parenthesis)); //check for ( if is_try && is_questionmark && is_open { let lo = self.token.span; @@ -1646,8 +1648,8 @@ impl<'a> Parser<'a> { self.bump(); //remove ! let try_span = lo.to(self.token.span); //we take the try!( span self.bump(); //remove ( - let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty - self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block + let is_empty = self.token == token::CloseDelim(Delimiter::Parenthesis); //check if the block is empty + self.consume_block(Delimiter::Parenthesis, ConsumeClosingDelim::No); //eat the block let hi = self.token.span; self.bump(); //remove ) let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro"); @@ -1678,7 +1680,7 @@ impl<'a> Parser<'a> { begin_paren: Option, ) -> P { match (&self.token.kind, begin_paren) { - (token::CloseDelim(token::Paren), Some(begin_par_sp)) => { + (token::CloseDelim(Delimiter::Parenthesis), Some(begin_par_sp)) => { self.bump(); self.struct_span_err( @@ -1711,8 +1713,8 @@ impl<'a> Parser<'a> { || self.token.is_ident() && matches!(node, ast::ExprKind::Path(..) | ast::ExprKind::Field(..)) && !self.token.is_reserved_ident() && // v `foo:bar(baz)` - self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) - || self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) // `foo:bar {` + self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Parenthesis)) + || self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)) // `foo:bar {` || self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:: Parser<'a> { pub(super) fn recover_seq_parse_error( &mut self, - delim: token::DelimToken, + delim: Delimiter, lo: Span, result: PResult<'a, P>, ) -> P { @@ -1842,7 +1844,7 @@ impl<'a> Parser<'a> { loop { debug!("recover_stmt_ loop {:?}", self.token); match self.token.kind { - token::OpenDelim(token::DelimToken::Brace) => { + token::OpenDelim(Delimiter::Brace) => { brace_depth += 1; self.bump(); if break_on_block == BlockMode::Break && brace_depth == 1 && bracket_depth == 0 @@ -1850,11 +1852,11 @@ impl<'a> Parser<'a> { in_block = true; } } - token::OpenDelim(token::DelimToken::Bracket) => { + token::OpenDelim(Delimiter::Bracket) => { bracket_depth += 1; self.bump(); } - token::CloseDelim(token::DelimToken::Brace) => { + token::CloseDelim(Delimiter::Brace) => { if brace_depth == 0 { debug!("recover_stmt_ return - close delim {:?}", self.token); break; @@ -1866,7 +1868,7 @@ impl<'a> Parser<'a> { break; } } - token::CloseDelim(token::DelimToken::Bracket) => { + token::CloseDelim(Delimiter::Bracket) => { bracket_depth -= 1; if bracket_depth < 0 { bracket_depth = 0; @@ -1924,11 +1926,11 @@ impl<'a> Parser<'a> { .emit(); self.bump(); } else if self.token == token::Pound - && self.look_ahead(1, |t| *t == token::OpenDelim(token::Bracket)) + && self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Bracket)) { let lo = self.token.span; // Skip every token until next possible arg. - while self.token != token::CloseDelim(token::Bracket) { + while self.token != token::CloseDelim(Delimiter::Bracket) { self.bump(); } let sp = lo.to(self.token.span); @@ -1949,7 +1951,9 @@ impl<'a> Parser<'a> { // If we find a pattern followed by an identifier, it could be an (incorrect) // C-style parameter declaration. if self.check_ident() - && self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseDelim(token::Paren)) + && self.look_ahead(1, |t| { + *t == token::Comma || *t == token::CloseDelim(Delimiter::Parenthesis) + }) { // `fn foo(String s) {}` let ident = self.parse_ident().unwrap(); @@ -1965,7 +1969,7 @@ impl<'a> Parser<'a> { } else if require_name && (self.token == token::Comma || self.token == token::Lt - || self.token == token::CloseDelim(token::Paren)) + || self.token == token::CloseDelim(Delimiter::Parenthesis)) { let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)"; @@ -2083,11 +2087,7 @@ impl<'a> Parser<'a> { Ok(param) } - pub(super) fn consume_block( - &mut self, - delim: token::DelimToken, - consume_close: ConsumeClosingDelim, - ) { + pub(super) fn consume_block(&mut self, delim: Delimiter, consume_close: ConsumeClosingDelim) { let mut brace_depth = 0; loop { if self.eat(&token::OpenDelim(delim)) { @@ -2106,7 +2106,8 @@ impl<'a> Parser<'a> { brace_depth -= 1; continue; } - } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) { + } else if self.token == token::Eof || self.eat(&token::CloseDelim(Delimiter::Invisible)) + { return; } else { self.bump(); @@ -2552,7 +2553,7 @@ impl<'a> Parser<'a> { crate fn maybe_recover_unexpected_block_label(&mut self) -> bool { let Some(label) = self.eat_label().filter(|_| { - self.eat(&token::Colon) && self.token.kind == token::OpenDelim(token::Brace) + self.eat(&token::Colon) && self.token.kind == token::OpenDelim(Delimiter::Brace) }) else { return false; }; @@ -2649,7 +2650,7 @@ impl<'a> Parser<'a> { /// Parse and throw away a parenthesized comma separated /// sequence of patterns until `)` is reached. fn skip_pat_list(&mut self) -> PResult<'a, ()> { - while !self.check(&token::CloseDelim(token::Paren)) { + while !self.check(&token::CloseDelim(Delimiter::Parenthesis)) { self.parse_pat_no_top_alt(None)?; if !self.eat(&token::Comma) { return Ok(()); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e4370809ebc24..bdbc25af7fa1e 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -7,9 +7,8 @@ use super::{ }; use crate::maybe_recover_from_interpolated_ty_qpath; -use ast::token::DelimToken; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::Spacing; use rustc_ast::util::classify; use rustc_ast::util::literal::LitError; @@ -495,7 +494,7 @@ impl<'a> Parser<'a> { fn is_at_start_of_range_notation_rhs(&self) -> bool { if self.token.can_begin_expr() { // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`. - if self.token == token::OpenDelim(token::Brace) { + if self.token == token::OpenDelim(Delimiter::Brace) { return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL); } true @@ -992,8 +991,8 @@ impl<'a> Parser<'a> { return Ok(e); } e = match self.token.kind { - token::OpenDelim(token::Paren) => self.parse_fn_call_expr(lo, e), - token::OpenDelim(token::Bracket) => self.parse_index_expr(lo, e)?, + token::OpenDelim(Delimiter::Parenthesis) => self.parse_fn_call_expr(lo, e), + token::OpenDelim(Delimiter::Bracket) => self.parse_index_expr(lo, e)?, _ => return Ok(e), } } @@ -1156,7 +1155,7 @@ impl<'a> Parser<'a> { /// Parse a function call expression, `expr(...)`. fn parse_fn_call_expr(&mut self, lo: Span, fun: P) -> P { - let snapshot = if self.token.kind == token::OpenDelim(token::Paren) + let snapshot = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) && self.look_ahead_type_ascription_as_field() { Some((self.create_snapshot_for_diagnostic(), fun.kind.clone())) @@ -1173,7 +1172,7 @@ impl<'a> Parser<'a> { { return expr; } - self.recover_seq_parse_error(token::Paren, lo, seq) + self.recover_seq_parse_error(Delimiter::Parenthesis, lo, seq) } /// If we encounter a parser state that looks like the user has written a `struct` literal with @@ -1190,8 +1189,10 @@ impl<'a> Parser<'a> { (Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => { let name = pprust::path_to_string(&path); snapshot.bump(); // `(` - match snapshot.parse_struct_fields(path, false, token::Paren) { - Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => { + match snapshot.parse_struct_fields(path, false, Delimiter::Parenthesis) { + Ok((fields, ..)) + if snapshot.eat(&token::CloseDelim(Delimiter::Parenthesis)) => + { // We are certain we have `Enum::Foo(a: 3, b: 4)`, suggest // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`. self.restore_snapshot(snapshot); @@ -1241,7 +1242,7 @@ impl<'a> Parser<'a> { fn parse_index_expr(&mut self, lo: Span, base: P) -> PResult<'a, P> { self.bump(); // `[` let index = self.parse_expr()?; - self.expect(&token::CloseDelim(token::Bracket))?; + self.expect(&token::CloseDelim(Delimiter::Bracket))?; Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new())) } @@ -1253,10 +1254,10 @@ impl<'a> Parser<'a> { let fn_span_lo = self.token.span; let mut segment = self.parse_path_segment(PathStyle::Expr, None)?; - self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(token::Paren)]); + self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(Delimiter::Parenthesis)]); self.check_turbofish_missing_angle_brackets(&mut segment); - if self.check(&token::OpenDelim(token::Paren)) { + if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Method call `expr.f()` let mut args = self.parse_paren_expr_seq()?; args.insert(0, self_arg); @@ -1302,9 +1303,9 @@ impl<'a> Parser<'a> { // could be removed without changing functionality, but it's faster // to have it here, especially for programs with large constants. self.parse_lit_expr(attrs) - } else if self.check(&token::OpenDelim(token::Paren)) { + } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { self.parse_tuple_parens_expr(attrs) - } else if self.check(&token::OpenDelim(token::Brace)) { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) { self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs) } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) { self.parse_closure_expr(attrs).map_err(|mut err| { @@ -1315,8 +1316,8 @@ impl<'a> Parser<'a> { } err }) - } else if self.check(&token::OpenDelim(token::Bracket)) { - self.parse_array_or_repeat_expr(attrs, token::Bracket) + } else if self.check(&token::OpenDelim(Delimiter::Bracket)) { + self.parse_array_or_repeat_expr(attrs, Delimiter::Bracket) } else if self.check_path() { self.parse_path_start_expr(attrs) } else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) { @@ -1422,14 +1423,16 @@ impl<'a> Parser<'a> { fn parse_tuple_parens_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.token.span; - self.expect(&token::OpenDelim(token::Paren))?; + self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; let (es, trailing_comma) = match self.parse_seq_to_end( - &token::CloseDelim(token::Paren), + &token::CloseDelim(Delimiter::Parenthesis), SeqSep::trailing_allowed(token::Comma), |p| p.parse_expr_catch_underscore(), ) { Ok(x) => x, - Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))), + Err(err) => { + return Ok(self.recover_seq_parse_error(Delimiter::Parenthesis, lo, Err(err))); + } }; let kind = if es.len() == 1 && !trailing_comma { // `(e)` is parenthesized `e`. @@ -1445,7 +1448,7 @@ impl<'a> Parser<'a> { fn parse_array_or_repeat_expr( &mut self, attrs: AttrVec, - close_delim: token::DelimToken, + close_delim: Delimiter, ) -> PResult<'a, P> { let lo = self.token.span; self.bump(); // `[` or other open delim @@ -1500,7 +1503,7 @@ impl<'a> Parser<'a> { prior_type_ascription: self.last_type_ascription, }; (self.prev_token.span, ExprKind::MacCall(mac)) - } else if self.check(&token::OpenDelim(token::Brace)) { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) { if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) { if qself.is_some() { self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); @@ -1533,7 +1536,7 @@ impl<'a> Parser<'a> { self.parse_for_expr(label, lo, attrs) } else if self.eat_keyword(kw::Loop) { self.parse_loop_expr(label, lo, attrs) - } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() { self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs) } else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) { // We're probably inside of a `Path<'a>` that needs a turbofish @@ -1631,7 +1634,7 @@ impl<'a> Parser<'a> { ) .emit(); Some(lexpr) - } else if self.token != token::OpenDelim(token::Brace) + } else if self.token != token::OpenDelim(Delimiter::Brace) || !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) { let expr = self.parse_expr_opt()?; @@ -1940,7 +1943,7 @@ impl<'a> Parser<'a> { attrs: AttrVec, ) -> Option> { let mut snapshot = self.create_snapshot_for_diagnostic(); - match snapshot.parse_array_or_repeat_expr(attrs, token::Brace) { + match snapshot.parse_array_or_repeat_expr(attrs, Delimiter::Brace) { Ok(arr) => { let hi = snapshot.prev_token.span; self.struct_span_err(arr.span, "this is a block expression, not an array") @@ -2044,7 +2047,7 @@ impl<'a> Parser<'a> { } if self.token.kind == TokenKind::Semi - && matches!(self.token_cursor.frame.delim_sp, Some((DelimToken::Paren, _))) + && matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _))) { // It is likely that the closure body is a block but where the // braces have been removed. We will recover and eat the next @@ -2158,7 +2161,7 @@ impl<'a> Parser<'a> { } } else { let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery. - let not_block = self.token != token::OpenDelim(token::Brace); + let not_block = self.token != token::OpenDelim(Delimiter::Brace); let block = self.parse_block().map_err(|err| { if not_block { self.error_missing_if_then_block(lo, Some(err), missing_then_block_binop_span()) @@ -2283,7 +2286,7 @@ impl<'a> Parser<'a> { // This is used below for recovery in case of `for ( $stuff ) $block` // in which case we will suggest `for $stuff $block`. let begin_paren = match self.token.kind { - token::OpenDelim(token::Paren) => Some(self.token.span), + token::OpenDelim(Delimiter::Parenthesis) => Some(self.token.span), _ => None, }; @@ -2372,7 +2375,7 @@ impl<'a> Parser<'a> { let match_span = self.prev_token.span; let lo = self.prev_token.span; let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; - if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) { + if let Err(mut e) = self.expect(&token::OpenDelim(Delimiter::Brace)) { if self.token == token::Semi { e.span_suggestion_short( match_span, @@ -2391,7 +2394,7 @@ impl<'a> Parser<'a> { attrs.extend(self.parse_inner_attributes()?); let mut arms: Vec = Vec::new(); - while self.token != token::CloseDelim(token::Brace) { + while self.token != token::CloseDelim(Delimiter::Brace) { match self.parse_arm() { Ok(arm) => arms.push(arm), Err(mut e) => { @@ -2399,7 +2402,7 @@ impl<'a> Parser<'a> { e.emit(); self.recover_stmt(); let span = lo.to(self.token.span); - if self.token == token::CloseDelim(token::Brace) { + if self.token == token::CloseDelim(Delimiter::Brace) { self.bump(); } return Ok(self.mk_expr(span, ExprKind::Match(scrutinee, arms), attrs)); @@ -2463,7 +2466,7 @@ impl<'a> Parser<'a> { // We might have either a `,` -> `;` typo, or a block without braces. We need // a more subtle parsing strategy. loop { - if self.token.kind == token::CloseDelim(token::Brace) { + if self.token.kind == token::CloseDelim(Delimiter::Brace) { // We have reached the closing brace of the `match` expression. return Some(err(self, stmts)); } @@ -2571,7 +2574,7 @@ impl<'a> Parser<'a> { })?; let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) - && this.token != token::CloseDelim(token::Brace); + && this.token != token::CloseDelim(Delimiter::Brace); let hi = this.prev_token.span; @@ -2592,8 +2595,8 @@ impl<'a> Parser<'a> { TrailingToken::None, )); } - this.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]).map_err( - |mut err| { + this.expect_one_of(&[token::Comma], &[token::CloseDelim(Delimiter::Brace)]) + .map_err(|mut err| { match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) { (Ok(ref expr_lines), Ok(ref arm_start_lines)) if arm_start_lines.lines[0].end_col @@ -2627,8 +2630,7 @@ impl<'a> Parser<'a> { } } err - }, - )?; + })?; } else { this.eat(&token::Comma); } @@ -2670,13 +2672,13 @@ impl<'a> Parser<'a> { fn is_do_catch_block(&self) -> bool { self.token.is_keyword(kw::Do) && self.is_keyword_ahead(1, &[kw::Catch]) - && self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) + && self.look_ahead(2, |t| *t == token::OpenDelim(Delimiter::Brace)) && !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) } fn is_try_block(&self) -> bool { self.token.is_keyword(kw::Try) - && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) + && self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace)) && self.token.uninterpolated_span().rust_2018() } @@ -2696,10 +2698,10 @@ impl<'a> Parser<'a> { && (( // `async move {` self.is_keyword_ahead(1, &[kw::Move]) - && self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) + && self.look_ahead(2, |t| *t == token::OpenDelim(Delimiter::Brace)) ) || ( // `async {` - self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) + self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace)) )) } @@ -2726,7 +2728,7 @@ impl<'a> Parser<'a> { ) -> Option>> { let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL); if struct_allowed || self.is_certainly_not_a_block() { - if let Err(err) = self.expect(&token::OpenDelim(token::Brace)) { + if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) { return Some(Err(err)); } let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true); @@ -2753,7 +2755,7 @@ impl<'a> Parser<'a> { &mut self, pth: ast::Path, recover: bool, - close_delim: token::DelimToken, + close_delim: Delimiter, ) -> PResult<'a, (Vec, ast::StructRest, bool)> { let mut fields = Vec::new(); let mut base = ast::StructRest::None; @@ -2853,9 +2855,9 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P> { let lo = pth.span; let (fields, base, recover_async) = - self.parse_struct_fields(pth.clone(), recover, token::Brace)?; + self.parse_struct_fields(pth.clone(), recover, Delimiter::Brace)?; let span = lo.to(self.token.span); - self.expect(&token::CloseDelim(token::Brace))?; + self.expect(&token::CloseDelim(Delimiter::Brace))?; let expr = if recover_async { ExprKind::Err } else { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ca81921faedcc..746861933d2f0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -4,7 +4,7 @@ use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, Traili use rustc_ast::ast::*; use rustc_ast::ptr::P; -use rustc_ast::token::{self, TokenKind}; +use rustc_ast::token::{self, Delimiter, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID}; use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind}; @@ -39,9 +39,9 @@ impl<'a> Parser<'a> { let mod_kind = if self.eat(&token::Semi) { ModKind::Unloaded } else { - self.expect(&token::OpenDelim(token::Brace))?; + self.expect(&token::OpenDelim(Delimiter::Brace))?; let (mut inner_attrs, items, inner_span) = - self.parse_mod(&token::CloseDelim(token::Brace))?; + self.parse_mod(&token::CloseDelim(Delimiter::Brace))?; attrs.append(&mut inner_attrs); ModKind::Loaded(items, Inline::Yes, inner_span) }; @@ -324,7 +324,7 @@ impl<'a> Parser<'a> { let sp = self.prev_token.span.between(self.token.span); let full_sp = self.prev_token.span.to(self.token.span); let ident_sp = self.token.span; - if self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) { + if self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace)) { // possible public struct definition where `struct` was forgotten let ident = self.parse_ident().unwrap(); let msg = format!("add `struct` here to parse `{ident}` as a public struct"); @@ -336,16 +336,16 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, // speculative ); Err(err) - } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) { + } else if self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Parenthesis)) { let ident = self.parse_ident().unwrap(); self.bump(); // `(` let kw_name = self.recover_first_param(); - self.consume_block(token::Paren, ConsumeClosingDelim::Yes); + self.consume_block(Delimiter::Parenthesis, ConsumeClosingDelim::Yes); let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) { - self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]); + self.eat_to_tokens(&[&token::OpenDelim(Delimiter::Brace)]); self.bump(); // `{` ("fn", kw_name, false) - } else if self.check(&token::OpenDelim(token::Brace)) { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) { self.bump(); // `{` ("fn", kw_name, false) } else if self.check(&token::Colon) { @@ -358,7 +358,7 @@ impl<'a> Parser<'a> { let msg = format!("missing `{kw}` for {kw_name} definition"); let mut err = self.struct_span_err(sp, &msg); if !ambiguous { - self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); let suggestion = format!("add `{kw}` here to parse `{ident}` as a public {kw_name}"); err.span_suggestion_short( @@ -386,9 +386,9 @@ impl<'a> Parser<'a> { let ident = self.parse_ident().unwrap(); self.eat_to_tokens(&[&token::Gt]); self.bump(); // `>` - let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) { + let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(Delimiter::Parenthesis)) { ("fn", self.recover_first_param(), false) - } else if self.check(&token::OpenDelim(token::Brace)) { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) { ("struct", "struct", false) } else { ("fn` or `struct", "function or struct", true) @@ -630,11 +630,11 @@ impl<'a> Parser<'a> { mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option>>, ) -> PResult<'a, Vec> { let open_brace_span = self.token.span; - self.expect(&token::OpenDelim(token::Brace))?; + self.expect(&token::OpenDelim(Delimiter::Brace))?; attrs.append(&mut self.parse_inner_attributes()?); let mut items = Vec::new(); - while !self.eat(&token::CloseDelim(token::Brace)) { + while !self.eat(&token::CloseDelim(Delimiter::Brace)) { if self.recover_doc_comment_before_brace() { continue; } @@ -642,7 +642,7 @@ impl<'a> Parser<'a> { Ok(None) => { // We have to bail or we'll potentially never make progress. let non_item_span = self.token.span; - self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); self.struct_span_err(non_item_span, "non-item in item list") .span_label(open_brace_span, "item list starts here") .span_label(non_item_span, "non-item starts here") @@ -652,7 +652,7 @@ impl<'a> Parser<'a> { } Ok(Some(item)) => items.extend(item), Err(mut err) => { - self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); err.span_label(open_brace_span, "while parsing this item list starting here") .span_label(self.prev_token.span, "the item list ends here") .emit(); @@ -666,7 +666,7 @@ impl<'a> Parser<'a> { /// Recover on a doc comment before `}`. fn recover_doc_comment_before_brace(&mut self) -> bool { if let token::DocComment(..) = self.token.kind { - if self.look_ahead(1, |tok| tok == &token::CloseDelim(token::Brace)) { + if self.look_ahead(1, |tok| tok == &token::CloseDelim(Delimiter::Brace)) { struct_span_err!( self.diagnostic(), self.token.span, @@ -866,7 +866,7 @@ impl<'a> Parser<'a> { let lo = self.token.span; let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None }; - let kind = if self.check(&token::OpenDelim(token::Brace)) + let kind = if self.check(&token::OpenDelim(Delimiter::Brace)) || self.check(&token::BinOp(token::Star)) || self.is_import_coupler() { @@ -908,7 +908,7 @@ impl<'a> Parser<'a> { /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> { - self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID))) + self.parse_delim_comma_seq(Delimiter::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID))) .map(|(r, _)| r) } @@ -1077,7 +1077,7 @@ impl<'a> Parser<'a> { && self.is_keyword_ahead(1, &[kw::Extern]) && self.look_ahead( 2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize), - |t| t.kind == token::OpenDelim(token::Brace), + |t| t.kind == token::OpenDelim(Delimiter::Brace), ) } @@ -1204,8 +1204,9 @@ impl<'a> Parser<'a> { let mut generics = self.parse_generics()?; generics.where_clause = self.parse_where_clause()?; - let (variants, _) = - self.parse_delim_comma_seq(token::Brace, |p| p.parse_enum_variant()).map_err(|e| { + let (variants, _) = self + .parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()) + .map_err(|e| { self.recover_stmt(); e })?; @@ -1228,11 +1229,11 @@ impl<'a> Parser<'a> { } let ident = this.parse_field_ident("enum", vlo)?; - let struct_def = if this.check(&token::OpenDelim(token::Brace)) { + let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) { // Parse a struct variant. let (fields, recovered) = this.parse_record_struct_body("struct", false)?; VariantData::Struct(fields, recovered) - } else if this.check(&token::OpenDelim(token::Paren)) { + } else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) { VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID) } else { VariantData::Unit(DUMMY_NODE_ID) @@ -1292,12 +1293,12 @@ impl<'a> Parser<'a> { } else if self.eat(&token::Semi) { VariantData::Unit(DUMMY_NODE_ID) // Record-style struct definition - } else if self.token == token::OpenDelim(token::Brace) { + } else if self.token == token::OpenDelim(Delimiter::Brace) { let (fields, recovered) = self.parse_record_struct_body("struct", generics.where_clause.has_where_token)?; VariantData::Struct(fields, recovered) // Tuple-style struct definition with optional where-clause. - } else if self.token == token::OpenDelim(token::Paren) { + } else if self.token == token::OpenDelim(Delimiter::Parenthesis) { let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID); generics.where_clause = self.parse_where_clause()?; self.expect_semi()?; @@ -1326,7 +1327,7 @@ impl<'a> Parser<'a> { let (fields, recovered) = self.parse_record_struct_body("union", generics.where_clause.has_where_token)?; VariantData::Struct(fields, recovered) - } else if self.token == token::OpenDelim(token::Brace) { + } else if self.token == token::OpenDelim(Delimiter::Brace) { let (fields, recovered) = self.parse_record_struct_body("union", generics.where_clause.has_where_token)?; VariantData::Struct(fields, recovered) @@ -1348,10 +1349,10 @@ impl<'a> Parser<'a> { ) -> PResult<'a, (Vec, /* recovered */ bool)> { let mut fields = Vec::new(); let mut recovered = false; - if self.eat(&token::OpenDelim(token::Brace)) { - while self.token != token::CloseDelim(token::Brace) { + if self.eat(&token::OpenDelim(Delimiter::Brace)) { + while self.token != token::CloseDelim(Delimiter::Brace) { let field = self.parse_field_def(adt_ty).map_err(|e| { - self.consume_block(token::Brace, ConsumeClosingDelim::No); + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::No); recovered = true; e }); @@ -1363,7 +1364,7 @@ impl<'a> Parser<'a> { } } } - self.eat(&token::CloseDelim(token::Brace)); + self.eat(&token::CloseDelim(Delimiter::Brace)); } else { let token_str = super::token_descr(&self.token); let msg = &format!( @@ -1439,7 +1440,7 @@ impl<'a> Parser<'a> { token::Comma => { self.bump(); } - token::CloseDelim(token::Brace) => {} + token::CloseDelim(Delimiter::Brace) => {} token::DocComment(..) => { let previous_span = self.prev_token.span; let mut err = self.span_err(self.token.span, Error::UselessDocComment); @@ -1450,7 +1451,7 @@ impl<'a> Parser<'a> { if !seen_comma && comma_after_doc_seen { seen_comma = true; } - if comma_after_doc_seen || self.token == token::CloseDelim(token::Brace) { + if comma_after_doc_seen || self.token == token::CloseDelim(Delimiter::Brace) { err.emit(); } else { if !seen_comma { @@ -1478,7 +1479,7 @@ impl<'a> Parser<'a> { if let Some(last_segment) = segments.last() { recovered = self.check_trailing_angle_brackets( last_segment, - &[&token::Comma, &token::CloseDelim(token::Brace)], + &[&token::Comma, &token::CloseDelim(Delimiter::Brace)], ); if recovered { // Handle a case like `Vec>,` where we can continue parsing fields @@ -1636,12 +1637,12 @@ impl<'a> Parser<'a> { /// ``` fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> { let ident = self.parse_ident()?; - let body = if self.check(&token::OpenDelim(token::Brace)) { + let body = if self.check(&token::OpenDelim(Delimiter::Brace)) { self.parse_mac_args()? // `MacBody` - } else if self.check(&token::OpenDelim(token::Paren)) { + } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { let params = self.parse_token_tree(); // `MacParams` let pspan = params.span(); - if !self.check(&token::OpenDelim(token::Brace)) { + if !self.check(&token::OpenDelim(Delimiter::Brace)) { return self.unexpected(); } let body = self.parse_token_tree(); // `MacBody` @@ -1924,7 +1925,7 @@ impl<'a> Parser<'a> { self.expect_semi()?; *sig_hi = self.prev_token.span; (Vec::new(), None) - } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() { self.parse_inner_attrs_and_block().map(|(attrs, body)| (attrs, Some(body)))? } else if self.token.kind == token::Eq { // Recover `fn foo() = $expr;`. @@ -1943,12 +1944,12 @@ impl<'a> Parser<'a> { (Vec::new(), Some(self.mk_block_err(span))) } else { let expected = if req_body { - &[token::OpenDelim(token::Brace)][..] + &[token::OpenDelim(Delimiter::Brace)][..] } else { - &[token::Semi, token::OpenDelim(token::Brace)] + &[token::Semi, token::OpenDelim(Delimiter::Brace)] }; if let Err(mut err) = self.expected_one_of_not_found(&[], &expected) { - if self.token.kind == token::CloseDelim(token::Brace) { + if self.token.kind == token::CloseDelim(Delimiter::Brace) { // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in // the AST for typechecking. err.span_label(ident.span, "while parsing this `fn`"); @@ -2164,7 +2165,7 @@ impl<'a> Parser<'a> { e.emit(); let lo = p.prev_token.span; // Skip every token until next possible arg or end. - p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]); + p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(Delimiter::Parenthesis)]); // Create a placeholder argument for proper arg count (issue #34264). Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span)))) }); @@ -2220,7 +2221,7 @@ impl<'a> Parser<'a> { let mut ty = this.parse_ty_for_param(); if ty.is_ok() && this.token != token::Comma - && this.token != token::CloseDelim(token::Paren) + && this.token != token::CloseDelim(Delimiter::Parenthesis) { // This wasn't actually a type, but a pattern looking like a type, // so we are going to rollback and re-parse for recovery. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index dfe758d0cdf01..96cca68257e7f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -19,7 +19,7 @@ pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma}; pub use path::PathStyle; use rustc_ast::ptr::P; -use rustc_ast::token::{self, DelimToken, Nonterminal, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::AttributesData; use rustc_ast::tokenstream::{self, DelimSpan, Spacing}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; @@ -244,12 +244,12 @@ struct TokenCursor { #[derive(Clone)] struct TokenCursorFrame { - delim_sp: Option<(DelimToken, DelimSpan)>, + delim_sp: Option<(Delimiter, DelimSpan)>, tree_cursor: tokenstream::Cursor, } impl TokenCursorFrame { - fn new(delim_sp: Option<(DelimToken, DelimSpan)>, tts: TokenStream) -> Self { + fn new(delim_sp: Option<(Delimiter, DelimSpan)>, tts: TokenStream) -> Self { TokenCursorFrame { delim_sp, tree_cursor: tts.into_trees() } } } @@ -263,8 +263,8 @@ impl TokenCursor { #[inline(always)] fn inlined_next(&mut self, desugar_doc_comments: bool) -> (Token, Spacing) { loop { - // FIXME: we currently don't return `NoDelim` open/close delims. To fix #67062 we will - // need to, whereupon the `delim != DelimToken::NoDelim` conditions below can be + // FIXME: we currently don't return `Delimiter` open/close delims. To fix #67062 we will + // need to, whereupon the `delim != Delimiter::Invisible` conditions below can be // removed. if let Some((tree, spacing)) = self.frame.tree_cursor.next_with_spacing_ref() { match tree { @@ -278,14 +278,14 @@ impl TokenCursor { // Set `open_delim` to true here because we deal with it immediately. let frame = TokenCursorFrame::new(Some((delim, sp)), tts.clone()); self.stack.push(mem::replace(&mut self.frame, frame)); - if delim != DelimToken::NoDelim { + if delim != Delimiter::Invisible { return (Token::new(token::OpenDelim(delim), sp.open), Spacing::Alone); } // No open delimeter to return; continue on to the next iteration. } }; } else if let Some(frame) = self.stack.pop() { - if let Some((delim, span)) = self.frame.delim_sp && delim != DelimToken::NoDelim { + if let Some((delim, span)) = self.frame.delim_sp && delim != Delimiter::Invisible { self.frame = frame; return (Token::new(token::CloseDelim(delim), span.close), Spacing::Alone); } @@ -314,7 +314,7 @@ impl TokenCursor { let delim_span = DelimSpan::from_single(span); let body = TokenTree::Delimited( delim_span, - token::Bracket, + Delimiter::Bracket, [ TokenTree::token(token::Ident(sym::doc, false), span), TokenTree::token(token::Eq, span), @@ -626,7 +626,7 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(dist, &[kw::Const]) && self.look_ahead(dist + 1, |t| match t.kind { token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)), - token::OpenDelim(DelimToken::Brace) => true, + token::OpenDelim(Delimiter::Brace) => true, _ => false, }) } @@ -954,7 +954,7 @@ impl<'a> Parser<'a> { fn parse_delim_comma_seq( &mut self, - delim: DelimToken, + delim: Delimiter, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, ) -> PResult<'a, (Vec, bool)> { self.parse_unspanned_seq( @@ -969,7 +969,7 @@ impl<'a> Parser<'a> { &mut self, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, ) -> PResult<'a, (Vec, bool)> { - self.parse_delim_comma_seq(token::Paren, f) + self.parse_delim_comma_seq(Delimiter::Parenthesis, f) } /// Advance the parser by one token using provided token as the next one. @@ -1005,7 +1005,7 @@ impl<'a> Parser<'a> { } debug_assert!(!matches!( next.0.kind, - token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) + token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) )); self.inlined_bump_with(next) } @@ -1018,10 +1018,10 @@ impl<'a> Parser<'a> { } let frame = &self.token_cursor.frame; - if let Some((delim, span)) = frame.delim_sp && delim != DelimToken::NoDelim { + if let Some((delim, span)) = frame.delim_sp && delim != Delimiter::Invisible { let all_normal = (0..dist).all(|i| { let token = frame.tree_cursor.look_ahead(i); - !matches!(token, Some(TokenTree::Delimited(_, DelimToken::NoDelim, _))) + !matches!(token, Some(TokenTree::Delimited(_, Delimiter::Invisible, _))) }); if all_normal { return match frame.tree_cursor.look_ahead(dist - 1) { @@ -1043,7 +1043,7 @@ impl<'a> Parser<'a> { token = cursor.next(/* desugar_doc_comments */ false).0; if matches!( token.kind, - token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) + token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) ) { continue; } @@ -1079,7 +1079,7 @@ impl<'a> Parser<'a> { /// Parses constness: `const` or nothing. fn parse_constness(&mut self) -> Const { // Avoid const blocks to be parsed as const items - if self.look_ahead(1, |t| t != &token::OpenDelim(DelimToken::Brace)) + if self.look_ahead(1, |t| t != &token::OpenDelim(Delimiter::Brace)) && self.eat_keyword(kw::Const) { Const::Yes(self.prev_token.uninterpolated_span()) @@ -1142,9 +1142,9 @@ impl<'a> Parser<'a> { fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, MacArgs> { Ok( - if self.check(&token::OpenDelim(DelimToken::Paren)) - || self.check(&token::OpenDelim(DelimToken::Bracket)) - || self.check(&token::OpenDelim(DelimToken::Brace)) + if self.check(&token::OpenDelim(Delimiter::Parenthesis)) + || self.check(&token::OpenDelim(Delimiter::Bracket)) + || self.check(&token::OpenDelim(Delimiter::Brace)) { match self.parse_token_tree() { TokenTree::Delimited(dspan, delim, tokens) => @@ -1288,7 +1288,7 @@ impl<'a> Parser<'a> { } let lo = self.prev_token.span; - if self.check(&token::OpenDelim(token::Paren)) { + if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // We don't `self.bump()` the `(` yet because this might be a struct definition where // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`. // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so @@ -1299,7 +1299,7 @@ impl<'a> Parser<'a> { // Parse `pub(crate)`. self.bump(); // `(` self.bump(); // `crate` - self.expect(&token::CloseDelim(token::Paren))?; // `)` + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let vis = VisibilityKind::Crate(CrateSugar::PubCrate); return Ok(Visibility { span: lo.to(self.prev_token.span), @@ -1311,20 +1311,20 @@ impl<'a> Parser<'a> { self.bump(); // `(` self.bump(); // `in` let path = self.parse_path(PathStyle::Mod)?; // `path` - self.expect(&token::CloseDelim(token::Paren))?; // `)` + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }; return Ok(Visibility { span: lo.to(self.prev_token.span), kind: vis, tokens: None, }); - } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) + } else if self.look_ahead(2, |t| t == &token::CloseDelim(Delimiter::Parenthesis)) && self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower]) { // Parse `pub(self)` or `pub(super)`. self.bump(); // `(` let path = self.parse_path(PathStyle::Mod)?; // `super`/`self` - self.expect(&token::CloseDelim(token::Paren))?; // `)` + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let vis = VisibilityKind::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }; return Ok(Visibility { span: lo.to(self.prev_token.span), @@ -1346,7 +1346,7 @@ impl<'a> Parser<'a> { fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> { self.bump(); // `(` let path = self.parse_path(PathStyle::Mod)?; - self.expect(&token::CloseDelim(token::Paren))?; // `)` + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let msg = "incorrect visibility restriction"; let suggestion = r##"some possible visibility restrictions are: @@ -1413,7 +1413,7 @@ impl<'a> Parser<'a> { fn is_import_coupler(&mut self) -> bool { self.check(&token::ModSep) && self.look_ahead(1, |t| { - *t == token::OpenDelim(token::Brace) || *t == token::BinOp(token::Star) + *t == token::OpenDelim(Delimiter::Brace) || *t == token::BinOp(token::Star) }) } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 691bfdb01a43e..6974f318f9498 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -1,5 +1,5 @@ use rustc_ast::ptr::P; -use rustc_ast::token::{self, NonterminalKind, Token}; +use rustc_ast::token::{self, Delimiter, NonterminalKind, Token}; use rustc_ast::AstLike; use rustc_ast_pretty::pprust; use rustc_errors::PResult; @@ -43,7 +43,7 @@ impl<'a> Parser<'a> { _ => token.can_begin_type(), }, NonterminalKind::Block => match token.kind { - token::OpenDelim(token::Brace) => true, + token::OpenDelim(Delimiter::Brace) => true, token::Interpolated(ref nt) => !matches!( **nt, token::NtItem(_) @@ -67,8 +67,8 @@ impl<'a> Parser<'a> { NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr { .. } => { match token.kind { token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) - token::OpenDelim(token::Paren) | // tuple pattern - token::OpenDelim(token::Bracket) | // slice pattern + token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern + token::OpenDelim(Delimiter::Bracket) | // slice pattern token::BinOp(token::And) | // reference token::BinOp(token::Minus) | // negative literal token::AndAnd | // double reference diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 67bbbf249369d..c7b929bf367dc 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -2,7 +2,7 @@ use super::{ForceCollect, Parser, PathStyle, TrailingToken}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; -use rustc_ast::token; +use rustc_ast::token::{self, Delimiter}; use rustc_ast::{ self as ast, AttrVec, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax, @@ -260,9 +260,9 @@ impl<'a> Parser<'a> { | token::Semi // e.g. `let a |;`. | token::Colon // e.g. `let a | :`. | token::Comma // e.g. `let (a |,)`. - | token::CloseDelim(token::Bracket) // e.g. `let [a | ]`. - | token::CloseDelim(token::Paren) // e.g. `let (a | )`. - | token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`. + | token::CloseDelim(Delimiter::Bracket) // e.g. `let [a | ]`. + | token::CloseDelim(Delimiter::Parenthesis) // e.g. `let (a | )`. + | token::CloseDelim(Delimiter::Brace) // e.g. `let A { f: a | }`. ) }); match (is_end_ahead, &self.token.kind) { @@ -323,11 +323,11 @@ impl<'a> Parser<'a> { let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd { self.parse_pat_deref(expected)? - } else if self.check(&token::OpenDelim(token::Paren)) { + } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { self.parse_pat_tuple_or_parens()? - } else if self.check(&token::OpenDelim(token::Bracket)) { + } else if self.check(&token::OpenDelim(Delimiter::Bracket)) { // Parse `[pat, pat,...]` as a slice pattern. - let (pats, _) = self.parse_delim_comma_seq(token::Bracket, |p| { + let (pats, _) = self.parse_delim_comma_seq(Delimiter::Bracket, |p| { p.parse_pat_allow_top_alt( None, RecoverComma::No, @@ -389,9 +389,9 @@ impl<'a> Parser<'a> { } else if let Some(form) = self.parse_range_end() { let begin = self.mk_expr(span, ExprKind::Path(qself, path), AttrVec::new()); self.parse_pat_range_begin_with(begin, form)? - } else if self.check(&token::OpenDelim(token::Brace)) { + } else if self.check(&token::OpenDelim(Delimiter::Brace)) { self.parse_pat_struct(qself, path)? - } else if self.check(&token::OpenDelim(token::Paren)) { + } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { self.parse_pat_tuple_struct(qself, path)? } else { PatKind::Path(qself, path) @@ -845,8 +845,8 @@ impl<'a> Parser<'a> { // Avoid `in`. Due to recovery in the list parser this messes with `for ( $pat in $expr )`. && !self.token.is_keyword(kw::In) // Try to do something more complex? - && self.look_ahead(1, |t| !matches!(t.kind, token::OpenDelim(token::Paren) // A tuple struct pattern. - | token::OpenDelim(token::Brace) // A struct pattern. + && self.look_ahead(1, |t| !matches!(t.kind, token::OpenDelim(Delimiter::Parenthesis) // A tuple struct pattern. + | token::OpenDelim(Delimiter::Brace) // A struct pattern. | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern. | token::ModSep // A tuple / struct variant pattern. | token::Not)) // A macro expanding to a pattern. @@ -868,7 +868,7 @@ impl<'a> Parser<'a> { // This shortly leads to a parse error. Note that if there is no explicit // binding mode then we do not end up here, because the lookahead // will direct us over to `parse_enum_variant()`. - if self.token == token::OpenDelim(token::Paren) { + if self.token == token::OpenDelim(Delimiter::Parenthesis) { return Err(self .struct_span_err(self.prev_token.span, "expected identifier, found enum pattern")); } @@ -917,7 +917,7 @@ impl<'a> Parser<'a> { let mut delayed_err: Option> = None; let mut etc_span = None; - while self.token != token::CloseDelim(token::Brace) { + while self.token != token::CloseDelim(Delimiter::Brace) { let attrs = match self.parse_outer_attributes() { Ok(attrs) => attrs, Err(err) => { @@ -946,7 +946,7 @@ impl<'a> Parser<'a> { self.recover_one_fewer_dotdot(); self.bump(); // `..` || `...` - if self.token == token::CloseDelim(token::Brace) { + if self.token == token::CloseDelim(Delimiter::Brace) { etc_span = Some(etc_sp); break; } @@ -970,7 +970,7 @@ impl<'a> Parser<'a> { } etc_span = Some(etc_sp.until(self.token.span)); - if self.token == token::CloseDelim(token::Brace) { + if self.token == token::CloseDelim(Delimiter::Brace) { // If the struct looks otherwise well formed, recover and continue. if let Some(sp) = comma_sp { err.span_suggestion_short( diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index b9e3adaac03a4..5c6fb376cd41a 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -2,7 +2,7 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::maybe_whole; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token}; +use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint, AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, @@ -236,14 +236,14 @@ impl<'a> Parser<'a> { token.kind, token::Lt | token::BinOp(token::Shl) - | token::OpenDelim(token::Paren) + | token::OpenDelim(Delimiter::Parenthesis) | token::LArrow ) }; let check_args_start = |this: &mut Self| { this.expected_tokens.extend_from_slice(&[ TokenType::Token(token::Lt), - TokenType::Token(token::OpenDelim(token::Paren)), + TokenType::Token(token::OpenDelim(Delimiter::Parenthesis)), ]); is_args_start(&this.token) }; @@ -639,7 +639,7 @@ impl<'a> Parser<'a> { /// the caller. pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> { // Parse const argument. - let value = if let token::OpenDelim(token::Brace) = self.token.kind { + let value = if let token::OpenDelim(Delimiter::Brace) = self.token.kind { self.parse_block_expr( None, self.token.span, @@ -667,7 +667,8 @@ impl<'a> Parser<'a> { GenericArg::Const(self.parse_const_arg()?) } else if self.check_type() { // Parse type argument. - let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren)); + let is_const_fn = + self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Parenthesis)); let mut snapshot = self.create_snapshot_for_diagnostic(); match self.parse_ty() { Ok(ty) => GenericArg::Type(ty), diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 14f1208b71f51..ac693597662e6 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -11,7 +11,7 @@ use crate::maybe_whole; use rustc_ast as ast; use rustc_ast::ptr::P; -use rustc_ast::token::{self, TokenKind}; +use rustc_ast::token::{self, Delimiter, TokenKind}; use rustc_ast::util::classify; use rustc_ast::{ AstLike, AttrStyle, AttrVec, Attribute, LocalKind, MacCall, MacCallStmt, MacStmtStyle, @@ -92,7 +92,7 @@ impl<'a> Parser<'a> { // Do not attempt to parse an expression if we're done here. self.error_outer_attrs(&attrs.take_for_recovery()); self.mk_stmt(lo, StmtKind::Empty) - } else if self.token != token::CloseDelim(token::Brace) { + } else if self.token != token::CloseDelim(Delimiter::Brace) { // Remainder are line-expr stmts. let e = if force_collect == ForceCollect::Yes { self.collect_tokens_no_attrs(|this| { @@ -131,7 +131,7 @@ impl<'a> Parser<'a> { } } - let expr = if this.eat(&token::OpenDelim(token::Brace)) { + let expr = if this.eat(&token::OpenDelim(Delimiter::Brace)) { this.parse_struct_expr(None, path, AttrVec::new(), true)? } else { let hi = this.prev_token.span; @@ -165,7 +165,7 @@ impl<'a> Parser<'a> { let hi = self.prev_token.span; let style = match delim { - Some(token::Brace) => MacStmtStyle::Braces, + Some(Delimiter::Brace) => MacStmtStyle::Braces, Some(_) => MacStmtStyle::NoBraces, None => unreachable!(), }; @@ -434,7 +434,7 @@ impl<'a> Parser<'a> { // If the next token is an open brace (e.g., `if a b {`), the place- // inside-a-block suggestion would be more likely wrong than right. Ok(Some(_)) - if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) + if self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)) || do_not_suggest_help => {} // Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836). Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {} @@ -488,7 +488,7 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtBlock, |x| (Vec::new(), x)); self.maybe_recover_unexpected_block_label(); - if !self.eat(&token::OpenDelim(token::Brace)) { + if !self.eat(&token::OpenDelim(Delimiter::Brace)) { return self.error_block_no_opening_brace(); } @@ -509,7 +509,7 @@ impl<'a> Parser<'a> { recover: AttemptLocalParseRecovery, ) -> PResult<'a, P> { let mut stmts = vec![]; - while !self.eat(&token::CloseDelim(token::Brace)) { + while !self.eat(&token::CloseDelim(Delimiter::Brace)) { if self.token == token::Eof { break; } @@ -553,7 +553,7 @@ impl<'a> Parser<'a> { { // Just check for errors and recover; do not eat semicolon yet. if let Err(mut e) = - self.expect_one_of(&[], &[token::Semi, token::CloseDelim(token::Brace)]) + self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]) { if let TokenKind::DocComment(..) = self.token.kind { if let Ok(snippet) = self.span_to_snippet(self.token.span) { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index bb387064e27fe..9e771a8af1a4e 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -3,7 +3,7 @@ use super::{Parser, PathStyle, TokenType}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::{ self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind, @@ -249,14 +249,14 @@ impl<'a> Parser<'a> { let lo = self.token.span; let mut impl_dyn_multi = false; - let kind = if self.check(&token::OpenDelim(token::Paren)) { + let kind = if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { self.parse_ty_tuple_or_parens(lo, allow_plus)? } else if self.eat(&token::Not) { // Never type `!` TyKind::Never } else if self.eat(&token::BinOp(token::Star)) { self.parse_ty_ptr()? - } else if self.eat(&token::OpenDelim(token::Bracket)) { + } else if self.eat(&token::OpenDelim(Delimiter::Bracket)) { self.parse_array_or_slice_ty()? } else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) { // Reference @@ -409,7 +409,7 @@ impl<'a> Parser<'a> { let elt_ty = match self.parse_ty() { Ok(ty) => ty, Err(mut err) - if self.look_ahead(1, |t| t.kind == token::CloseDelim(token::Bracket)) + if self.look_ahead(1, |t| t.kind == token::CloseDelim(Delimiter::Bracket)) | self.look_ahead(1, |t| t.kind == token::Semi) => { // Recover from `[LIT; EXPR]` and `[LIT]` @@ -422,14 +422,14 @@ impl<'a> Parser<'a> { let ty = if self.eat(&token::Semi) { let mut length = self.parse_anon_const_expr()?; - if let Err(e) = self.expect(&token::CloseDelim(token::Bracket)) { + if let Err(e) = self.expect(&token::CloseDelim(Delimiter::Bracket)) { // Try to recover from `X` when `X::` works self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?; - self.expect(&token::CloseDelim(token::Bracket))?; + self.expect(&token::CloseDelim(Delimiter::Bracket))?; } TyKind::Array(elt_ty, length) } else { - self.expect(&token::CloseDelim(token::Bracket))?; + self.expect(&token::CloseDelim(Delimiter::Bracket))?; TyKind::Slice(elt_ty) }; @@ -492,9 +492,9 @@ impl<'a> Parser<'a> { // Parses the `typeof(EXPR)`. // To avoid ambiguity, the type is surrounded by parentheses. fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> { - self.expect(&token::OpenDelim(token::Paren))?; + self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; let expr = self.parse_anon_const_expr()?; - self.expect(&token::CloseDelim(token::Paren))?; + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; Ok(TyKind::Typeof(expr)) } @@ -672,7 +672,7 @@ impl<'a> Parser<'a> { || self.check(&token::Question) || self.check(&token::Tilde) || self.check_keyword(kw::For) - || self.check(&token::OpenDelim(token::Paren)) + || self.check(&token::OpenDelim(Delimiter::Parenthesis)) } fn error_negative_bounds( @@ -713,7 +713,7 @@ impl<'a> Parser<'a> { fn parse_generic_bound(&mut self) -> PResult<'a, Result> { let anchor_lo = self.prev_token.span; let lo = self.token.span; - let has_parens = self.eat(&token::OpenDelim(token::Paren)); + let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis)); let inner_lo = self.token.span; let is_negative = self.eat(&token::Not); @@ -766,7 +766,7 @@ impl<'a> Parser<'a> { /// Recover on `('lifetime)` with `(` already eaten. fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> { let inner_span = inner_lo.to(self.prev_token.span); - self.expect(&token::CloseDelim(token::Paren))?; + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let mut err = self.struct_span_err( lo.to(self.prev_token.span), "parenthesized lifetime bounds are not supported", @@ -829,7 +829,7 @@ impl<'a> Parser<'a> { // suggestion is given. let bounds = vec![]; self.parse_remaining_bounds(bounds, true)?; - self.expect(&token::CloseDelim(token::Paren))?; + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let sp = vec![lo, self.prev_token.span]; let sugg: Vec<_> = sp.iter().map(|sp| (*sp, String::new())).collect(); self.struct_span_err(sp, "incorrect braces around trait bounds") @@ -840,7 +840,7 @@ impl<'a> Parser<'a> { ) .emit(); } else { - self.expect(&token::CloseDelim(token::Paren))?; + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; } } diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 8064c217457bb..db755ccd1d515 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -1,6 +1,6 @@ use crate::parse::ParseSess; use crate::session::Session; -use rustc_ast::token::{self, DelimToken, Nonterminal, Token}; +use rustc_ast::token::{self, Delimiter, Nonterminal, Token}; use rustc_ast::tokenstream::CanSynthesizeMissingTokens; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_data_structures::profiling::VerboseTimingGuard; @@ -137,7 +137,7 @@ impl<'a> FlattenNonterminals<'a> { let tts = (self.nt_to_tokenstream)(&nt, self.parse_sess, self.synthesize_tokens); TokenTree::Delimited( DelimSpan::from_single(token.span), - DelimToken::NoDelim, + Delimiter::Invisible, self.process_token_stream(tts), ) .into() diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 00b8bb1eb2637..f1c5eaad868e9 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -704,10 +704,10 @@ pub enum Delimiter { #[stable(feature = "proc_macro_lib2", since = "1.29.0")] Bracket, /// `Ø ... Ø` - /// An implicit delimiter, that may, for example, appear around tokens coming from a + /// An invisible delimiter, that may, for example, appear around tokens coming from a /// "macro variable" `$var`. It is important to preserve operator priorities in cases like /// `$var * 3` where `$var` is `1 + 2`. - /// Implicit delimiters might not survive roundtrip of a token stream through a string. + /// Invisible delimiters might not survive roundtrip of a token stream through a string. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] None, } diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 58ca8869ea9d7..a9c0fe6f07971 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{self, BinOpToken, DelimToken}; +use rustc_ast::token::{self, BinOpToken, Delimiter}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast_pretty::pprust::state::State as Printer; use rustc_ast_pretty::pprust::PrintState; @@ -104,11 +104,11 @@ fn print_tt(printer: &mut Printer<'_>, tt: &TokenTree) { let open_delim = printer.token_kind_to_string(&token::OpenDelim(*delim)); printer.word(open_delim); if !tts.is_empty() { - if *delim == DelimToken::Brace { + if *delim == Delimiter::Brace { printer.space(); } print_tts(printer, tts); - if *delim == DelimToken::Brace { + if *delim == Delimiter::Brace { printer.space(); } } @@ -162,9 +162,9 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { (_, _) => (true, Other), }, TokenTree::Delimited(_, delim, _) => match (state, delim) { - (Dollar, DelimToken::Paren) => (false, DollarParen), - (Pound | PoundBang, DelimToken::Bracket) => (false, Other), - (Ident, DelimToken::Paren | DelimToken::Bracket) => (false, Other), + (Dollar, Delimiter::Parenthesis) => (false, DollarParen), + (Pound | PoundBang, Delimiter::Bracket) => (false, Other), + (Ident, Delimiter::Parenthesis | Delimiter::Bracket) => (false, Other), (_, _) => (true, Other), }, }; diff --git a/src/test/ui/proc-macro/nodelim-groups.rs b/src/test/ui/proc-macro/nodelim-groups.rs index db2a879f40504..ec30199028142 100644 --- a/src/test/ui/proc-macro/nodelim-groups.rs +++ b/src/test/ui/proc-macro/nodelim-groups.rs @@ -3,7 +3,7 @@ // compile-flags: -Z span-debug // edition:2018 // -// Tests the pretty-printing behavior of inserting `NoDelim` groups +// Tests the pretty-printing behavior of inserting `Invisible`-delimited groups #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index cd724373f4d16..741f3350801db 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::{DelimToken, LitKind}; +use rustc_ast::token::{Delimiter, LitKind}; use rustc_ast::{ast, ptr}; use rustc_span::{BytePos, Span}; @@ -412,7 +412,7 @@ pub(crate) fn rewrite_array<'a, T: 'a + IntoOverflowableItem<'a>>( context: &'a RewriteContext<'_>, shape: Shape, force_separator_tactic: Option, - delim_token: Option, + delim_token: Option, ) -> Option { overflow::rewrite_with_square_brackets( context, diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 92606902c5789..26c429eb94ff3 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; use std::panic::{catch_unwind, AssertUnwindSafe}; -use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; +use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; @@ -203,7 +203,7 @@ fn rewrite_macro_inner( let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&¯o_name[..]); let style = if is_forced_bracket && !is_nested_macro { - DelimToken::Bracket + Delimiter::Bracket } else { original_style }; @@ -212,15 +212,15 @@ fn rewrite_macro_inner( let has_comment = contains_comment(context.snippet(mac.span())); if ts.is_empty() && !has_comment { return match style { - DelimToken::Paren if position == MacroPosition::Item => { + Delimiter::Parenthesis if position == MacroPosition::Item => { Some(format!("{}();", macro_name)) } - DelimToken::Bracket if position == MacroPosition::Item => { + Delimiter::Bracket if position == MacroPosition::Item => { Some(format!("{}[];", macro_name)) } - DelimToken::Paren => Some(format!("{}()", macro_name)), - DelimToken::Bracket => Some(format!("{}[]", macro_name)), - DelimToken::Brace => Some(format!("{} {{}}", macro_name)), + Delimiter::Parenthesis => Some(format!("{}()", macro_name)), + Delimiter::Bracket => Some(format!("{}[]", macro_name)), + Delimiter::Brace => Some(format!("{} {{}}", macro_name)), _ => unreachable!(), }; } @@ -260,7 +260,7 @@ fn rewrite_macro_inner( } match style { - DelimToken::Paren => { + Delimiter::Parenthesis => { // Handle special case: `vec!(expr; expr)` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -286,7 +286,7 @@ fn rewrite_macro_inner( }) } } - DelimToken::Bracket => { + Delimiter::Bracket => { // Handle special case: `vec![expr; expr]` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -323,7 +323,7 @@ fn rewrite_macro_inner( Some(format!("{}{}", rewrite, comma)) } } - DelimToken::Brace => { + Delimiter::Brace => { // For macro invocations with braces, always put a space between // the `macro_name!` and `{ /* macro_body */ }` but skip modifying // anything in between the braces (for now). @@ -342,11 +342,11 @@ fn handle_vec_semi( shape: Shape, arg_vec: Vec, macro_name: String, - delim_token: DelimToken, + delim_token: Delimiter, ) -> Option { let (left, right) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), _ => unreachable!(), }; @@ -528,7 +528,7 @@ enum MacroArgKind { /// e.g., `$($foo: expr),*` Repeat( /// `()`, `[]` or `{}`. - DelimToken, + Delimiter, /// Inner arguments inside delimiters. Vec, /// Something after the closing delimiter and the repeat token, if available. @@ -537,7 +537,7 @@ enum MacroArgKind { Token, ), /// e.g., `[derive(Debug)]` - Delimited(DelimToken, Vec), + Delimited(Delimiter, Vec), /// A possible separator. e.g., `,` or `;`. Separator(String, String), /// Other random stuff that does not fit to other kinds. @@ -547,22 +547,22 @@ enum MacroArgKind { fn delim_token_to_str( context: &RewriteContext<'_>, - delim_token: DelimToken, + delim_token: Delimiter, shape: Shape, use_multiple_lines: bool, inner_is_empty: bool, ) -> (String, String) { let (lhs, rhs) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => { + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => { if inner_is_empty || use_multiple_lines { ("{", "}") } else { ("{ ", " }") } } - DelimToken::NoDelim => unreachable!(), + Delimiter::Invisible => unreachable!(), }; if use_multiple_lines { let indent_str = shape.indent.to_string_with_newline(context.config); @@ -583,8 +583,8 @@ impl MacroArgKind { fn starts_with_brace(&self) -> bool { matches!( *self, - MacroArgKind::Repeat(DelimToken::Brace, _, _, _) - | MacroArgKind::Delimited(DelimToken::Brace, _) + MacroArgKind::Repeat(Delimiter::Brace, _, _, _) + | MacroArgKind::Delimited(Delimiter::Brace, _) ) } @@ -753,7 +753,7 @@ impl MacroArgParser { } } - fn add_delimited(&mut self, inner: Vec, delim: DelimToken) { + fn add_delimited(&mut self, inner: Vec, delim: Delimiter) { self.result.push(ParsedMacroArg { kind: MacroArgKind::Delimited(delim, inner), }); @@ -763,7 +763,7 @@ impl MacroArgParser { fn add_repeat( &mut self, inner: Vec, - delim: DelimToken, + delim: Delimiter, iter: &mut Cursor, ) -> Option<()> { let mut buffer = String::new(); @@ -1083,18 +1083,18 @@ pub(crate) fn convert_try_mac( } } -pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> DelimToken { +pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> Delimiter { let snippet = context.snippet(mac.span()); let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value()); let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value()); let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value()); if paren_pos < bracket_pos && paren_pos < brace_pos { - DelimToken::Paren + Delimiter::Parenthesis } else if bracket_pos < brace_pos { - DelimToken::Bracket + Delimiter::Bracket } else { - DelimToken::Brace + Delimiter::Brace } } @@ -1174,7 +1174,7 @@ struct Macro { // rather than clone them, if we can make the borrowing work out. struct MacroBranch { span: Span, - args_paren_kind: DelimToken, + args_paren_kind: Delimiter, args: TokenStream, body: Span, whole_body: Span, @@ -1188,7 +1188,7 @@ impl MacroBranch { multi_branch_style: bool, ) -> Option { // Only attempt to format function-like macros. - if self.args_paren_kind != DelimToken::Paren { + if self.args_paren_kind != Delimiter::Parenthesis { // FIXME(#1539): implement for non-sugared macros. return None; } @@ -1350,18 +1350,18 @@ fn rewrite_macro_with_items( items: &[MacroArg], macro_name: &str, shape: Shape, - style: DelimToken, + style: Delimiter, position: MacroPosition, span: Span, ) -> Option { let (opener, closer) = match style { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => (" {", "}"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => (" {", "}"), _ => return None, }; let trailing_semicolon = match style { - DelimToken::Paren | DelimToken::Bracket if position == MacroPosition::Item => ";", + Delimiter::Parenthesis | Delimiter::Bracket if position == MacroPosition::Item => ";", _ => "", }; diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs index 80aed998d7377..f115e7d026182 100644 --- a/src/tools/rustfmt/src/overflow.rs +++ b/src/tools/rustfmt/src/overflow.rs @@ -3,7 +3,7 @@ use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::DelimToken; +use rustc_ast::token::Delimiter; use rustc_ast::{ast, ptr}; use rustc_span::Span; @@ -297,11 +297,11 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>> shape: Shape, span: Span, force_separator_tactic: Option, - delim_token: Option, + delim_token: Option, ) -> Option { let (lhs, rhs) = match delim_token { - Some(DelimToken::Paren) => ("(", ")"), - Some(DelimToken::Brace) => ("{", "}"), + Some(Delimiter::Parenthesis) => ("(", ")"), + Some(Delimiter::Brace) => ("{", "}"), _ => ("[", "]"), }; Context::new( diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs index 306b6bb745ee6..09b3e32df312d 100644 --- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs +++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs @@ -1,7 +1,7 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use rustc_ast::ast; -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -47,11 +47,11 @@ fn parse_cfg_if_inner<'a>( .map_err(|_| "Failed to parse attributes")?; } - if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { return Err("Expected an opening brace"); } - while parser.token != TokenKind::CloseDelim(DelimToken::Brace) + while parser.token != TokenKind::CloseDelim(Delimiter::Brace) && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { @@ -70,7 +70,7 @@ fn parse_cfg_if_inner<'a>( } } - if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::CloseDelim(Delimiter::Brace)) { return Err("Expected a closing brace"); } diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index 3728f3a19b44f..d4dbf21f8cab7 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser}; @@ -81,7 +81,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { && parser.look_ahead(1, |t| { t.kind == TokenKind::Eof || t.kind == TokenKind::Comma - || t.kind == TokenKind::CloseDelim(DelimToken::NoDelim) + || t.kind == TokenKind::CloseDelim(Delimiter::Invisible) }) { parser.bump(); @@ -97,7 +97,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { pub(crate) fn parse_macro_args( context: &RewriteContext<'_>, tokens: TokenStream, - style: DelimToken, + style: Delimiter, forced_bracket: bool, ) -> Option { let mut parser = build_parser(context, tokens); @@ -105,7 +105,7 @@ pub(crate) fn parse_macro_args( let mut vec_with_semi = false; let mut trailing_comma = false; - if DelimToken::Brace != style { + if Delimiter::Brace != style { loop { if let Some(arg) = check_keyword(&mut parser) { args.push(arg); diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 1621eb406b10f..f04fb2e0446c2 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -1,7 +1,7 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; -use rustc_ast::{ast, token::DelimToken, visit, AstLike}; +use rustc_ast::{ast, token::Delimiter, visit, AstLike}; use rustc_data_structures::sync::Lrc; use rustc_span::{symbol, BytePos, Pos, Span}; @@ -689,7 +689,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc) ;`) // are formatted correctly. let (span, rewrite) = match macro_style(mac, &self.get_context()) { - DelimToken::Bracket | DelimToken::Paren if MacroPosition::Item == pos => { + Delimiter::Bracket | Delimiter::Parenthesis if MacroPosition::Item == pos => { let search_span = mk_sp(mac.span().hi(), self.snippet_provider.end_pos()); let hi = self.snippet_provider.span_before(search_span, ";"); let target_span = mk_sp(mac.span().lo(), hi + BytePos(1));