From a980b562a7b9035f00a67330afb95224f1196184 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Fri, 10 Mar 2023 13:44:07 +0330 Subject: [PATCH] Fix stack overflow when derefrencing `&!` --- crates/hir-ty/src/consteval/tests.rs | 16 ++++++++++++++++ crates/hir-ty/src/mir/lower.rs | 2 +- crates/hir-ty/src/mir/lower/as_place.rs | 2 +- .../src/handlers/mutability_errors.rs | 12 ++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index f2e42d6e50..6a29e8ce52 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -146,6 +146,22 @@ fn reference_autoderef() { "#, 3, ); + check_number( + r#" + struct Foo { x: T } + impl Foo { + fn foo(&mut self) -> T { self.x } + } + fn f(i: &mut &mut Foo>) -> i32 { + ((**i).x).foo() + } + fn g(i: Foo>) -> i32 { + i.x.foo() + } + const GOAL: i32 = f(&mut &mut Foo { x: Foo { x: 3 } }) + g(Foo { x: Foo { x: 5 } }); + "#, + 8, + ); } #[test] diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 8638e1d920..435a914088 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -637,7 +637,7 @@ impl MirLowerCtx<'_> { } Expr::Box { .. } => not_supported!("box expression"), 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); }; self.push_assignment(current, place, Operand::Copy(p).into(), expr_id.into()); diff --git a/crates/hir-ty/src/mir/lower/as_place.rs b/crates/hir-ty/src/mir/lower/as_place.rs index 09bcdd93be..fe8147dcd3 100644 --- a/crates/hir-ty/src/mir/lower/as_place.rs +++ b/crates/hir-ty/src/mir/lower/as_place.rs @@ -110,7 +110,7 @@ impl MirLowerCtx<'_> { } } - fn lower_expr_as_place_without_adjust( + pub(super) fn lower_expr_as_place_without_adjust( &mut self, current: BasicBlockId, expr_id: ExprId, diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs index f73d1302bf..84189a5d56 100644 --- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -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] fn match_bindings() { check_diagnostics(