Fix stack overflow when derefrencing &!

This commit is contained in:
hkalbasi 2023-03-10 13:44:07 +03:30
parent 1b5bba4535
commit a980b562a7
4 changed files with 30 additions and 2 deletions

View file

@ -146,6 +146,22 @@ fn reference_autoderef() {
"#, "#,
3, 3,
); );
check_number(
r#"
struct Foo<T> { x: T }
impl<T> Foo<T> {
fn foo(&mut self) -> T { self.x }
}
fn f(i: &mut &mut Foo<Foo<i32>>) -> i32 {
((**i).x).foo()
}
fn g(i: Foo<Foo<i32>>) -> i32 {
i.x.foo()
}
const GOAL: i32 = f(&mut &mut Foo { x: Foo { x: 3 } }) + g(Foo { x: Foo { x: 5 } });
"#,
8,
);
} }
#[test] #[test]

View file

@ -637,7 +637,7 @@ impl MirLowerCtx<'_> {
} }
Expr::Box { .. } => not_supported!("box expression"), Expr::Box { .. } => not_supported!("box expression"),
Expr::Field { .. } | Expr::Index { .. } | Expr::UnaryOp { op: hir_def::expr::UnaryOp::Deref, .. } => { Expr::Field { .. } | Expr::Index { .. } | Expr::UnaryOp { op: hir_def::expr::UnaryOp::Deref, .. } => {
let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else { let Some((p, current)) = self.lower_expr_as_place_without_adjust(current, expr_id, true)? else {
return Ok(None); return Ok(None);
}; };
self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into()); self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into());

View file

@ -110,7 +110,7 @@ impl MirLowerCtx<'_> {
} }
} }
fn lower_expr_as_place_without_adjust( pub(super) fn lower_expr_as_place_without_adjust(
&mut self, &mut self,
current: BasicBlockId, current: BasicBlockId,
expr_id: ExprId, expr_id: ExprId,

View file

@ -336,6 +336,18 @@ fn main() {
); );
} }
#[test]
fn regression_14310() {
check_diagnostics(
r#"
fn clone(mut i: &!) -> ! {
//^^^^^ 💡 weak: variable does not need to be mutable
*i
}
"#,
);
}
#[test] #[test]
fn match_bindings() { fn match_bindings() {
check_diagnostics( check_diagnostics(