Skip to content

Commit ffb8f04

Browse files
committed
Fix ICE by introducing an expr_or_init variant for outside bodies
1 parent b97d311 commit ffb8f04

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

compiler/rustc_lint/src/context.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,40 @@ impl<'tcx> LateContext<'tcx> {
13161316
})
13171317
}
13181318

1319+
/// If the given expression is a local binding, find the initializer expression.
1320+
/// If that initializer expression is another local binding, find its initializer again.
1321+
///
1322+
/// This process repeats as long as possible (but usually no more than once).
1323+
/// Type-check adjustments are not taken in account in this function.
1324+
///
1325+
/// Examples:
1326+
/// ```
1327+
/// let abc = 1;
1328+
/// let def = abc + 2;
1329+
/// // ^^^^^^^ output
1330+
/// let def = def;
1331+
/// dbg!(def);
1332+
/// // ^^^ input
1333+
/// ```
1334+
pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> {
1335+
expr = expr.peel_blocks();
1336+
1337+
while let hir::ExprKind::Path(ref qpath) = expr.kind
1338+
&& let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
1339+
Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id),
1340+
_ => None,
1341+
}
1342+
&& let Some(init) = match parent_node {
1343+
hir::Node::Expr(expr) => Some(expr),
1344+
hir::Node::Local(hir::Local { init, .. }) => *init,
1345+
_ => None
1346+
}
1347+
{
1348+
expr = init.peel_blocks();
1349+
}
1350+
expr
1351+
}
1352+
13191353
/// If the given expression is a local binding, find the initializer expression.
13201354
/// If that initializer expression is another local or **outside** (`const`/`static`)
13211355
/// binding, find its initializer again.
@@ -1338,7 +1372,10 @@ impl<'tcx> LateContext<'tcx> {
13381372
/// dbg!(def);
13391373
/// // ^^^ input
13401374
/// ```
1341-
pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> {
1375+
pub fn expr_or_init_with_outside_body<'a>(
1376+
&self,
1377+
mut expr: &'a hir::Expr<'tcx>,
1378+
) -> &'a hir::Expr<'tcx> {
13421379
expr = expr.peel_blocks();
13431380

13441381
while let hir::ExprKind::Path(ref qpath) = expr.kind

compiler/rustc_lint/src/invalid_from_utf8.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
8484
)
8585
};
8686

87-
let mut init = cx.expr_or_init(arg);
87+
let mut init = cx.expr_or_init_with_outside_body(arg);
8888
while let ExprKind::AddrOf(.., inner) = init.kind {
89-
init = cx.expr_or_init(inner);
89+
init = cx.expr_or_init_with_outside_body(inner);
9090
}
9191
match init.kind {
9292
ExprKind::Lit(Spanned { node: lit, .. }) => {

tests/ui/lint/reference_casting.rs

+2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ unsafe fn assign_to_ref() {
130130
}
131131
}
132132

133+
const RAW_PTR: *mut u8 = 1 as *mut u8;
133134
unsafe fn no_warn() {
134135
let num = &3i32;
135136
let mut_num = &mut 3i32;
@@ -144,6 +145,7 @@ unsafe fn no_warn() {
144145
let mut value = 3;
145146
let value: *const i32 = &mut value;
146147
*(value as *const i16 as *mut i16) = 42;
148+
*RAW_PTR = 42;
147149

148150
fn safe_as_mut<T>(x: &std::cell::UnsafeCell<T>) -> &mut T {
149151
unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }

0 commit comments

Comments
 (0)