Skip to content

Commit 479cb33

Browse files
committed
gccrs: Emit error when borrowing immutable variable as mutable
Fixes #4289 Rust rules strictly forbid creating a mutable reference ('&mut T') to an immutable binding. Previously, the compiler failed to validate the mutability of the source variable when using a 'ref mut' pattern. This patch adds verification logic to TypeCheckStmt to check the mutability status of the variable definition. gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): Add check to ensure 'ref mut' patterns bind to mutable variables. gcc/testsuite/ChangeLog: * rust/compile/issue-4289.rs: New test. Signed-off-by: Jayant Chauhan <0001jayant@gmail.com>
1 parent 32622b7 commit 479cb33

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

gcc/rust/typecheck/rust-hir-type-check-stmt.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,39 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
8888
{
8989
init_expr_locus = stmt.get_init_expr ().get_locus ();
9090
init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ());
91+
92+
if (stmt_pattern.get_pattern_kind ()
93+
== HIR::Pattern::PatternKind::Identifier)
94+
{
95+
auto &ident = static_cast<HIR::IdentifierPattern &> (stmt_pattern);
96+
97+
if (ident.is_ref () && ident.is_mut ())
98+
{
99+
HIR::Expr &init = stmt.get_init_expr ();
100+
101+
if (init.get_expression_kind () == HIR::Expr::ExprKind::Path)
102+
{
103+
NodeId ref_id = init.get_mappings ().get_nodeid ();
104+
NodeId def_id = UNKNOWN_NODEID;
105+
106+
if (resolver->lookup_resolved_name (ref_id, &def_id))
107+
{
108+
bool is_mutable = false;
109+
Resolver::Rib::Definition def;
110+
if (resolver->get_name_scope ().lookup (def_id, &def))
111+
{
112+
is_mutable = def.is_mutable;
113+
}
114+
if (!is_mutable)
115+
{
116+
rust_error_at (stmt_pattern.get_locus (),
117+
"cannot borrow immutable local "
118+
"variable as mutable");
119+
}
120+
}
121+
}
122+
}
123+
}
91124
if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
92125
return;
93126

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// { dg-options "-fsyntax-only" }
2+
pub fn a() {
3+
let v = 10;
4+
let ref mut r = v; // { dg-error "cannot borrow immutable local variable as mutable" }
5+
}
6+
7+
pub fn b() {
8+
let mut v2 = 10;
9+
let ref mut r2 = v2; // Should compile fine
10+
}

0 commit comments

Comments
 (0)