Skip to content

Commit 9985737

Browse files
committed
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.
1 parent 9fa6b3c commit 9985737

File tree

4 files changed

+45
-33
lines changed

4 files changed

+45
-33
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+25-30
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
135135
LitKind::Err
136136
}
137137
};
138-
hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind))
138+
let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));
139+
hir::ExprKind::Lit(lit)
140+
}
141+
ExprKind::IncludedBytes(bytes) => {
142+
let lit = self.arena.alloc(respan(
143+
self.lower_span(e.span),
144+
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
145+
));
146+
hir::ExprKind::Lit(lit)
139147
}
140-
ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan(
141-
self.lower_span(e.span),
142-
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
143-
)),
144148
ExprKind::Cast(expr, ty) => {
145149
let expr = self.lower_expr(expr);
146150
let ty =
@@ -1749,40 +1753,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
17491753
}
17501754

17511755
pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> {
1752-
self.expr(
1753-
sp,
1754-
hir::ExprKind::Lit(hir::Lit {
1755-
span: sp,
1756-
node: ast::LitKind::Int(
1757-
value as u128,
1758-
ast::LitIntType::Unsigned(ast::UintTy::Usize),
1759-
),
1760-
}),
1761-
)
1756+
let lit = self.arena.alloc(hir::Lit {
1757+
span: sp,
1758+
node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)),
1759+
});
1760+
self.expr(sp, hir::ExprKind::Lit(lit))
17621761
}
17631762

17641763
pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> {
1765-
self.expr(
1766-
sp,
1767-
hir::ExprKind::Lit(hir::Lit {
1768-
span: sp,
1769-
node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
1770-
}),
1771-
)
1764+
let lit = self.arena.alloc(hir::Lit {
1765+
span: sp,
1766+
node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)),
1767+
});
1768+
self.expr(sp, hir::ExprKind::Lit(lit))
17721769
}
17731770

17741771
pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> {
1775-
self.expr(sp, hir::ExprKind::Lit(hir::Lit { span: sp, node: ast::LitKind::Char(value) }))
1772+
let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) });
1773+
self.expr(sp, hir::ExprKind::Lit(lit))
17761774
}
17771775

17781776
pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> {
1779-
self.expr(
1780-
sp,
1781-
hir::ExprKind::Lit(hir::Lit {
1782-
span: sp,
1783-
node: ast::LitKind::Str(value, ast::StrStyle::Cooked),
1784-
}),
1785-
)
1777+
let lit = self
1778+
.arena
1779+
.alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) });
1780+
self.expr(sp, hir::ExprKind::Lit(lit))
17861781
}
17871782

17881783
pub(super) fn expr_call_mut(

compiler/rustc_hir/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ macro_rules! arena_types {
5151
[] type_binding: rustc_hir::TypeBinding<'tcx>,
5252
[] variant: rustc_hir::Variant<'tcx>,
5353
[] where_predicate: rustc_hir::WherePredicate<'tcx>,
54+
[] lint: rustc_hir::Lit,
5455
]);
5556
)
5657
}

compiler/rustc_hir/src/hir.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1941,7 +1941,7 @@ pub enum ExprKind<'hir> {
19411941
/// A unary operation (e.g., `!x`, `*x`).
19421942
Unary(UnOp, &'hir Expr<'hir>),
19431943
/// A literal (e.g., `1`, `"foo"`).
1944-
Lit(Lit),
1944+
Lit(&'hir Lit),
19451945
/// A cast (e.g., `foo as f64`).
19461946
Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
19471947
/// A type reference (e.g., `Foo`).
@@ -3997,6 +3997,22 @@ mod size_asserts {
39973997
// tidy-alphabetical-end
39983998
}
39993999

4000+
mod dropless {
4001+
use super::*;
4002+
4003+
macro_rules! static_assert_no_destructor {
4004+
($ty:ty) => {
4005+
const _: () = {
4006+
if std::mem::needs_drop::<$ty>() {
4007+
panic!(concat!(stringify!($ty), " has a destructor"));
4008+
}
4009+
};
4010+
};
4011+
}
4012+
4013+
static_assert_no_destructor!(Expr<'_>);
4014+
}
4015+
40004016
fn debug_fn(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Debug {
40014017
struct DebugFn<F>(F);
40024018
impl<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result> fmt::Debug for DebugFn<F> {

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12431243
node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed),
12441244
span,
12451245
}) => {
1246-
let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { return false; };
1246+
let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(*span) else { return false; };
12471247
if !(snippet.starts_with("0x") || snippet.starts_with("0X")) {
12481248
return false;
12491249
}
@@ -1302,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13021302

13031303
// We have satisfied all requirements to provide a suggestion. Emit it.
13041304
err.span_suggestion(
1305-
span,
1305+
*span,
13061306
format!("if you meant to create a null pointer, use `{null_path_str}()`"),
13071307
null_path_str + "()",
13081308
Applicability::MachineApplicable,

0 commit comments

Comments
 (0)