Skip to content

Commit 8b81855

Browse files
authored
mut_ref cleanup: remove is_mut params from VIR (#2407)
1 parent 6b51a7c commit 8b81855

17 files changed

Lines changed: 62 additions & 540 deletions

source/rust_verify/src/rust_to_vir_func.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,6 @@ fn handle_autospec<'tcx>(
170170

171171
let mut spec_params = vec![];
172172
for p in functionx.params.iter() {
173-
if p.x.is_mut {
174-
return err_span(
175-
span,
176-
format!("allow_in_spec not supported for function with &mut param"),
177-
);
178-
}
179173
if p.x.unwrapped_info.is_some() {
180174
return err_span(
181175
span,
@@ -190,7 +184,6 @@ fn handle_autospec<'tcx>(
190184
name: p.x.name.clone(),
191185
typ: p.x.typ.clone(),
192186
mode: Mode::Spec,
193-
is_mut: false,
194187
unwrapped_info: None,
195188
user_mut: false,
196189
},
@@ -203,7 +196,6 @@ fn handle_autospec<'tcx>(
203196
name: air_unique_var(RETURN_VALUE),
204197
typ: ret_param.x.typ.clone(),
205198
mode: Mode::Spec,
206-
is_mut: false,
207199
unwrapped_info: None,
208200
user_mut: false,
209201
},
@@ -1708,7 +1700,6 @@ pub(crate) fn check_item_fn<'tcx>(
17081700
name: name.clone(),
17091701
typ: typ.clone(),
17101702
mode: param_mode,
1711-
is_mut: false,
17121703
unwrapped_info: None,
17131704
user_mut: is_mut_var,
17141705
},
@@ -1906,7 +1897,6 @@ pub(crate) fn check_item_fn<'tcx>(
19061897
name: ret_name.clone(),
19071898
typ: ret_typ,
19081899
mode: ret_mode,
1909-
is_mut: false,
19101900
user_mut: false,
19111901
unwrapped_info: None,
19121902
},
@@ -1923,7 +1913,6 @@ pub(crate) fn check_item_fn<'tcx>(
19231913
.0
19241914
.clone(),
19251915
mode: ret_mode,
1926-
is_mut: false,
19271916
unwrapped_info: None,
19281917
user_mut: false,
19291918
},
@@ -2340,7 +2329,6 @@ fn param_names_for_async_func<'tcx>(
23402329
name: async_body_modes[&param.x.name].clone(),
23412330
typ: param.x.typ.clone(),
23422331
mode: param.x.mode,
2343-
is_mut: param.x.is_mut,
23442332
unwrapped_info: param.x.unwrapped_info.clone(),
23452333
user_mut: param.x.user_mut,
23462334
},
@@ -2431,10 +2419,6 @@ fn check_generics_for_invariant_fn<'tcx>(
24312419
}
24322420
}
24332421

2434-
// &mut T => Some(T, None)
2435-
// Ghost<&mut T> => Some(T, Some(Spec))
2436-
// Tracked<&mut T> => Some(T, Some(Proof))
2437-
// _ => None
24382422
fn is_mut_ty<'tcx>(
24392423
ctxt: &Context<'tcx>,
24402424
ty: rustc_middle::ty::Ty<'tcx>,
@@ -2869,7 +2853,6 @@ pub(crate) fn check_item_const_or_static<'tcx>(
28692853
name: ret_name,
28702854
typ: typ.clone(),
28712855
mode: ret_mode,
2872-
is_mut: false,
28732856
user_mut: false,
28742857
unwrapped_info: None,
28752858
},
@@ -2995,20 +2978,11 @@ pub(crate) fn check_foreign_item_fn<'tcx>(
29952978
assert!(idents.len() == inputs.len());
29962979
for (param, input) in idents.iter().zip(inputs.iter()) {
29972980
let name = no_body_param_to_var(param);
2998-
let is_mut = is_mut_ty(ctxt, *input);
2999-
let typ =
3000-
ctxt.mid_ty_to_vir(id, param.span, is_mut.map(|(t, _)| t).unwrap_or(input), None)?;
2981+
let typ = ctxt.mid_ty_to_vir(id, param.span, input, None)?;
30012982
// REVIEW: the parameters don't have attributes, so we use the overall mode
30022983
let vir_param = ctxt.spanned_new(
30032984
param.span,
3004-
ParamX {
3005-
name,
3006-
typ,
3007-
mode,
3008-
is_mut: is_mut.is_some(),
3009-
unwrapped_info: None,
3010-
user_mut: false,
3011-
},
2985+
ParamX { name, typ, mode, unwrapped_info: None, user_mut: false },
30122986
);
30132987
vir_params.push(vir_param);
30142988
}
@@ -3021,7 +2995,6 @@ pub(crate) fn check_foreign_item_fn<'tcx>(
30212995
name: air_unique_var(RETURN_VALUE),
30222996
typ: ret_typ,
30232997
mode: ret_mode,
3024-
is_mut: false,
30252998
user_mut: false,
30262999
unwrapped_info: None,
30273000
};

