From 34ed5c3efc839913d2dcfcbc60e8f11c3423d87b Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 25 Mar 2023 10:12:35 +0000 Subject: [PATCH] Alloc `hir::Lit` in an arena to remove the destructor from `Expr` This allows allocating `Expr`s into a dropless arena, which is useful for using length prefixed thing slices in HIR, since these can only be allocated in the dropless arena and not in a typed arena. This is something I'm working on. --- compiler/rustc_ast_lowering/src/expr.rs | 55 +++++++++---------- compiler/rustc_hir/src/arena.rs | 1 + compiler/rustc_hir/src/hir.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 4 +- .../src/bool_assert_comparison.rs | 2 +- .../clippy/clippy_lints/src/manual_strip.rs | 2 +- .../src/matches/match_like_matches.rs | 2 +- .../clippy_lints/src/methods/open_options.rs | 2 +- .../clippy/clippy_lints/src/utils/author.rs | 2 +- 9 files changed, 34 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1b1c4765bc07a..0d212b3e130a2 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -121,12 +121,16 @@ impl<'hir> LoweringContext<'_, 'hir> { LitKind::Err } }; - hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind)) + let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind)); + hir::ExprKind::Lit(lit) + } + ExprKind::IncludedBytes(bytes) => { + let lit = self.arena.alloc(respan( + self.lower_span(e.span), + LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), + )); + hir::ExprKind::Lit(lit) } - ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan( - self.lower_span(e.span), - LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), - )), ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = @@ -1746,40 +1750,31 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Int( - value as u128, - ast::LitIntType::Unsigned(ast::UintTy::Usize), - ), - }), - ) + let lit = self.arena.alloc(hir::Lit { + span: sp, + node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), + }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)), - }), - ) + let lit = self.arena.alloc(hir::Lit { + span: sp, + node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)), + }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> { - self.expr(sp, hir::ExprKind::Lit(hir::Lit { span: sp, node: ast::LitKind::Char(value) })) + let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Str(value, ast::StrStyle::Cooked), - }), - ) + let lit = self + .arena + .alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_call_mut( diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index c89e7eb75f8f0..3e5b3c498eee9 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -51,6 +51,7 @@ macro_rules! arena_types { [] type_binding: rustc_hir::TypeBinding<'tcx>, [] variant: rustc_hir::Variant<'tcx>, [] where_predicate: rustc_hir::WherePredicate<'tcx>, + [] lit: rustc_hir::Lit, ]); ) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 35a72f868fbcc..b274e62807988 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1957,7 +1957,7 @@ pub enum ExprKind<'hir> { /// A unary operation (e.g., `!x`, `*x`). Unary(UnOp, &'hir Expr<'hir>), /// A literal (e.g., `1`, `"foo"`). - Lit(Lit), + Lit(&'hir Lit), /// A cast (e.g., `foo as f64`). Cast(&'hir Expr<'hir>, &'hir Ty<'hir>), /// A type reference (e.g., `Foo`). diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 5fda4e191c2a0..e82821850d62e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed), span, }) => { - let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { return false; }; + let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(*span) else { return false; }; if !(snippet.starts_with("0x") || snippet.starts_with("0X")) { return false; } @@ -1311,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We have satisfied all requirements to provide a suggestion. Emit it. err.span_suggestion( - span, + *span, format!("if you meant to create a null pointer, use `{null_path_str}()`"), null_path_str + "()", Applicability::MachineApplicable, diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 1d9096ea64d1c..8c3ad24eeed43 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -41,7 +41,7 @@ fn extract_bool_lit(e: &Expr<'_>) -> Option { }) = e.kind && !e.span.from_expansion() { - Some(b) + Some(*b) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index c795c1d9a16c3..7d28c11162458 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -159,7 +159,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t .. }) = expr.kind { - constant_length(cx, pattern).map_or(false, |length| length == n) + constant_length(cx, pattern).map_or(false, |length| length == *n) } else { len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index 107fad32393cf..33bc20dad6b78 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -162,7 +162,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option { node: LitKind::Bool(b), .. }) = exp.kind { - Some(b) + Some(*b) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index c6a27cdd6fac0..23d23f25f14cf 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -48,7 +48,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec .. } = *span { - if lit { Argument::True } else { Argument::False } + if *lit { Argument::True } else { Argument::False } } else { // The function is called with a literal which is not a boolean literal. // This is theoretically possible, but not very likely. diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bc4adf1596d44..2dac807c420e3 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -430,7 +430,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Unary(UnOp::{op:?}, {inner})"); self.expr(inner); }, - ExprKind::Lit(ref lit) => { + ExprKind::Lit(lit) => { bind!(self, lit); kind!("Lit(ref {lit})"); self.lit(lit);