From 95b4c07ef897974a8978b4a43d0d98103a824f58 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 3 Jun 2024 15:47:46 +1000 Subject: Reduce `pub` exposure. --- compiler/rustc_parse/src/parser/diagnostics.rs | 26 +++++++++------- compiler/rustc_parse/src/parser/expr.rs | 8 +++-- compiler/rustc_parse/src/parser/item.rs | 4 +-- compiler/rustc_parse/src/parser/mod.rs | 43 +++++++++++++------------- compiler/rustc_parse/src/parser/path.rs | 2 +- compiler/rustc_parse/src/parser/stmt.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 2 +- 7 files changed, 48 insertions(+), 39 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9677eea0604..2bb6fb53869 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -130,14 +130,14 @@ pub enum AttemptLocalParseRecovery { } impl AttemptLocalParseRecovery { - pub fn yes(&self) -> bool { + pub(super) fn yes(&self) -> bool { match self { AttemptLocalParseRecovery::Yes => true, AttemptLocalParseRecovery::No => false, } } - pub fn no(&self) -> bool { + pub(super) fn no(&self) -> bool { match self { AttemptLocalParseRecovery::Yes => false, AttemptLocalParseRecovery::No => true, @@ -891,7 +891,7 @@ impl<'a> Parser<'a> { } } - pub fn maybe_suggest_struct_literal( + pub(super) fn maybe_suggest_struct_literal( &mut self, lo: Span, s: BlockCheckMode, @@ -2459,7 +2459,7 @@ impl<'a> Parser<'a> { /// Handle encountering a symbol in a generic argument list that is not a `,` or `>`. In this /// case, we emit an error and try to suggest enclosing a const argument in braces if it looks /// like the user has forgotten them. - pub fn handle_ambiguous_unbraced_const_arg( + pub(super) fn handle_ambiguous_unbraced_const_arg( &mut self, args: &mut ThinVec, ) -> PResult<'a, bool> { @@ -2500,7 +2500,7 @@ impl<'a> Parser<'a> { /// - Single-segment paths (i.e. standalone generic const parameters). /// All other expressions that can be parsed will emit an error suggesting the expression be /// wrapped in braces. - pub fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P> { + pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P> { let start = self.token.span; let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| { err.span_label( @@ -2559,7 +2559,7 @@ impl<'a> Parser<'a> { Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })) } - pub fn recover_const_param_declaration( + pub(super) fn recover_const_param_declaration( &mut self, ty_generics: Option<&Generics>, ) -> PResult<'a, Option> { @@ -2589,7 +2589,11 @@ impl<'a> Parser<'a> { /// When encountering code like `foo::< bar + 3 >` or `foo::< bar - baz >` we suggest /// `foo::<{ bar + 3 }>` and `foo::<{ bar - baz }>`, respectively. We only provide a suggestion /// if we think that the resulting expression would be well formed. - pub fn recover_const_arg(&mut self, start: Span, mut err: Diag<'a>) -> PResult<'a, GenericArg> { + pub(super) fn recover_const_arg( + &mut self, + start: Span, + mut err: Diag<'a>, + ) -> PResult<'a, GenericArg> { let is_op_or_dot = AssocOp::from_token(&self.token) .and_then(|op| { if let AssocOp::Greater @@ -2690,7 +2694,7 @@ impl<'a> Parser<'a> { } /// Creates a dummy const argument, and reports that the expression must be enclosed in braces - pub fn dummy_const_arg_needs_braces(&self, mut err: Diag<'a>, span: Span) -> GenericArg { + pub(super) fn dummy_const_arg_needs_braces(&self, mut err: Diag<'a>, span: Span) -> GenericArg { err.multipart_suggestion( "expressions must be enclosed in braces to be used as const generic \ arguments", @@ -2961,7 +2965,7 @@ impl<'a> Parser<'a> { /// * `=====` /// * `<<<<<` /// - pub fn is_vcs_conflict_marker( + pub(super) fn is_vcs_conflict_marker( &mut self, long_kind: &TokenKind, short_kind: &TokenKind, @@ -2981,14 +2985,14 @@ impl<'a> Parser<'a> { None } - pub fn recover_vcs_conflict_marker(&mut self) { + pub(super) fn recover_vcs_conflict_marker(&mut self) { if let Err(err) = self.err_vcs_conflict_marker() { err.emit(); FatalError.raise(); } } - pub fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { + pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) else { return Ok(()); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1b99bc015b6..5a39248e49a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -445,7 +445,7 @@ impl<'a> Parser<'a> { /// The method does not advance the current token. /// /// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively. - pub fn check_assoc_op(&self) -> Option> { + pub(super) fn check_assoc_op(&self) -> Option> { let (op, span) = match (AssocOp::from_token(&self.token), self.token.ident()) { // When parsing const expressions, stop parsing when encountering `>`. ( @@ -1022,7 +1022,11 @@ impl<'a> Parser<'a> { } } - pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P) -> PResult<'a, P> { + pub(super) fn parse_dot_suffix_expr( + &mut self, + lo: Span, + base: P, + ) -> PResult<'a, P> { // At this point we've consumed something like `expr.` and `self.token` holds the token // after the dot. match self.token.uninterpolate().kind { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 53757c38e8b..fcafa243215 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2256,7 +2256,7 @@ pub(crate) struct FnParseMode { /// to true. /// * The span is from Edition 2015. In particular, you can get a /// 2015 span inside a 2021 crate using macros. - pub req_name: ReqName, + pub(super) req_name: ReqName, /// If this flag is set to `true`, then plain, semicolon-terminated function /// prototypes are not allowed here. /// @@ -2275,7 +2275,7 @@ pub(crate) struct FnParseMode { /// This field should only be set to false if the item is inside of a trait /// definition or extern block. Within an impl block or a module, it should /// always be set to true. - pub req_body: bool, + pub(super) req_body: bool, } /// Parsing of functions and methods. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index bab8b6c06eb..d00dbe3a4a6 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -11,14 +11,13 @@ mod stmt; mod ty; use crate::lexer::UnmatchedDelim; -pub use attr_wrapper::AttrWrapper; +use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; pub(crate) use expr::ForbiddenLetReason; pub(crate) use item::FnParseMode; pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma}; -pub use path::PathStyle; +use path::PathStyle; -use core::fmt; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing}; @@ -37,7 +36,7 @@ use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use std::ops::Range; -use std::{mem, slice}; +use std::{fmt, mem, slice}; use thin_vec::ThinVec; use tracing::debug; @@ -146,7 +145,7 @@ pub struct Parser<'a> { /// The current token. pub token: Token, /// The spacing for the current token. - pub token_spacing: Spacing, + token_spacing: Spacing, /// The previous token. pub prev_token: Token, pub capture_cfg: bool, @@ -187,7 +186,7 @@ pub struct Parser<'a> { current_closure: Option, /// Whether the parser is allowed to do recovery. /// This is disabled when parsing macro arguments, see #103534 - pub recovery: Recovery, + recovery: Recovery, } // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure @@ -197,10 +196,10 @@ rustc_data_structures::static_assert_size!(Parser<'_>, 264); /// Stores span information about a closure. #[derive(Clone, Debug)] -pub struct ClosureSpans { - pub whole_closure: Span, - pub closing_pipe: Span, - pub body: Span, +struct ClosureSpans { + whole_closure: Span, + closing_pipe: Span, + body: Span, } /// Indicates a range of tokens that should be replaced by @@ -220,13 +219,13 @@ pub struct ClosureSpans { /// the first macro inner attribute to invoke a proc-macro). /// When create a `TokenStream`, the inner attributes get inserted /// into the proper place in the token stream. -pub type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>); +type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>); /// Controls how we capture tokens. Capturing can be expensive, /// so we try to avoid performing capturing in cases where /// we will never need an `AttrTokenStream`. #[derive(Copy, Clone, Debug)] -pub enum Capturing { +enum Capturing { /// We aren't performing any capturing - this is the default mode. No, /// We are capturing tokens @@ -374,13 +373,13 @@ pub enum FollowedByType { } #[derive(Copy, Clone, Debug)] -pub enum Trailing { +enum Trailing { No, Yes, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum TokenDescription { +pub(super) enum TokenDescription { ReservedIdentifier, Keyword, ReservedKeyword, @@ -388,7 +387,7 @@ pub enum TokenDescription { } impl TokenDescription { - pub fn from_token(token: &Token) -> Option { + pub(super) fn from_token(token: &Token) -> Option { match token.kind { _ if token.is_special_ident() => Some(TokenDescription::ReservedIdentifier), _ if token.is_used_keyword() => Some(TokenDescription::Keyword), @@ -502,7 +501,7 @@ impl<'a> Parser<'a> { /// Expect next token to be edible or inedible token. If edible, /// then consume it; if inedible, then return without consuming /// anything. Signal a fatal error if next token is unexpected. - pub fn expect_one_of( + fn expect_one_of( &mut self, edible: &[TokenKind], inedible: &[TokenKind], @@ -572,7 +571,7 @@ impl<'a> Parser<'a> { /// the main purpose of this function is to reduce the cluttering of the suggestions list /// which using the normal eat method could introduce in some cases. #[inline] - pub fn eat_noexpect(&mut self, tok: &TokenKind) -> bool { + fn eat_noexpect(&mut self, tok: &TokenKind) -> bool { let is_present = self.check_noexpect(tok); if is_present { self.bump() @@ -1515,7 +1514,7 @@ impl<'a> Parser<'a> { } } - pub fn collect_tokens_no_attrs( + fn collect_tokens_no_attrs( &mut self, f: impl FnOnce(&mut Self) -> PResult<'a, R>, ) -> PResult<'a, R> { @@ -1536,8 +1535,10 @@ impl<'a> Parser<'a> { }) } - // debug view of the parser's token stream, up to `{lookahead}` tokens - pub fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ { + // Debug view of the parser's token stream, up to `{lookahead}` tokens. + // Only used when debugging. + #[allow(unused)] + pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ { struct DebugParser<'dbg> { parser: &'dbg Parser<'dbg>, lookahead: usize, @@ -1613,7 +1614,7 @@ pub(crate) fn make_unclosed_delims_error( /// is then 'parsed' to build up an `AttrTokenStream` with nested /// `AttrTokenTree::Delimited` tokens. #[derive(Debug, Clone)] -pub enum FlatToken { +enum FlatToken { /// A token - this holds both delimiter (e.g. '{' and '}') /// and non-delimiter tokens Token(Token), diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index fcedc1a4af3..9beecd9849f 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -20,7 +20,7 @@ use tracing::debug; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] -pub enum PathStyle { +pub(super) enum PathStyle { /// In some contexts, notably in expressions, paths with generic arguments are ambiguous /// with something else. For example, in expressions `segment < ....` can be interpreted /// as a comparison and `segment ( ....` can be interpreted as a function call. diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index be539d15386..104aae9b257 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -31,7 +31,7 @@ impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. // Public for rustfmt usage. - pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> { + pub(super) fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> { Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| { e.emit(); self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 2033f387887..5bed0317e5e 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -127,7 +127,7 @@ impl<'a> Parser<'a> { /// Parse a type suitable for a field definition. /// The difference from `parse_ty` is that this version /// allows anonymous structs and unions. - pub fn parse_ty_for_field_def(&mut self) -> PResult<'a, P> { + pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P> { if self.can_begin_anon_struct_or_union() { self.parse_anon_struct_or_union() } else { -- cgit 1.4.1-3-g733a5 From 13f2bc9a651abe9cb1711293be7eae8d48169300 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Jun 2024 13:20:43 +1000 Subject: Specialize `assert_pred`. It has only two uses, and both use `matches_codepattern`. So just change it to `assert_matches_codepattern`. --- compiler/rustc_parse/src/parser/mut_visit/tests.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/mut_visit/tests.rs b/compiler/rustc_parse/src/parser/mut_visit/tests.rs index b3cb28af657..677bcdf7fcd 100644 --- a/compiler/rustc_parse/src/parser/mut_visit/tests.rs +++ b/compiler/rustc_parse/src/parser/mut_visit/tests.rs @@ -21,14 +21,12 @@ impl MutVisitor for ToZzIdentMutVisitor { } } -// Maybe add to `expand.rs`. -macro_rules! assert_pred { - ($pred:expr, $predname:expr, $a:expr , $b:expr) => {{ - let pred_val = $pred; +macro_rules! assert_matches_codepattern { + ($a:expr , $b:expr) => {{ let a_val = $a; let b_val = $b; - if !(pred_val(&a_val, &b_val)) { - panic!("expected args satisfying {}, got {} and {}", $predname, a_val, b_val); + if !matches_codepattern(&a_val, &b_val) { + panic!("expected args satisfying `matches_codepattern`, got {} and {}", a_val, b_val); } }}; } @@ -41,9 +39,7 @@ fn ident_transformation() { let mut krate = string_to_crate("#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); zz_visitor.visit_crate(&mut krate); - assert_pred!( - matches_codepattern, - "matches_codepattern", + assert_matches_codepattern!( print_crate_items(&krate), "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string() ); @@ -61,9 +57,7 @@ fn ident_transformation_in_defs() { .to_string(), ); zz_visitor.visit_crate(&mut krate); - assert_pred!( - matches_codepattern, - "matches_codepattern", + assert_matches_codepattern!( print_crate_items(&krate), "macro_rules! zz{(zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+))}".to_string() ); -- cgit 1.4.1-3-g733a5 From 216424da32db1bf0d224b97ff3d0424622c97c4c Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Thu, 6 Jun 2024 20:39:54 +0000 Subject: Revert "Rollup merge of #124099 - voidc:disallow-ambiguous-expr-attrs, r=davidtwco" This reverts commit 57dad1d75e562ff73051c1c43b07eaf65c7dbd74, reversing changes made to 36316df9fe6c3e246153fe6e78967643cf08c148. --- compiler/rustc_parse/messages.ftl | 2 - compiler/rustc_parse/src/errors.rs | 9 ----- compiler/rustc_parse/src/parser/expr.rs | 32 ++++++--------- src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed | 6 +-- src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs | 6 +-- src/tools/rustfmt/tests/source/attrib.rs | 4 +- src/tools/rustfmt/tests/target/attrib.rs | 4 +- tests/pretty/ast-stmt-expr-attr.rs | 18 ++++----- tests/pretty/stmt_expr_attributes.rs | 12 +++--- .../lint/unused/unused-doc-comments-edge-cases.rs | 4 +- .../unused/unused-doc-comments-edge-cases.stderr | 14 +++---- .../attribute/attr-binary-expr-ambigous.fixed | 15 ------- .../parser/attribute/attr-binary-expr-ambigous.rs | 15 ------- .../attribute/attr-binary-expr-ambigous.stderr | 46 ---------------------- tests/ui/proc-macro/issue-81555.rs | 3 +- 15 files changed, 49 insertions(+), 141 deletions(-) delete mode 100644 tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed delete mode 100644 tests/ui/parser/attribute/attr-binary-expr-ambigous.rs delete mode 100644 tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 04f855e4f55..f678d11213c 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -622,8 +622,6 @@ parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allo parse_out_of_range_hex_escape = out of range hex escape .label = must be a character in the range [\x00-\x7f] -parse_outer_attr_ambiguous = ambiguous outer attributes - parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 3f08a830b0c..6c1fcbe06fc 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -495,15 +495,6 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse { pub attributes: Span, } -#[derive(Diagnostic)] -#[diag(parse_outer_attr_ambiguous)] -pub(crate) struct AmbiguousOuterAttributes { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub sugg: WrapInParentheses, -} - #[derive(Diagnostic)] #[diag(parse_missing_in_in_for_loop)] pub(crate) struct MissingInInForLoop { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1b99bc015b6..285bac3f4b8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -328,9 +328,7 @@ impl<'a> Parser<'a> { this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed) })?; - self.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span); - let span = lhs_span.to(rhs.span); - + let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); lhs = match op { AssocOp::Add | AssocOp::Subtract @@ -429,18 +427,6 @@ impl<'a> Parser<'a> { }); } - fn error_ambiguous_outer_attrs(&self, lhs: &P, lhs_span: Span, rhs_span: Span) { - if let Some(attr) = lhs.attrs.iter().find(|a| a.style == AttrStyle::Outer) { - self.dcx().emit_err(errors::AmbiguousOuterAttributes { - span: attr.span.to(rhs_span), - sugg: errors::WrapInParentheses::Expression { - left: attr.span.shrink_to_lo(), - right: lhs_span.shrink_to_hi(), - }, - }); - } - } - /// Possibly translate the current token to an associative operator. /// The method does not advance the current token. /// @@ -520,8 +506,7 @@ impl<'a> Parser<'a> { None }; let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span); - self.error_ambiguous_outer_attrs(&lhs, lhs.span, rhs_span); - let span = lhs.span.to(rhs_span); + let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span); let limits = if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let range = self.mk_range(Some(lhs), rhs, limits); @@ -739,8 +724,7 @@ impl<'a> Parser<'a> { expr_kind: fn(P, P) -> ExprKind, ) -> PResult<'a, P> { let mk_expr = |this: &mut Self, lhs: P, rhs: P| { - this.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span); - this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs)) + this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs)) }; // Save the state of the parser before parsing type normally, in case there is a @@ -3858,6 +3842,16 @@ impl<'a> Parser<'a> { self.mk_expr(span, ExprKind::Err(guar)) } + /// Create expression span ensuring the span of the parent node + /// is larger than the span of lhs and rhs, including the attributes. + fn mk_expr_sp(&self, lhs: &P, lhs_span: Span, rhs_span: Span) -> Span { + lhs.attrs + .iter() + .find(|a| a.style == AttrStyle::Outer) + .map_or(lhs_span, |a| a.span) + .to(rhs_span) + } + fn collect_tokens_for_expr( &mut self, attrs: AttrWrapper, diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed index 84dac431169..05d5b3d10ea 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[rustfmt::skip] - { 5+3; } + 5+3; } #[rustfmt::skip] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+29; } + 1+29; } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[rustfmt::skip] - { 1+30; } + 1+30; } diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs index 4ab5c70e13b..bc29e20210e 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 5+3; } + 5+3; } #[cfg_attr(rustfmt, rustfmt_skip)] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+29; } + 1+29; } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+30; } + 1+30; } diff --git a/src/tools/rustfmt/tests/source/attrib.rs b/src/tools/rustfmt/tests/source/attrib.rs index fc13cd02b03..d45fba55224 100644 --- a/src/tools/rustfmt/tests/source/attrib.rs +++ b/src/tools/rustfmt/tests/source/attrib.rs @@ -214,8 +214,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo ; - (#[must_use] - foo) = false ; + #[must_use] + foo = false ; } // #3509 diff --git a/src/tools/rustfmt/tests/target/attrib.rs b/src/tools/rustfmt/tests/target/attrib.rs index 7b3309676de..7e61f68d76a 100644 --- a/src/tools/rustfmt/tests/target/attrib.rs +++ b/src/tools/rustfmt/tests/target/attrib.rs @@ -248,8 +248,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo; - (#[must_use] - foo) = false; + #[must_use] + foo = false; } // #3509 diff --git a/tests/pretty/ast-stmt-expr-attr.rs b/tests/pretty/ast-stmt-expr-attr.rs index 899f7173f70..fd7272a1b1f 100644 --- a/tests/pretty/ast-stmt-expr-attr.rs +++ b/tests/pretty/ast-stmt-expr-attr.rs @@ -13,17 +13,17 @@ fn syntax() { let _ = #[attr] (); let _ = #[attr] (#[attr] 0,); let _ = #[attr] (#[attr] 0, 0); - let _ = (#[attr] 0) + #[attr] 0; - let _ = (#[attr] 0) / #[attr] 0; - let _ = (#[attr] 0) & #[attr] 0; - let _ = (#[attr] 0) % #[attr] 0; + let _ = #[attr] 0 + #[attr] 0; + let _ = #[attr] 0 / #[attr] 0; + let _ = #[attr] 0 & #[attr] 0; + let _ = #[attr] 0 % #[attr] 0; let _ = #[attr] (0 + 0); let _ = #[attr] !0; let _ = #[attr] -0; let _ = #[attr] false; let _ = #[attr] 0; let _ = #[attr] 'c'; - let _ = (#[attr] x) as Y; + let _ = #[attr] x as Y; let _ = #[attr] (x as Y); let _ = #[attr] while true { @@ -88,9 +88,9 @@ fn syntax() { let _ = (); foo }; - let _ = (#[attr] x) = y; + let _ = #[attr] x = y; let _ = #[attr] (x = y); - let _ = (#[attr] x) += y; + let _ = #[attr] x += y; let _ = #[attr] (x += y); let _ = #[attr] foo.bar; let _ = (#[attr] foo).bar; @@ -98,8 +98,8 @@ fn syntax() { let _ = (#[attr] foo).0; let _ = #[attr] foo[bar]; let _ = (#[attr] foo)[bar]; - let _ = (#[attr] 0)..#[attr] 0; - let _ = (#[attr] 0)..; + let _ = #[attr] 0..#[attr] 0; + let _ = #[attr] 0..; let _ = #[attr] (0..0); let _ = #[attr] (0..); let _ = #[attr] (..0); diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs index f9041268211..e7fd4642724 100644 --- a/tests/pretty/stmt_expr_attributes.rs +++ b/tests/pretty/stmt_expr_attributes.rs @@ -147,13 +147,13 @@ fn _11() { let _ = #[rustc_dummy] (0); let _ = #[rustc_dummy] (0,); let _ = #[rustc_dummy] (0, 0); - let _ = (#[rustc_dummy] 0) + #[rustc_dummy] 0; + let _ = #[rustc_dummy] 0 + #[rustc_dummy] 0; let _ = #[rustc_dummy] !0; let _ = #[rustc_dummy] -0i32; let _ = #[rustc_dummy] false; let _ = #[rustc_dummy] 'c'; let _ = #[rustc_dummy] 0; - let _ = (#[rustc_dummy] 0) as usize; + let _ = #[rustc_dummy] 0 as usize; let _ = #[rustc_dummy] while false { #![rustc_dummy] @@ -208,8 +208,8 @@ fn _11() { }; let const {} = #[rustc_dummy] const {}; let mut x = 0; - let _ = (#[rustc_dummy] x) = 15; - let _ = (#[rustc_dummy] x) += 15; + let _ = #[rustc_dummy] x = 15; + let _ = #[rustc_dummy] x += 15; let s = Foo { data: () }; let _ = #[rustc_dummy] s.data; let _ = (#[rustc_dummy] s).data; @@ -219,8 +219,8 @@ fn _11() { let v = vec!(0); let _ = #[rustc_dummy] v[0]; let _ = (#[rustc_dummy] v)[0]; - let _ = (#[rustc_dummy] 0)..#[rustc_dummy] 0; - let _ = (#[rustc_dummy] 0)..; + let _ = #[rustc_dummy] 0..#[rustc_dummy] 0; + let _ = #[rustc_dummy] 0..; let _ = #[rustc_dummy] (0..0); let _ = #[rustc_dummy] (0..); let _ = #[rustc_dummy] (..0); diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs index 0f9eac93930..ba32fb566e8 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs @@ -20,10 +20,10 @@ fn doc_comment_between_if_else(num: u8) -> bool { } fn doc_comment_on_expr(num: u8) -> bool { - (/// useless doc comment + /// useless doc comment //~^ ERROR: attributes on expressions are experimental //~| ERROR: unused doc comment - num) == 3 + num == 3 } fn doc_comment_on_expr_field() -> bool { diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr index 1ff5c8d8825..c0741174554 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -5,10 +5,10 @@ LL | else { | ^^^^ expected expression error[E0658]: attributes on expressions are experimental - --> $DIR/unused-doc-comments-edge-cases.rs:23:6 + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 | -LL | (/// useless doc comment - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #15701 for more information = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable @@ -32,12 +32,12 @@ LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ error: unused doc comment - --> $DIR/unused-doc-comments-edge-cases.rs:23:6 + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 | -LL | (/// useless doc comment - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | num) == 3 +LL | num == 3 | --- rustdoc does not generate documentation for expressions | = help: use `//` for a plain comment diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed b/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed deleted file mode 100644 index aae71ede771..00000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-rustfix -#![feature(stmt_expr_attributes)] -#![allow(unused_assignments, unused_attributes)] - -fn main() { - let mut x = (#[deprecated] 1) + 2; //~ ERROR ambiguous - - (#[deprecated] x) = 4; //~ ERROR ambiguous - - x = (#[deprecated] 5) as i32; //~ ERROR ambiguous - - let _r = (#[deprecated] 1)..6; //~ ERROR ambiguous - - println!("{}", x); -} diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs b/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs deleted file mode 100644 index 613e01d743b..00000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-rustfix -#![feature(stmt_expr_attributes)] -#![allow(unused_assignments, unused_attributes)] - -fn main() { - let mut x = #[deprecated] 1 + 2; //~ ERROR ambiguous - - #[deprecated] x = 4; //~ ERROR ambiguous - - x = #[deprecated] 5 as i32; //~ ERROR ambiguous - - let _r = #[deprecated] 1..6; //~ ERROR ambiguous - - println!("{}", x); -} diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr b/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr deleted file mode 100644 index 0430570fd49..00000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr +++ /dev/null @@ -1,46 +0,0 @@ -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:6:17 - | -LL | let mut x = #[deprecated] 1 + 2; - | ^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | let mut x = (#[deprecated] 1) + 2; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:8:5 - | -LL | #[deprecated] x = 4; - | ^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | (#[deprecated] x) = 4; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:10:9 - | -LL | x = #[deprecated] 5 as i32; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | x = (#[deprecated] 5) as i32; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:12:14 - | -LL | let _r = #[deprecated] 1..6; - | ^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | let _r = (#[deprecated] 1)..6; - | + + - -error: aborting due to 4 previous errors - diff --git a/tests/ui/proc-macro/issue-81555.rs b/tests/ui/proc-macro/issue-81555.rs index b337ab7ce37..7a61a31952f 100644 --- a/tests/ui/proc-macro/issue-81555.rs +++ b/tests/ui/proc-macro/issue-81555.rs @@ -10,5 +10,6 @@ use test_macros::identity_attr; fn main() { let _x; let y = (); - (#[identity_attr] _x) = y; + #[identity_attr] + _x = y; } -- cgit 1.4.1-3-g733a5 From 67f5dd1ef112c8a87bc3353793cf4c1cece10c2d Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:54:50 -0500 Subject: Parse unsafe attributes --- compiler/rustc_ast/src/ast.rs | 9 +++- compiler/rustc_ast/src/attr/mod.rs | 33 +++++++++---- compiler/rustc_ast/src/mut_visit.rs | 10 ++-- compiler/rustc_ast_lowering/src/expr.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_pretty/src/pprust/state.rs | 6 ++- compiler/rustc_builtin_macros/src/cmdline_attrs.rs | 3 +- compiler/rustc_builtin_macros/src/test_harness.rs | 1 + compiler/rustc_expand/src/build.rs | 6 +-- compiler/rustc_expand/src/expand.rs | 8 +++- compiler/rustc_feature/src/builtin_attrs.rs | 56 ++++++++++++++++++++-- compiler/rustc_feature/src/unstable.rs | 1 + compiler/rustc_parse/src/parser/attr.rs | 35 ++++++++++++-- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + src/librustdoc/clean/cfg/tests.rs | 6 ++- .../feature-gate-unsafe-attributes.rs | 8 ++++ .../feature-gate-unsafe-attributes.stderr | 13 +++++ 19 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-unsafe-attributes.rs create mode 100644 tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 910fbb87697..8cb49a1b760 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -488,6 +488,7 @@ pub struct Crate { /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItem { + pub unsafety: Unsafe, pub path: Path, pub kind: MetaItemKind, pub span: Span, @@ -2823,7 +2824,12 @@ pub struct NormalAttr { impl NormalAttr { pub fn from_ident(ident: Ident) -> Self { Self { - item: AttrItem { path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None }, + item: AttrItem { + unsafety: Unsafe::No, + path: Path::from_ident(ident), + args: AttrArgs::Empty, + tokens: None, + }, tokens: None, } } @@ -2831,6 +2837,7 @@ impl NormalAttr { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { + pub unsafety: Unsafe, pub path: Path, pub args: AttrArgs, // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index d5c9fc960c8..62b7a276219 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,6 +1,8 @@ //! Functions dealing with attributes and meta items. -use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; +use crate::ast::{ + AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Unsafe, +}; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; use crate::ast::{Path, PathSegment, DUMMY_NODE_ID}; @@ -238,7 +240,12 @@ impl AttrItem { } pub fn meta(&self, span: Span) -> Option { - Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span }) + Some(MetaItem { + unsafety: Unsafe::No, + path: self.path.clone(), + kind: self.meta_kind()?, + span, + }) } pub fn meta_kind(&self) -> Option { @@ -371,7 +378,8 @@ impl MetaItem { _ => path.span.hi(), }; let span = path.span.with_hi(hi); - Some(MetaItem { path, kind, span }) + // FIX THIS LATER + Some(MetaItem { unsafety: Unsafe::No, path, kind, span }) } } @@ -555,11 +563,12 @@ pub fn mk_doc_comment( pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, path: Path, args: AttrArgs, span: Span, ) -> Attribute { - mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) + mk_attr_from_item(g, AttrItem { unsafety, path, args, tokens: None }, None, style, span) } pub fn mk_attr_from_item( @@ -577,15 +586,22 @@ pub fn mk_attr_from_item( } } -pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute { +pub fn mk_attr_word( + g: &AttrIdGenerator, + style: AttrStyle, + unsafety: Unsafe, + name: Symbol, + span: Span, +) -> Attribute { let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Empty; - mk_attr(g, style, path, args, span) + mk_attr(g, style, unsafety, path, args, span) } pub fn mk_attr_nested_word( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, outer: Symbol, inner: Symbol, span: Span, @@ -601,12 +617,13 @@ pub fn mk_attr_nested_word( delim: Delimiter::Parenthesis, tokens: inner_tokens, }); - mk_attr(g, style, path, attr_args, span) + mk_attr(g, style, unsafety, path, attr_args, span) } pub fn mk_attr_name_value_str( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, name: Symbol, val: Symbol, span: Span, @@ -621,7 +638,7 @@ pub fn mk_attr_name_value_str( }); let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); - mk_attr(g, style, path, args, span) + mk_attr(g, style, unsafety, path, args, span) } pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a04c648ac73..dfe82309531 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -647,8 +647,10 @@ fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { let Attribute { kind, id: _, style: _, span } = attr; match kind { AttrKind::Normal(normal) => { - let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = - &mut **normal; + let NormalAttr { + item: AttrItem { unsafety: _, path, args, tokens }, + tokens: attr_tokens, + } = &mut **normal; vis.visit_path(path); visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); @@ -678,7 +680,7 @@ fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T } fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { - let MetaItem { path: _, kind, span } = mi; + let MetaItem { unsafety: _, path: _, kind, span } = mi; match kind { MetaItemKind::Word => {} MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), @@ -840,7 +842,7 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { token::NtTy(ty) => vis.visit_ty(ty), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { - let AttrItem { path, args, tokens } = item.deref_mut(); + let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); vis.visit_path(path); visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index eb206a09be3..5fbae6a34e5 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1801,6 +1801,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr = attr::mk_attr_nested_word( &self.tcx.sess.psess.attr_id_generator, AttrStyle::Outer, + Unsafe::No, sym::allow, sym::unreachable_code, self.lower_span(span), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 023dc6d52c3..e4959853d3f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -911,6 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match attr.kind { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { + unsafety: normal.item.unsafety, path: normal.item.path.clone(), args: self.lower_attr_args(&normal.item.args), tokens: None, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index a9dca9b6a29..764d942836c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -561,6 +561,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(mut_ref, "mutable by-reference bindings are experimental"); gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental"); gate_all!(global_registration, "global registration is experimental"); + gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index ca26b436b82..e3ccbbe391e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -16,7 +16,7 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Unsafe}; use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -249,6 +249,7 @@ pub fn print_crate<'a>( let fake_attr = attr::mk_attr_nested_word( g, ast::AttrStyle::Inner, + Unsafe::No, sym::feature, sym::prelude_import, DUMMY_SP, @@ -259,7 +260,8 @@ pub fn print_crate<'a>( // root, so this is not needed, and actually breaks things. if edition.is_rust_2015() { // `#![no_std]` - let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP); + let fake_attr = + attr::mk_attr_word(g, ast::AttrStyle::Inner, Unsafe::No, sym::no_std, DUMMY_SP); s.print_attribute(&fake_attr); } } diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index e9b63b4abeb..16184ec7511 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -17,7 +17,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { )); let start_span = parser.token.span; - let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) { + let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) { Ok(ai) => ai, Err(err) => { err.emit(); @@ -33,6 +33,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { krate.attrs.push(mk_attr( &psess.attr_id_generator, AttrStyle::Inner, + unsafety, path, args, start_span.to(end_span), diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 38ac2f15fe7..fec54cfe38f 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -203,6 +203,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let allow_dead_code = attr::mk_attr_nested_word( &self.sess.psess.attr_id_generator, ast::AttrStyle::Outer, + ast::Unsafe::No, sym::allow, sym::dead_code, self.def_site, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b3d41908260..9451102c010 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -666,7 +666,7 @@ impl<'a> ExtCtxt<'a> { // Builds `#[name]`. pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_word(g, ast::AttrStyle::Outer, name, span) + attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, span) } // Builds `#[name = val]`. @@ -674,12 +674,12 @@ impl<'a> ExtCtxt<'a> { // Note: `span` is used for both the identifier and the value. pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span) + attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, val, span) } // Builds `#[outer(inner)]`. pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, outer, inner, span) + attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, outer, inner, span) } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index d8f0f221189..77cb617eb33 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -778,7 +778,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if let SyntaxExtensionKind::Derive(..) = ext { self.gate_proc_macro_input(&item); } - let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path }; + // FIX THIS LATER + let meta = ast::MetaItem { + unsafety: ast::Unsafe::No, + kind: MetaItemKind::Word, + span, + path, + }; let items = match expander.expand(self.cx, span, &meta, item, is_const) { ExpandResult::Ready(items) => items, ExpandResult::Retry(item) => { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8b7e93fd555..edfda9bf066 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -59,6 +59,17 @@ pub enum AttributeType { CrateLevel, } +#[derive(Copy, Clone, PartialEq, Debug)] +#[allow(dead_code)] +pub enum AttributeSafety { + /// Normal attribute that does not need `#[unsafe(...)]` + Normal, + + /// Unsafe attribute that requires safety obligations + /// to be discharged + Unsafe, +} + #[derive(Clone, Copy)] pub enum AttributeGate { /// Is gated by a given feature gate, reason @@ -177,6 +188,18 @@ macro_rules! ungated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, + template: $tpl, + gate: Ungated, + duplicates: $duplicates, + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, template: $tpl, gate: Ungated, duplicates: $duplicates, @@ -190,6 +213,7 @@ macro_rules! gated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), @@ -200,6 +224,29 @@ macro_rules! gated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, + template: $tpl, + duplicates: $duplicates, + gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, + template: $tpl, + duplicates: $duplicates, + gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), @@ -228,6 +275,7 @@ macro_rules! rustc_attr { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), @@ -258,6 +306,7 @@ pub struct BuiltinAttribute { /// Otherwise, it can only be used in the local crate. pub encode_cross_crate: EncodeCrossCrate, pub type_: AttributeType, + pub safety: AttributeSafety, pub template: AttributeTemplate, pub duplicates: AttributeDuplicates, pub gate: AttributeGate, @@ -375,9 +424,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No), - ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), - ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), - ungated!(no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), + ungated!(unsafe export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), + ungated!(unsafe link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), + ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No), ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes), @@ -850,6 +899,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`. encode_cross_crate: EncodeCrossCrate::Yes, type_: Normal, + safety: AttributeSafety::Normal, template: template!(NameValueStr: "name"), duplicates: ErrorFollowing, gate: Gated( diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8add2b92761..83a50f017d3 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -623,6 +623,7 @@ declare_features! ( /// Allows unsafe on extern declarations and safety qualifiers over internal items. (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), /// Allows unsized fn parameters. + (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)), (unstable, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. (incomplete, unsized_locals, "1.30.0", Some(48055)), diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 4acc610d8c4..2dd19f6c20a 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -7,7 +7,7 @@ use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Delimiter}; use rustc_errors::{codes::*, Diag, PResult}; -use rustc_span::{sym, BytePos, Span}; +use rustc_span::{sym, symbol::kw, BytePos, Span}; use thin_vec::ThinVec; use tracing::debug; @@ -252,9 +252,23 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtMeta, |attr| attr.into_inner()); let do_parse = |this: &mut Self| { + let is_unsafe = this.eat_keyword(kw::Unsafe); + let unsafety = if is_unsafe { + let unsafe_span = this.prev_token.span; + this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); + this.expect(&token::OpenDelim(Delimiter::Parenthesis))?; + + ast::Unsafe::Yes(unsafe_span) + } else { + ast::Unsafe::No + }; + let path = this.parse_path(PathStyle::Mod)?; let args = this.parse_attr_args()?; - Ok(ast::AttrItem { path, args, tokens: None }) + if is_unsafe { + this.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + } + Ok(ast::AttrItem { unsafety, path, args, tokens: None }) }; // Attr items don't have attributes if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) } @@ -375,10 +389,25 @@ impl<'a> Parser<'a> { } let lo = self.token.span; + let is_unsafe = self.eat_keyword(kw::Unsafe); + let unsafety = if is_unsafe { + let unsafe_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); + self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; + + ast::Unsafe::Yes(unsafe_span) + } else { + ast::Unsafe::No + }; + let path = self.parse_path(PathStyle::Mod)?; let kind = self.parse_meta_item_kind()?; + if is_unsafe { + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + } let span = lo.to(self.prev_token.span); - Ok(ast::MetaItem { path, kind, span }) + + Ok(ast::MetaItem { unsafety, path, kind, span }) } pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index b91ef1ae1f3..58342ff8290 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -42,6 +42,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> { let item = attr.get_normal_item(); Ok(MetaItem { + unsafety: item.unsafety, span: attr.span, path: item.path.clone(), kind: match &item.args { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f530d1dd1d4..93594264167 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1962,6 +1962,7 @@ symbols! { unreachable_display, unreachable_macro, unrestricted_attribute_tokens, + unsafe_attributes, unsafe_block_in_unsafe_fn, unsafe_cell, unsafe_cell_raw_get, diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 20bcf1abf41..2579c15fc5f 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::{MetaItemLit, Path, StrStyle}; +use rustc_ast::{MetaItemLit, Path, StrStyle, Unsafe}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident}; use rustc_span::DUMMY_SP; @@ -16,6 +16,7 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { fn dummy_meta_item_word(name: &str) -> MetaItem { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::Word, span: DUMMY_SP, @@ -25,6 +26,7 @@ fn dummy_meta_item_word(name: &str) -> MetaItem { fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem { let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::NameValue(lit), span: DUMMY_SP, @@ -34,6 +36,7 @@ fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> Meta macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( @@ -48,6 +51,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs b/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs new file mode 100644 index 00000000000..9eba415dda0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs @@ -0,0 +1,8 @@ +#[unsafe(no_mangle)] //~ ERROR [E0658] +extern "C" fn foo() { + +} + +fn main() { + foo(); +} diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr b/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr new file mode 100644 index 00000000000..dfcea756b02 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr @@ -0,0 +1,13 @@ +error[E0658]: `#[unsafe()]` markers for attributes are experimental + --> $DIR/feature-gate-unsafe-attributes.rs:1:3 + | +LL | #[unsafe(no_mangle)] + | ^^^^^^ + | + = note: see issue #123757 for more information + = help: add `#![feature(unsafe_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From 87be1bae73586eaf917790f10ac2240186cb7b2b Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Tue, 21 May 2024 08:37:05 -0500 Subject: Fix build --- compiler/rustc_ast/src/ast.rs | 6 +++--- compiler/rustc_ast/src/attr/mod.rs | 14 +++++++------- compiler/rustc_ast_lowering/src/expr.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +++--- compiler/rustc_builtin_macros/src/derive.rs | 6 +++--- compiler/rustc_builtin_macros/src/test_harness.rs | 2 +- compiler/rustc_expand/src/build.rs | 6 +++--- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_parse/src/parser/attr.rs | 8 ++++---- compiler/rustc_passes/src/check_attr.rs | 2 +- src/librustdoc/clean/cfg/tests.rs | 10 +++++----- 11 files changed, 32 insertions(+), 32 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8cb49a1b760..957c4d7c698 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -488,7 +488,7 @@ pub struct Crate { /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItem { - pub unsafety: Unsafe, + pub unsafety: Safety, pub path: Path, pub kind: MetaItemKind, pub span: Span, @@ -2825,7 +2825,7 @@ impl NormalAttr { pub fn from_ident(ident: Ident) -> Self { Self { item: AttrItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None, @@ -2837,7 +2837,7 @@ impl NormalAttr { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { - pub unsafety: Unsafe, + pub unsafety: Safety, pub path: Path, pub args: AttrArgs, // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 62b7a276219..ed1b4733820 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,7 +1,7 @@ //! Functions dealing with attributes and meta items. use crate::ast::{ - AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Unsafe, + AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Safety, }; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; @@ -241,7 +241,7 @@ impl AttrItem { pub fn meta(&self, span: Span) -> Option { Some(MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: self.path.clone(), kind: self.meta_kind()?, span, @@ -379,7 +379,7 @@ impl MetaItem { }; let span = path.span.with_hi(hi); // FIX THIS LATER - Some(MetaItem { unsafety: Unsafe::No, path, kind, span }) + Some(MetaItem { unsafety: Safety::Default, path, kind, span }) } } @@ -563,7 +563,7 @@ pub fn mk_doc_comment( pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, path: Path, args: AttrArgs, span: Span, @@ -589,7 +589,7 @@ pub fn mk_attr_from_item( pub fn mk_attr_word( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, name: Symbol, span: Span, ) -> Attribute { @@ -601,7 +601,7 @@ pub fn mk_attr_word( pub fn mk_attr_nested_word( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, outer: Symbol, inner: Symbol, span: Span, @@ -623,7 +623,7 @@ pub fn mk_attr_nested_word( pub fn mk_attr_name_value_str( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, name: Symbol, val: Symbol, span: Span, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 5fbae6a34e5..554f9f09858 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1801,7 +1801,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr = attr::mk_attr_nested_word( &self.tcx.sess.psess.attr_id_generator, AttrStyle::Outer, - Unsafe::No, + Safety::Default, sym::allow, sym::unreachable_code, self.lower_span(span), diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index e3ccbbe391e..54d642f6a0f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -16,7 +16,7 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Unsafe}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Safety}; use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -249,7 +249,7 @@ pub fn print_crate<'a>( let fake_attr = attr::mk_attr_nested_word( g, ast::AttrStyle::Inner, - Unsafe::No, + Safety::Default, sym::feature, sym::prelude_import, DUMMY_SP, @@ -261,7 +261,7 @@ pub fn print_crate<'a>( if edition.is_rust_2015() { // `#![no_std]` let fake_attr = - attr::mk_attr_word(g, ast::AttrStyle::Inner, Unsafe::No, sym::no_std, DUMMY_SP); + attr::mk_attr_word(g, ast::AttrStyle::Inner, Safety::Default, sym::no_std, DUMMY_SP); s.print_attribute(&fake_attr); } } diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index d70eaa617ca..dea668ff8f4 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval; use crate::errors; use rustc_ast as ast; -use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Unsafe}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Safety}; use rustc_expand::base::{ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, }; @@ -163,9 +163,9 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) { match meta.unsafety { - Unsafe::Yes(span) => { + Safety::Unsafe(span) => { sess.dcx().emit_err(errors::DeriveUnsafePath { span }); } - Unsafe::No => {} + Safety::Default => {} } } diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index fec54cfe38f..ba4e5cfd130 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -203,7 +203,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let allow_dead_code = attr::mk_attr_nested_word( &self.sess.psess.attr_id_generator, ast::AttrStyle::Outer, - ast::Unsafe::No, + ast::Safety::Default, sym::allow, sym::dead_code, self.def_site, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 9451102c010..e513e61f4d1 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -666,7 +666,7 @@ impl<'a> ExtCtxt<'a> { // Builds `#[name]`. pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, span) + attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Safety::Default, name, span) } // Builds `#[name = val]`. @@ -674,12 +674,12 @@ impl<'a> ExtCtxt<'a> { // Note: `span` is used for both the identifier and the value. pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, val, span) + attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Safety::Default, name, val, span) } // Builds `#[outer(inner)]`. pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, outer, inner, span) + attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Safety::Default, outer, inner, span) } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index dfef2540d29..c28a09eb57c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -781,7 +781,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // The `MetaItem` representing the trait to derive can't // have an unsafe around it (as of now). let meta = ast::MetaItem { - unsafety: ast::Unsafe::No, + unsafety: ast::Safety::Default, kind: MetaItemKind::Word, span, path, diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 2dd19f6c20a..58fef9b6c45 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -258,9 +258,9 @@ impl<'a> Parser<'a> { this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); this.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - ast::Unsafe::Yes(unsafe_span) + ast::Safety::Unsafe(unsafe_span) } else { - ast::Unsafe::No + ast::Safety::Default }; let path = this.parse_path(PathStyle::Mod)?; @@ -395,9 +395,9 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - ast::Unsafe::Yes(unsafe_span) + ast::Safety::Unsafe(unsafe_span) } else { - ast::Unsafe::No + ast::Safety::Default }; let path = self.parse_path(PathStyle::Mod)?; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d826eacbd15..29bc165159d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -317,7 +317,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_unsafe_attr(&self, attr: &Attribute) { if !attr.is_doc_comment() { let attr_item = attr.get_normal_item(); - if let ast::Unsafe::Yes(unsafe_span) = attr_item.unsafety { + if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety { if !is_unsafe_attr(attr.name_or_empty()) { self.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 2579c15fc5f..56a10f9fb9c 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::{MetaItemLit, Path, StrStyle, Unsafe}; +use rustc_ast::{MetaItemLit, Path, StrStyle, Safety}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident}; use rustc_span::DUMMY_SP; @@ -16,7 +16,7 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { fn dummy_meta_item_word(name: &str) -> MetaItem { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::Word, span: DUMMY_SP, @@ -26,7 +26,7 @@ fn dummy_meta_item_word(name: &str) -> MetaItem { fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem { let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::NameValue(lit), span: DUMMY_SP, @@ -36,7 +36,7 @@ fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> Meta macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( @@ -51,7 +51,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( -- cgit 1.4.1-3-g733a5 From cbee17d5025c7824828c793ac776ad6e1addbeac Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 09:11:58 +0000 Subject: Revert "Create const block DefIds in typeck instead of ast lowering" This reverts commit ddc5f9b6c1f21da5d4596bf7980185a00984ac42. --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 9 ++++- compiler/rustc_ast_lowering/src/index.rs | 8 +++++ compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 5 ++- .../rustc_const_eval/src/const_eval/fn_queries.rs | 2 +- compiler/rustc_hir/src/hir.rs | 14 +++++++- compiler/rustc_hir/src/intravisit.rs | 13 ++++++- compiler/rustc_hir_analysis/src/check/region.rs | 7 ++-- .../rustc_hir_analysis/src/collect/generics_of.rs | 10 +++--- compiler/rustc_hir_analysis/src/collect/type_of.rs | 3 +- compiler/rustc_hir_analysis/src/lib.rs | 8 ++--- compiler/rustc_hir_pretty/src/lib.rs | 5 +-- compiler/rustc_hir_typeck/src/expr.rs | 21 ++++++++++- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 4 --- compiler/rustc_hir_typeck/src/upvar.rs | 4 +++ compiler/rustc_hir_typeck/src/writeback.rs | 13 ++++--- compiler/rustc_middle/src/hir/map/mod.rs | 42 +++++++--------------- compiler/rustc_middle/src/ty/typeck_results.rs | 5 --- compiler/rustc_mir_build/src/build/mod.rs | 7 ++-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 6 ++-- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 8 +++-- compiler/rustc_mir_transform/src/lib.rs | 6 ---- compiler/rustc_parse/src/parser/mod.rs | 13 ++++--- compiler/rustc_passes/src/check_const.rs | 10 +++--- compiler/rustc_passes/src/dead.rs | 21 +++++------ compiler/rustc_passes/src/liveness.rs | 8 +---- compiler/rustc_passes/src/loops.rs | 7 ++-- compiler/rustc_resolve/src/def_collector.rs | 10 ++++++ compiler/rustc_resolve/src/late.rs | 6 ++-- src/tools/clippy/clippy_utils/src/consts.rs | 6 ++-- src/tools/clippy/clippy_utils/src/hir_utils.rs | 6 ++-- .../clippy/tests/ui/arithmetic_side_effects.stderr | 32 +++-------------- .../building/custom/consts.consts.built.after.mir | 2 +- tests/pretty/stmt_expr_attributes.rs | 7 +++- tests/ui/lint/non-local-defs/consts.stderr | 19 ++++++---- tests/ui/unpretty/expanded-exhaustive.stdout | 3 +- 39 files changed, 190 insertions(+), 168 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 910fbb87697..b5a59442f14 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1392,7 +1392,7 @@ pub enum ExprKind { /// An array (e.g, `[a, b, c, d]`). Array(ThinVec>), /// Allow anonymous constants from an inline `const` block - ConstBlock(P), + ConstBlock(AnonConst), /// A function call /// /// The first field resolves to the function itself, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a04c648ac73..635535a1125 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1417,7 +1417,7 @@ pub fn noop_visit_expr( match kind { ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis), ExprKind::ConstBlock(anon_const) => { - vis.visit_expr(anon_const); + vis.visit_anon_const(anon_const); } ExprKind::Repeat(expr, count) => { vis.visit_expr(expr); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index de285aed165..fa97c8db326 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -959,7 +959,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::Array(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)), + ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)), ExprKind::Repeat(element, count) => { try_visit!(visitor.visit_expr(element)); try_visit!(visitor.visit_anon_const(count)); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c0a424115aa..a5531090928 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -74,7 +74,14 @@ impl<'hir> LoweringContext<'_, 'hir> { let kind = match &e.kind { ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)), - ExprKind::ConstBlock(c) => hir::ExprKind::ConstBlock(self.lower_expr(c)), + ExprKind::ConstBlock(c) => { + let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock { + def_id: this.local_def_id(c.id), + hir_id: this.lower_node_id(c.id), + body: this.lower_const_body(c.value.span, Some(&c.value)), + }); + hir::ExprKind::ConstBlock(c) + } ExprKind::Repeat(expr, count) => { let expr = self.lower_expr(expr); let count = self.lower_array_length(count); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 741a44eb0c5..44f37b5533a 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -236,6 +236,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } + fn visit_inline_const(&mut self, constant: &'hir ConstBlock) { + self.insert(DUMMY_SP, constant.hir_id, Node::ConstBlock(constant)); + + self.with_parent(constant.hir_id, |this| { + intravisit::walk_inline_const(this, constant); + }); + } + fn visit_expr(&mut self, expr: &'hir Expr<'hir>) { self.insert(expr.span, expr.hir_id, Node::Expr(expr)); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 993ccc5b956..1e117c46b6e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -380,9 +380,8 @@ impl<'a> State<'a> { ast::ExprKind::Array(exprs) => { self.print_expr_vec(exprs); } - ast::ExprKind::ConstBlock(expr) => { - self.word_space("const"); - self.print_expr(expr, FixupContext::default()); + ast::ExprKind::ConstBlock(anon_const) => { + self.print_expr_anon_const(anon_const, attrs); } ast::ExprKind::Repeat(element, count) => { self.print_expr_repeat(element, count); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 3c11d67e748..8c66888d100 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -38,6 +38,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { match node { hir::Node::Ctor(_) | hir::Node::AnonConst(_) + | hir::Node::ConstBlock(_) | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { hir::Constness::Const } @@ -56,7 +57,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { if is_const { hir::Constness::Const } else { hir::Constness::NotConst } } hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness, - hir::Node::Expr(e) if let hir::ExprKind::ConstBlock(_) = e.kind => hir::Constness::Const, _ => { if let Some(fn_kind) = node.fn_kind() { if fn_kind.constness() == hir::Constness::Const { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d5f545c1c15..1570f8d5990 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1623,6 +1623,14 @@ pub struct AnonConst { pub span: Span, } +/// An inline constant expression `const { something }`. +#[derive(Copy, Clone, Debug, HashStable_Generic)] +pub struct ConstBlock { + pub hir_id: HirId, + pub def_id: LocalDefId, + pub body: BodyId, +} + /// An expression. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Expr<'hir> { @@ -1909,7 +1917,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { #[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ExprKind<'hir> { /// Allow anonymous constants from an inline `const` block - ConstBlock(&'hir Expr<'hir>), + ConstBlock(ConstBlock), /// An array (e.g., `[a, b, c, d]`). Array(&'hir [Expr<'hir>]), /// A function call. @@ -3641,6 +3649,7 @@ pub enum Node<'hir> { Variant(&'hir Variant<'hir>), Field(&'hir FieldDef<'hir>), AnonConst(&'hir AnonConst), + ConstBlock(&'hir ConstBlock), Expr(&'hir Expr<'hir>), ExprField(&'hir ExprField<'hir>), Stmt(&'hir Stmt<'hir>), @@ -3701,6 +3710,7 @@ impl<'hir> Node<'hir> { Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident), Node::Param(..) | Node::AnonConst(..) + | Node::ConstBlock(..) | Node::Expr(..) | Node::Stmt(..) | Node::Block(..) @@ -3798,6 +3808,7 @@ impl<'hir> Node<'hir> { } Node::AnonConst(constant) => Some((constant.def_id, constant.body)), + Node::ConstBlock(constant) => Some((constant.def_id, constant.body)), _ => None, } @@ -3866,6 +3877,7 @@ impl<'hir> Node<'hir> { expect_variant, &'hir Variant<'hir>, Node::Variant(n), n; expect_field, &'hir FieldDef<'hir>, Node::Field(n), n; expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n; + expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n; expect_expr, &'hir Expr<'hir>, Node::Expr(n), n; expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n; expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n; diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index e37473df956..5a16f266dab 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -344,6 +344,9 @@ pub trait Visitor<'v>: Sized { fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result { walk_anon_const(self, c) } + fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result { + walk_inline_const(self, c) + } fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result { walk_expr(self, ex) } @@ -718,6 +721,14 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo visitor.visit_nested_body(constant.body) } +pub fn walk_inline_const<'v, V: Visitor<'v>>( + visitor: &mut V, + constant: &'v ConstBlock, +) -> V::Result { + try_visit!(visitor.visit_id(constant.hir_id)); + visitor.visit_nested_body(constant.body) +} + pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result { try_visit!(visitor.visit_id(expression.hir_id)); match expression.kind { @@ -725,7 +736,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) walk_list!(visitor, visit_expr, subexpressions); } ExprKind::ConstBlock(ref const_block) => { - try_visit!(visitor.visit_expr(const_block)) + try_visit!(visitor.visit_inline_const(const_block)) } ExprKind::Repeat(ref element, ref count) => { try_visit!(visitor.visit_expr(element)); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 30b03b43872..72e431926ca 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -407,14 +407,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h match expr.kind { // Manually recurse over closures and inline consts, because they are the only // case of nested bodies that share the parent environment. - hir::ExprKind::Closure(&hir::Closure { body, .. }) => { + hir::ExprKind::Closure(&hir::Closure { body, .. }) + | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => { let body = visitor.tcx.hir().body(body); visitor.visit_body(body); } - hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| { - this.cx.var_parent = None; - resolve_local(this, None, Some(expr)); - }), hir::ExprKind::AssignOp(_, left_expr, right_expr) => { debug!( "resolve_expr - enabling pessimistic_yield, was previously {}", diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 9af959681fb..abdf85ad707 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } } } - Node::Expr(&hir::Expr { - kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. }, - .. - }) => Some(tcx.typeck_root_def_id(def_id.to_def_id())), + Node::ConstBlock(_) + | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { + Some(tcx.typeck_root_def_id(def_id.to_def_id())) + } Node::Item(item) => match item.kind { ItemKind::OpaqueTy(&hir::OpaqueTy { origin: @@ -415,7 +415,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } // provide junk type parameter defs for const blocks. - if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node { + if let Node::ConstBlock(_) = node { own_params.push(ty::GenericParamDef { index: next_index(), name: Symbol::intern(""), diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 6811f62de07..2684467a438 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -485,7 +485,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } Node::AnonConst(_) => anon_const_type_of(tcx, def_id), - Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => { + + Node::ConstBlock(_) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id()); args.as_inline_const().ty() } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 65b02a2ec56..8fe81851f93 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -190,6 +190,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } }); + // Freeze definitions as we don't add new ones at this point. This improves performance by + // allowing lock-free access to them. + tcx.untracked().definitions.freeze(); + // FIXME: Remove this when we implement creating `DefId`s // for anon constants during their parents' typeck. // Typeck all body owners in parallel will produce queries @@ -201,10 +205,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } }); - // Freeze definitions as we don't add new ones at this point. This improves performance by - // allowing lock-free access to them. - tcx.untracked().definitions.freeze(); - tcx.ensure().check_unused_traits(()); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6983bbcb052..6f2febd86b0 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -84,6 +84,7 @@ impl<'a> State<'a> { Node::ImplItem(a) => self.print_impl_item(a), Node::Variant(a) => self.print_variant(a), Node::AnonConst(a) => self.print_anon_const(a), + Node::ConstBlock(a) => self.print_inline_const(a), Node::Expr(a) => self.print_expr(a), Node::ExprField(a) => self.print_expr_field(a), Node::Stmt(a) => self.print_stmt(a), @@ -1049,10 +1050,10 @@ impl<'a> State<'a> { self.end() } - fn print_inline_const(&mut self, constant: &hir::Expr<'_>) { + fn print_inline_const(&mut self, constant: &hir::ConstBlock) { self.ibox(INDENT_UNIT); self.word_space("const"); - self.print_expr(constant); + self.ann.nested(self, Nested::Body(constant.body)); self.end() } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7dd7b3ff055..811b7ab2463 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -31,6 +31,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; @@ -334,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected), ExprKind::Array(args) => self.check_expr_array(args, expected, expr), - ExprKind::ConstBlock(ref block) => self.check_expr_with_expectation(block, expected), + ExprKind::ConstBlock(ref block) => self.check_expr_const_block(block, expected), ExprKind::Repeat(element, ref count) => { self.check_expr_repeat(element, count, expected, expr) } @@ -1456,6 +1457,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn check_expr_const_block( + &self, + block: &'tcx hir::ConstBlock, + expected: Expectation<'tcx>, + ) -> Ty<'tcx> { + let body = self.tcx.hir().body(block.body); + + // Create a new function context. + let def_id = block.def_id; + let fcx = FnCtxt::new(self, self.param_env, def_id); + crate::GatherLocalsVisitor::new(&fcx).visit_body(body); + + let ty = fcx.check_expr_with_expectation(body.value, expected); + fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized); + fcx.write_ty(block.hir_id, ty); + ty + } + fn check_expr_repeat( &self, element: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index caaf4142f7d..9ab89f3444c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1051,10 +1051,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .take_while(|(_, node)| { // look at parents until we find the first body owner node.body_id().is_none() - && !matches!( - node, - Node::Expr(Expr { kind: ExprKind::ConstBlock { .. }, .. }) - ) }) .any(|(parent_id, _)| self.is_loop(parent_id)); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4386e68ce86..466397817da 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -149,6 +149,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> { self.visit_body(body); self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause); } + hir::ExprKind::ConstBlock(anon_const) => { + let body = self.fcx.tcx.hir().body(anon_const.body); + self.visit_body(body); + } _ => {} } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 8727c0f87dc..b67d29fce92 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -3,7 +3,6 @@ // generic parameters. use crate::FnCtxt; -use hir::def::DefKind; use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_hir as hir; @@ -17,7 +16,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::TypeSuperFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::sym; use rustc_span::Span; use rustc_trait_selection::solve; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; @@ -296,11 +295,11 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => { self.visit_field_id(e.hir_id); } - hir::ExprKind::ConstBlock(_) => { - let feed = self.tcx().create_def(self.fcx.body_id, kw::Empty, DefKind::InlineConst); - feed.def_span(e.span); - feed.local_def_id_to_hir_id(e.hir_id); - self.typeck_results.inline_consts.insert(e.hir_id.local_id, feed.def_id()); + hir::ExprKind::ConstBlock(anon_const) => { + self.visit_node_id(e.span, anon_const.hir_id); + + let body = self.tcx().hir().body(anon_const.body); + self.visit_body(body); } _ => {} } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 8a3bbf71eb6..305ba1ef3bb 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1,5 +1,3 @@ -use std::borrow::Cow; - use crate::hir::ModuleItems; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::query::LocalCrate; @@ -256,26 +254,13 @@ impl<'hir> Map<'hir> { /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. - pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option>> { - Some(match self.tcx.def_kind(id) { - // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler. - DefKind::InlineConst => { - let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id)); - Cow::Owned(Body { - params: &[], - value: match e.kind { - ExprKind::ConstBlock(body) => body, - _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"), - }, - }) - } - _ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)), - }) + pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> { + Some(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)) } /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] - pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> { + pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> { self.maybe_body_owned_by(id).unwrap_or_else(|| { let hir_id = self.tcx.local_def_id_to_hir_id(id); span_bug!( @@ -338,7 +323,7 @@ impl<'hir> Map<'hir> { /// Returns an iterator of the `DefId`s for all body-owners in this /// crate. If you would prefer to iterate over the bodies - /// themselves, you can do `self.hir().krate().owners.iter()`. + /// themselves, you can do `self.hir().krate().body_ids.iter()`. #[inline] pub fn body_owners(self) -> impl Iterator + 'hir { self.tcx.hir_crate_items(()).body_owners.iter().copied() @@ -525,17 +510,7 @@ impl<'hir> Map<'hir> { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. /// Used exclusively for diagnostics, to avoid suggestion function calls. pub fn is_inside_const_context(self, hir_id: HirId) -> bool { - for (_, node) in self.parent_iter(hir_id) { - if let Some((def_id, _)) = node.associated_body() { - return self.body_const_context(def_id).is_some(); - } - if let Node::Expr(e) = node { - if let ExprKind::ConstBlock(_) = e.kind { - return true; - } - } - } - false + self.body_const_context(self.enclosing_body_owner(hir_id)).is_some() } /// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is @@ -918,6 +893,7 @@ impl<'hir> Map<'hir> { Node::Variant(variant) => variant.span, Node::Field(field) => field.span, Node::AnonConst(constant) => constant.span, + Node::ConstBlock(constant) => self.body(constant.body).value.span, Node::Expr(expr) => expr.span, Node::ExprField(field) => field.span, Node::Stmt(stmt) => stmt.span, @@ -1187,6 +1163,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) } Node::AnonConst(_) => node_str("const"), + Node::ConstBlock(_) => node_str("const"), Node::Expr(_) => node_str("expr"), Node::ExprField(_) => node_str("expr field"), Node::Stmt(_) => node_str("stmt"), @@ -1336,6 +1313,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { intravisit::walk_anon_const(self, c) } + fn visit_inline_const(&mut self, c: &'hir ConstBlock) { + self.body_owners.push(c.def_id); + intravisit::walk_inline_const(self, c) + } + fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { if let ExprKind::Closure(closure) = ex.kind { self.body_owners.push(closure.def_id); diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 69ea9c9843a..24e3e623ff2 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -217,10 +217,6 @@ pub struct TypeckResults<'tcx> { /// Container types and field indices of `offset_of!` expressions offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>, - - /// Maps from `HirId`s of const blocks (the `ExprKind::ConstBlock`, not the inner expression's) - /// to the `DefId` of the corresponding inline const. - pub inline_consts: FxIndexMap, } impl<'tcx> TypeckResults<'tcx> { @@ -253,7 +249,6 @@ impl<'tcx> TypeckResults<'tcx> { treat_byte_string_as_slice: Default::default(), closure_size_eval: Default::default(), offset_of_data: Default::default(), - inline_consts: Default::default(), } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 14d1b502474..193f0d124bb 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -568,8 +568,11 @@ fn construct_const<'a, 'tcx>( .. }) => (*span, ty.span), Node::AnonConst(ct) => (ct.span, ct.span), - Node::Expr(&hir::Expr { span, kind: hir::ExprKind::ConstBlock(_), .. }) => (span, span), - node => span_bug!(tcx.def_span(def), "can't build MIR for {def:?}: {node:#?}"), + Node::ConstBlock(_) => { + let span = tcx.def_span(def); + (span, span) + } + _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), }; let infcx = tcx.infer_ctxt().build(); diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index bd66257e6b6..28f9300b97a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -671,9 +671,9 @@ impl<'tcx> Cx<'tcx> { ExprKind::OffsetOf { container, fields } } - hir::ExprKind::ConstBlock(body) => { - let ty = self.typeck_results().node_type(body.hir_id); - let did = self.typeck_results().inline_consts[&expr.hir_id.local_id].into(); + hir::ExprKind::ConstBlock(ref anon_const) => { + let ty = self.typeck_results().node_type(anon_const.hir_id); + let did = anon_const.def_id.to_def_id(); let typeck_root_def_id = tcx.typeck_root_def_id(did); let parent_args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id)); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index bd9e34ae80f..244ac409fd3 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -165,7 +165,7 @@ impl<'tcx> Cx<'tcx> { &'a mut self, owner_id: HirId, fn_decl: &'tcx hir::FnDecl<'tcx>, - body: &hir::Body<'tcx>, + body: &'tcx hir::Body<'tcx>, ) -> impl Iterator> + 'a { let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id]; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 145a40ca3cd..158ca91fcf1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -637,13 +637,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { /// Converts inline const patterns. fn lower_inline_const( &mut self, - expr: &'tcx hir::Expr<'tcx>, + block: &'tcx hir::ConstBlock, id: hir::HirId, span: Span, ) -> PatKind<'tcx> { let tcx = self.tcx; - let def_id = self.typeck_results.inline_consts[&id.local_id]; - let ty = tcx.typeck(def_id).node_type(expr.hir_id); + let def_id = block.def_id; + let body_id = block.body; + let expr = &tcx.hir().body(body_id).value; + let ty = tcx.typeck(def_id).node_type(block.hir_id); // Special case inline consts that are just literals. This is solely // a performance optimization, as we could also just go through the regular diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b66e3d66f4d..9d88f8bf9be 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -222,12 +222,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. set.extend(tcx.hir().body_owners()); - // Inline consts' bodies are created in - // typeck instead of during ast lowering, like all other bodies so far. - for def_id in tcx.hir().body_owners() { - set.extend(tcx.typeck(def_id).inline_consts.values()) - } - // Additionally, tuple struct/variant constructors have MIR, but // they don't have a BodyId, so we need to build them separately. struct GatherCtors<'a> { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 8f733b4fcbb..29a84078c51 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -25,8 +25,8 @@ use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing}; use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs, Expr, - ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility, + self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs, + Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility, VisibilityKind, DUMMY_NODE_ID, }; use rustc_ast_pretty::pprust; @@ -1262,9 +1262,12 @@ impl<'a> Parser<'a> { } self.eat_keyword(kw::Const); let (attrs, blk) = self.parse_inner_attrs_and_block()?; - let expr = self.mk_expr(blk.span, ExprKind::Block(blk, None)); - let blk_span = expr.span; - Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(expr), attrs)) + let anon_const = AnonConst { + id: DUMMY_NODE_ID, + value: self.mk_expr(blk.span, ExprKind::Block(blk, None)), + }; + let blk_span = anon_const.value.span; + Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs)) } /// Parses mutability (`mut` or nothing). diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 71f3e8b7b5d..3f6eccbd5a5 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -196,6 +196,11 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); } + fn visit_inline_const(&mut self, block: &'tcx hir::ConstBlock) { + let kind = Some(hir::ConstContext::Const { inline: true }); + self.recurse_into(kind, None, |this| intravisit::walk_inline_const(this, block)); + } + fn visit_body(&mut self, body: &hir::Body<'tcx>) { let owner = self.tcx.hir().body_owner_def_id(body.id()); let kind = self.tcx.hir().body_const_context(owner); @@ -223,11 +228,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { self.const_check_violated(expr, e.span); } } - hir::ExprKind::ConstBlock(expr) => { - let kind = Some(hir::ConstContext::Const { inline: true }); - self.recurse_into(kind, None, |this| intravisit::walk_expr(this, expr)); - return; - } _ => {} } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 0049afff528..ddc50e2b811 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -587,16 +587,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { hir::ExprKind::OffsetOf(..) => { self.handle_offset_of(expr); } - hir::ExprKind::ConstBlock(expr) => { - // When inline const blocks are used in pattern position, paths - // referenced by it should be considered as used. - let in_pat = mem::replace(&mut self.in_pat, false); - - intravisit::walk_expr(self, expr); - - self.in_pat = in_pat; - return; - } _ => (), } @@ -658,6 +648,17 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { self.in_pat = in_pat; } + + fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) { + // When inline const blocks are used in pattern position, paths + // referenced by it should be considered as used. + let in_pat = mem::replace(&mut self.in_pat, false); + + self.live_symbols.insert(c.def_id); + intravisit::walk_inline_const(self, c); + + self.in_pat = in_pat; + } } fn has_allow_dead_code_or_lang_attr( diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 698f15015c4..dfa7dfa3398 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -147,11 +147,6 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { return; } - // Don't run for inline consts, they are collected together with their parent - if let DefKind::InlineConst = tcx.def_kind(def_id) { - return; - } - // Don't run unused pass for #[naked] if tcx.has_attr(def_id.to_def_id(), sym::naked) { return; @@ -1148,13 +1143,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } hir::ExprKind::Lit(..) + | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) | hir::ExprKind::Path(hir::QPath::LangItem(..)) | hir::ExprKind::OffsetOf(..) => succ, - hir::ExprKind::ConstBlock(expr) => self.propagate_through_expr(expr, succ), - // Note that labels have been resolved, so we don't need to look // at the label ident hir::ExprKind::Block(ref blk, _) => self.propagate_through_block(blk, succ), diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 737310e5c04..2587a18b8c8 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -93,6 +93,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { self.with_context(Constant, |v| intravisit::walk_anon_const(v, c)); } + fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) { + self.with_context(Constant, |v| intravisit::walk_inline_const(v, c)); + } + fn visit_fn( &mut self, fk: hir::intravisit::FnKind<'hir>, @@ -285,9 +289,6 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { self.cx_stack.len() - 1, ) } - hir::ExprKind::ConstBlock(expr) => { - self.with_context(Constant, |v| intravisit::walk_expr(v, expr)); - } _ => intravisit::walk_expr(self, e), } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index d7416ead325..ca97d10617b 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -340,6 +340,16 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { ExprKind::Gen(_, _, _) => { self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) } + ExprKind::ConstBlock(ref constant) => { + let def = self.create_def( + constant.id, + kw::Empty, + DefKind::InlineConst, + constant.value.span, + ); + self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + return; + } _ => self.parent_def, }; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c7c95addf49..b0adc3775f6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4535,10 +4535,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.visit_expr(elem); self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes)); } - ExprKind::ConstBlock(ref expr) => { - self.resolve_anon_const_manual(false, AnonConstKind::InlineConst, |this| { - this.visit_expr(expr) - }); + ExprKind::ConstBlock(ref ct) => { + self.resolve_anon_const(ct, AnonConstKind::InlineConst); } ExprKind::Index(ref elem, ref idx, _) => { self.resolve_expr(elem, Some(expr)); diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index cd88ccd87cf..5c9cad2b45d 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -6,7 +6,7 @@ use crate::{clip, is_direct_expn_of, sext, unsext}; use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; +use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp}; use rustc_lexer::tokenize; use rustc_lint::LateContext; use rustc_middle::mir::interpret::{alloc_range, Scalar}; @@ -412,7 +412,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. pub fn expr(&mut self, e: &Expr<'_>) -> Option> { match e.kind { - ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr(e), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => { self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| { let result = mir_to_const(this.lcx, result)?; @@ -490,7 +490,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// leaves the local crate. pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option { match e.kind { - ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr_is_empty(e), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr_is_empty(e), ExprKind::Path(ref qpath) => { if !self .typeck_results diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index c649c179468..36634817fc9 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -295,7 +295,7 @@ impl HirEqInterExpr<'_, '_, '_> { self.eq_expr(lx, rx) && self.eq_ty(lt, rt) }, (&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false, - (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_expr(lb, rb), + (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body), (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => { both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name) }, @@ -769,8 +769,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { // closures inherit TypeckResults self.hash_expr(self.cx.tcx.hir().body(body).value); }, - ExprKind::ConstBlock(l_id) => { - self.hash_expr(l_id); + ExprKind::ConstBlock(ref l_id) => { + self.hash_body(l_id.body); }, ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { self.hash_expr(e); diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr index df14ff396f6..8039c0bfa24 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr @@ -1,35 +1,11 @@ -error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:188:36 - | -LL | let _ = const { let mut n = 1; n += 1; n }; - | ^^^^^^ - | - = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]` - -error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:191:40 - | -LL | let _ = const { let mut n = 1; n = n + 1; n }; - | ^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:194:40 - | -LL | let _ = const { let mut n = 1; n = 1 + n; n }; - | ^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:200:59 - | -LL | let _ = const { let mut n = 1; n = -1; n = -(-1); n = -n; n }; - | ^^ - error: arithmetic operation that can potentially result in unexpected side-effects --> tests/ui/arithmetic_side_effects.rs:304:5 | LL | _n += 1; | ^^^^^^^ + | + = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]` error: arithmetic operation that can potentially result in unexpected side-effects --> tests/ui/arithmetic_side_effects.rs:305:5 @@ -751,5 +727,5 @@ error: arithmetic operation that can potentially result in unexpected side-effec LL | one.sub_assign(1); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 125 previous errors +error: aborting due to 121 previous errors diff --git a/tests/mir-opt/building/custom/consts.consts.built.after.mir b/tests/mir-opt/building/custom/consts.consts.built.after.mir index 7b6964849d4..a011fadcef1 100644 --- a/tests/mir-opt/building/custom/consts.consts.built.after.mir +++ b/tests/mir-opt/building/custom/consts.consts.built.after.mir @@ -10,7 +10,7 @@ fn consts() -> () { bb0: { _1 = const 5_u8; - _2 = const consts::::{constant#1}; + _2 = const consts::::{constant#0}; _3 = const C; _4 = const D; _5 = consts::<10>; diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs index f9041268211..5eb7d2fcae3 100644 --- a/tests/pretty/stmt_expr_attributes.rs +++ b/tests/pretty/stmt_expr_attributes.rs @@ -206,7 +206,12 @@ fn _11() { let _ = (); () }; - let const {} = #[rustc_dummy] const {}; + let const { + #![rustc_dummy] + } = + #[rustc_dummy] const { + #![rustc_dummy] + }; let mut x = 0; let _ = (#[rustc_dummy] x) = 15; let _ = (#[rustc_dummy] x) += 15; diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 48bdaa60823..2756ea40138 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -67,13 +67,18 @@ LL | impl Test { warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item --> $DIR/consts.rs:50:9 | -LL | fn main() { - | --------- move the `impl` block outside of this function `main` -... -LL | impl Test { - | ^^^^^---- - | | - | `Test` is not local +LL | const { + | ___________- +LL | | impl Test { + | | ^^^^^---- + | | | + | | `Test` is not local +LL | | +LL | | fn hoo() {} +... | +LL | | 1 +LL | | }; + | |_____- move the `impl` block outside of this inline constant `` and up 2 bodies | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 9e45f57af35..137a8aa5510 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -83,8 +83,7 @@ mod expressions { fn expr_const_block() { const {}; const { 1 }; - const - { + const { struct S; }; } -- cgit 1.4.1-3-g733a5