source/vir/src/ast.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,8 +1376,6 @@ pub struct ParamX {
13761376
pub mode: Mode,
13771377
/// Marked 'mut' at the source level?
13781378
pub user_mut: bool,
1379-
/// An &mut parameter (only used outside new-mut-ref)
1380-
pub is_mut: bool,
13811379
/// If the parameter uses a Ghost(x) or Tracked(x) pattern to unwrap the value, this is
13821380
/// the mode of the resulting unwrapped x variable (Spec for Ghost(x), Proof for Tracked(x)).
13831381
/// We also save a copy of the original wrapped name for lifetime_generate

source/vir/src/ast_simplify.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,6 @@ fn simplify_function(
11971197
typ: Arc::new(TypX::Int(IntRange::Int)),
11981198
mode: Mode::Spec,
11991199
user_mut: false,
1200-
is_mut: false,
12011200
unwrapped_info: None,
12021201
};
12031202
param_names.push(paramx.name.clone());

source/vir/src/ast_to_sst.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ pub(crate) enum PreLocalDeclKind {
5757
ExecClosureParam,
5858
/// StmtLet (mutability to be inferred)
5959
StmtLet,
60-
/// Param, always consider mut
61-
MutParam,
6260
}
6361

6462
#[derive(Clone)]
@@ -529,7 +527,6 @@ impl PreLocalDeclKind {
529527
Ok(LocalDeclKind::ExecClosureParam { mutable: mutbl.is_some() })
530528
}
531529
PreLocalDeclKind::StmtLet => Ok(LocalDeclKind::StmtLet { mutable: mutbl.is_some() }),
532-
PreLocalDeclKind::MutParam => Ok(LocalDeclKind::Param { mutable: true }),
533530
}
534531
}
535532
}

source/vir/src/ast_to_sst_func.rs

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -94,55 +94,28 @@ pub fn mk_fun_ctx<F: FunctionCommon>(
9494
mk_fun_ctx_dec(f, checking_spec_preconditions, false)
9595
}
9696

