1
Fork 0

Auto merge of #109588 - Nilstrieb:dropless-expr, r=compiler-errors

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 commit is contained in:
bors 2023-04-17 05:12:12 +00:00
commit 53ac4f8e2f
9 changed files with 34 additions and 38 deletions

View file

@ -121,12 +121,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
LitKind::Err 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) => hir::ExprKind::Lit(respan( ExprKind::IncludedBytes(bytes) => {
let lit = self.arena.alloc(respan(
self.lower_span(e.span), self.lower_span(e.span),
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
)), ));
hir::ExprKind::Lit(lit)
}
ExprKind::Cast(expr, ty) => { ExprKind::Cast(expr, ty) => {
let expr = self.lower_expr(expr); let expr = self.lower_expr(expr);
let ty = let ty =
@ -1746,40 +1750,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> { pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> {
self.expr( let lit = self.arena.alloc(hir::Lit {
sp,
hir::ExprKind::Lit(hir::Lit {
span: sp, span: sp,
node: ast::LitKind::Int( node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
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> { pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> {
self.expr( let lit = self.arena.alloc(hir::Lit {
sp,
hir::ExprKind::Lit(hir::Lit {
span: sp, span: sp,
node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)), 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> { 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> { pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
self.expr( let lit = self
sp, .arena
hir::ExprKind::Lit(hir::Lit { .alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) });
span: sp, self.expr(sp, hir::ExprKind::Lit(lit))
node: ast::LitKind::Str(value, ast::StrStyle::Cooked),
}),
)
} }
pub(super) fn expr_call_mut( pub(super) fn expr_call_mut(

View file

@ -51,6 +51,7 @@ macro_rules! arena_types {
[] type_binding: rustc_hir::TypeBinding<'tcx>, [] type_binding: rustc_hir::TypeBinding<'tcx>,
[] variant: rustc_hir::Variant<'tcx>, [] variant: rustc_hir::Variant<'tcx>,
[] where_predicate: rustc_hir::WherePredicate<'tcx>, [] where_predicate: rustc_hir::WherePredicate<'tcx>,
[] lit: rustc_hir::Lit,
]); ]);
) )
} }

View file

@ -1957,7 +1957,7 @@ pub enum ExprKind<'hir> {
/// A unary operation (e.g., `!x`, `*x`). /// A unary operation (e.g., `!x`, `*x`).
Unary(UnOp, &'hir Expr<'hir>), Unary(UnOp, &'hir Expr<'hir>),
/// A literal (e.g., `1`, `"foo"`). /// A literal (e.g., `1`, `"foo"`).
Lit(Lit), Lit(&'hir Lit),
/// A cast (e.g., `foo as f64`). /// A cast (e.g., `foo as f64`).
Cast(&'hir Expr<'hir>, &'hir Ty<'hir>), Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
/// A type reference (e.g., `Foo`). /// A type reference (e.g., `Foo`).

View file

@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed), node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed),
span, 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")) { if !(snippet.starts_with("0x") || snippet.starts_with("0X")) {
return false; return false;
} }
@ -1311,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We have satisfied all requirements to provide a suggestion. Emit it. // We have satisfied all requirements to provide a suggestion. Emit it.
err.span_suggestion( err.span_suggestion(
span, *span,
format!("if you meant to create a null pointer, use `{null_path_str}()`"), format!("if you meant to create a null pointer, use `{null_path_str}()`"),
null_path_str + "()", null_path_str + "()",
Applicability::MachineApplicable, Applicability::MachineApplicable,

View file

@ -41,7 +41,7 @@ fn extract_bool_lit(e: &Expr<'_>) -> Option<bool> {
}) = e.kind }) = e.kind
&& !e.span.from_expansion() && !e.span.from_expansion()
{ {
Some(b) Some(*b)
} else { } else {
None None
} }

View file

@ -159,7 +159,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t
.. ..
}) = expr.kind }) = expr.kind
{ {
constant_length(cx, pattern).map_or(false, |length| length == n) constant_length(cx, pattern).map_or(false, |length| length == *n)
} else { } else {
len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg))
} }

View file

@ -162,7 +162,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option<bool> {
node: LitKind::Bool(b), .. node: LitKind::Bool(b), ..
}) = exp.kind }) = exp.kind
{ {
Some(b) Some(*b)
} else { } else {
None None
} }

View file

@ -48,7 +48,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
.. ..
} = *span } = *span
{ {
if lit { Argument::True } else { Argument::False } if *lit { Argument::True } else { Argument::False }
} else { } else {
// The function is called with a literal which is not a boolean literal. // The function is called with a literal which is not a boolean literal.
// This is theoretically possible, but not very likely. // This is theoretically possible, but not very likely.

View file

@ -430,7 +430,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
kind!("Unary(UnOp::{op:?}, {inner})"); kind!("Unary(UnOp::{op:?}, {inner})");
self.expr(inner); self.expr(inner);
}, },
ExprKind::Lit(ref lit) => { ExprKind::Lit(lit) => {
bind!(self, lit); bind!(self, lit);
kind!("Lit(ref {lit})"); kind!("Lit(ref {lit})");
self.lit(lit); self.lit(lit);