97-
pub(crate) fn param_to_par(param: &Param, allow_is_mut: bool) -> Par {
97+
pub(crate) fn param_to_par(param: &Param) -> Par {
9898
param.map_x(|p| {
99-
let ParamX { name, typ, mode, is_mut, user_mut: _, unwrapped_info: _ } = p;
100-
if *is_mut && !allow_is_mut {
101-
panic!("mut unexpected here");
102-
}
103-
ParX {
104-
name: name.clone(),
105-
typ: typ.clone(),
106-
mode: *mode,
107-
is_mut: *is_mut,
108-
purpose: ParPurpose::Regular,
109-
}
99+
let ParamX { name, typ, mode, user_mut: _, unwrapped_info: _ } = p;
100+
ParX { name: name.clone(), typ: typ.clone(), mode: *mode, purpose: ParPurpose::Regular }
110101
})
111102
}
112103

113-
pub(crate) fn params_to_pars(params: &Params, allow_is_mut: bool) -> Pars {
114-
Arc::new(vec_map(params, |p| param_to_par(p, allow_is_mut)))
104+
pub(crate) fn params_to_pars(params: &Params) -> Pars {
105+
Arc::new(vec_map(params, |p| param_to_par(p)))
115106
}
116107

117-
pub(crate) fn params_to_pre_post_pars(params: &Params, pre: bool) -> Pars {
108+
pub(crate) fn params_to_pre_post_pars(params: &Params) -> Pars {
118109
Arc::new(
119110
params
120111
.iter()
121-
.flat_map(|param| {
122-
let mut res = Vec::new();
123-
if param.x.is_mut {
124-
res.push(param.map_x(|p| ParX {
125-
name: p.name.clone(),
126-
typ: p.typ.clone(),
127-
mode: p.mode,
128-
is_mut: p.is_mut,
129-
purpose: ParPurpose::MutPre,
130-
}));
131-
}
132-
if !(param.x.is_mut && pre) {
133-
res.push(param.map_x(|p| ParX {
134-
name: p.name.clone(),
135-
typ: p.typ.clone(),
136-
mode: p.mode,
137-
is_mut: p.is_mut,
138-
purpose: if param.x.is_mut {
139-
ParPurpose::MutPost
140-
} else {
141-
ParPurpose::Regular
142-
},
143-
}));
144-
}
145-
res
112+
.map(|param| {
113+
param.map_x(|p| ParX {
114+
name: p.name.clone(),
115+
typ: p.typ.clone(),
116+
mode: p.mode,
117+
purpose: ParPurpose::Regular,
118+
})
146119
})
147120
.collect::<Vec<_>>(),
148121
)
@@ -155,7 +128,7 @@ fn func_body_to_sst(
155128
body: &Expr,
156129
verifying_owning_bucket: bool,
157130
) -> Result<FuncSpecBodySst, VirErr> {
158-
let pars = params_to_pars(&function.x.params, false);
131+
let pars = params_to_pars(&function.x.params);
159132

160133
// ast --> sst
161134
let mut state = State::new(diagnostics);
@@ -425,15 +398,14 @@ fn req_ens_to_sst(
425398
specs: &Vec<Expr>,
426399
pre: bool,
427400
) -> Result<(Pars, Vec<Exp>), VirErr> {
428-
let mut pars = params_to_pre_post_pars(&function.x.params, pre);
401+
let mut pars = params_to_pre_post_pars(&function.x.params);
429402
let pars_mut = Arc::make_mut(&mut pars);
430403
if !pre && matches!(function.x.mode, Mode::Exec | Mode::Proof) && function.x.ens_has_return {
431404
if !function.x.attrs.is_async {
432-
pars_mut.push(param_to_par(&function.x.ret, false));
405+
pars_mut.push(param_to_par(&function.x.ret));
433406
} else {
434407
pars_mut.push(param_to_par(
435408
&function.x.async_ret.as_ref().expect("Async function has no return type"),
436-
false,
437409
));
438410
}
439411
}
@@ -597,7 +569,7 @@ pub fn func_axioms_to_sst(
597569
assert!(function.x.ensure.1.len() == 0);
598570
let ens = crate::ast_util::conjoin(span, &*function.x.ensure.0);
599571
let req_ens = crate::ast_util::mk_implies(span, &req, &ens);
600-
let params = params_to_pre_post_pars(&function.x.params, false);
572+
let params = params_to_pre_post_pars(&function.x.params);
601573
// Use expr_to_bind_decls_exp_skip_checks, skipping checks on req_ens,
602574
// because the requires/ensures are checked when the function itself is checked
603575
let exp = expr_to_bind_decls_exp_skip_checks(ctx, diagnostics, &params, &req_ens)?;
@@ -864,15 +836,10 @@ pub fn func_def_to_sst(
864836
None
865837
};
866838
let ens_params = Arc::new(ens_params);
867-
let ens_pars = params_to_pars(&ens_params, true);
839+
let ens_pars = params_to_pars(&ens_params);
868840

869841
for param in function.x.params.iter() {
870-
state.declare_var_stm(
871-
&param.x.name,
872-
&param.x.typ,
873-
if param.x.is_mut { PreLocalDeclKind::MutParam } else { PreLocalDeclKind::Param },
874-
false,
875-
);
842+
state.declare_var_stm(&param.x.name, &param.x.typ, PreLocalDeclKind::Param, false);
876843
}
877844

878845
// When emitting an expression that refers to input variables, but which is embedded
@@ -881,9 +848,7 @@ pub fn func_def_to_sst(
881848
// Collect all such vars here.
882849
let mut params_to_use_pre = HashSet::<VarIdent>::new();
883850
for param in function.x.params.iter() {
884-
if !param.x.is_mut {
885-
params_to_use_pre.insert(param.x.name.clone());
886-
}
851+
params_to_use_pre.insert(param.x.name.clone());
887852
}
888853
// We need to perform this translation on:
889854
// - Postcondition
@@ -1140,8 +1105,8 @@ pub fn function_to_sst(
11401105
opaqueness: function.x.opaqueness.clone(),
11411106
typ_params: function.x.typ_params.clone(),
11421107
typ_bounds: function.x.typ_bounds.clone(),
1143-
pars: params_to_pars(&function.x.params, true),
1144-
ret: param_to_par(&function.x.ret, true),
1108+
pars: params_to_pars(&function.x.params),
1109+
ret: param_to_par(&function.x.ret),
11451110
ens_has_return: function.x.ens_has_return,
11461111
item_kind: function.x.item_kind,
11471112
attrs: function.x.attrs.clone(),
@@ -1152,7 +1117,7 @@ pub fn function_to_sst(
11521117
recommends_check,
11531118
safe_api_check,
11541119
async_ret: match &function.x.async_ret {
1155-
Some(async_ret) => Some(param_to_par(async_ret, true)),
1120+
Some(async_ret) => Some(param_to_par(async_ret)),
11561121
None => None,
11571122
},
11581123
};

source/vir/src/ast_util.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -254,26 +254,9 @@ pub fn params_equal_opt(
254254
// the publicly visible parameters.
255255
// 'user_mut' also isn't important at this level since it is only used to determine
256256
// if mutation is allowed within the function
257-
let ParamX {
258-
name: name1,
259-
typ: typ1,
260-
mode: mode1,
261-
is_mut: is_mut1,
262-
unwrapped_info: _,
263-
user_mut: _,
264-
} = &param1.x;
265-
let ParamX {
266-
name: name2,
267-
typ: typ2,
268-
mode: mode2,
269-
is_mut: is_mut2,
270-
unwrapped_info: _,
271-
user_mut: _,
272-
} = &param2.x;
273-
(!check_names || name1 == name2)
274-
&& types_equal(typ1, typ2)
275-
&& (!check_modes || mode1 == mode2)
276-
&& is_mut1 == is_mut2
257+
let ParamX { name: name1, typ: typ1, mode: mode1, unwrapped_info: _, user_mut: _ } = &param1.x;
258+
let ParamX { name: name2, typ: typ2, mode: mode2, unwrapped_info: _, user_mut: _ } = &param2.x;
259+
(!check_names || name1 == name2) && types_equal(typ1, typ2) && (!check_modes || mode1 == mode2)
277260
}
278261

279262
pub fn params_equal(param1: &Param, param2: &Param) -> bool {

source/vir/src/ast_visitor.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -981,14 +981,13 @@ pub(crate) trait AstVisitor<R: Returner, Err, Scope: Scoper> {
981981
}
982982

983983
fn visit_param(&mut self, param: &Param) -> Result<R::Ret<Param>, Err> {
984-
let ParamX { name, typ, mode, is_mut, user_mut, unwrapped_info } = &param.x;
984+
let ParamX { name, typ, mode, user_mut, unwrapped_info } = &param.x;
985985
let typ = self.visit_typ(typ)?;
986986
R::ret(|| {
987987
param.new_x(ParamX {
988988
name: name.clone(),
989989
typ: R::get(typ),
990990
mode: *mode,
991-
is_mut: *is_mut,
992991
user_mut: *user_mut,
993992
unwrapped_info: unwrapped_info.clone(),
994993
})

source/vir/src/datatype_to_air.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ fn field_to_par(span: &Span, f: &Field) -> Par {
6161
name: crate::ast_util::str_unique_var(&("_".to_string() + &f.name), dis),
6262
typ: f.a.0.clone(),
6363
mode: f.a.1,
64-
is_mut: false,
6564
purpose: ParPurpose::Regular,
6665
},
6766
)
@@ -185,7 +184,6 @@ fn datatype_or_fun_to_air_commands(
185184
name: x.clone(),
186185
typ: typ.clone(),
187186
mode: Mode::Exec,
188-
is_mut: false,
189187
purpose: ParPurpose::Regular,
190188
},
191189
)
@@ -243,7 +241,6 @@ fn datatype_or_fun_to_air_commands(
243241
name,
244242
typ: vpolytyp.clone(),
245243
mode: Mode::Exec,
246-
is_mut: false,
247244
purpose: ParPurpose::Regular,
248245
};
249246
params.push(Spanned::new(span.clone(), parx));

0 commit comments

Comments
 (0)