Skip to content

Commit d4a4097

Browse files
In ast_visitor, move more code into generic visitor
1 parent edba476 commit d4a4097

File tree

2 files changed

+137
-67
lines changed

2 files changed

+137
-67
lines changed

source/rust_verify/src/rust_to_vir_adts.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub(crate) fn check_item_struct<'tcx>(
197197
mode,
198198
ext_equal: vattrs.ext_equal,
199199
user_defined_invariant_fn: None,
200-
sized_constraint: get_sized_constraint(span, ctxt, &adt_def)?,
200+
sized_constraint: get_sized_constraint(span, ctxt, &adt_def, None)?,
201201
destructor: adt_def.destructor(ctxt.tcx).is_some(),
202202
};
203203
vir.datatypes.push(ctxt.spanned_new(span, datatype));
@@ -287,7 +287,7 @@ pub(crate) fn check_item_enum<'tcx>(
287287
mode: get_mode(Mode::Exec, attrs),
288288
ext_equal: vattrs.ext_equal,
289289
user_defined_invariant_fn: None,
290-
sized_constraint: get_sized_constraint(span, ctxt, &adt_def)?,
290+
sized_constraint: get_sized_constraint(span, ctxt, &adt_def, None)?,
291291
destructor: adt_def.destructor(ctxt.tcx).is_some(),
292292
},
293293
));
@@ -388,7 +388,7 @@ pub(crate) fn check_item_union<'tcx>(
388388
mode: get_mode(Mode::Exec, attrs),
389389
ext_equal: vattrs.ext_equal,
390390
user_defined_invariant_fn: None,
391-
sized_constraint: get_sized_constraint(span, ctxt, &adt_def)?,
391+
sized_constraint: get_sized_constraint(span, ctxt, &adt_def, None)?,
392392
destructor: adt_def.destructor(ctxt.tcx).is_some(),
393393
},
394394
));
@@ -399,6 +399,7 @@ fn get_sized_constraint<'tcx>(
399399
span: Span,
400400
ctxt: &Context<'tcx>,
401401
adt_def: &AdtDef<'tcx>,
402+
substs: Option<GenericArgsRef<'tcx>>,
402403
) -> Result<Option<vir::ast::Typ>, VirErr> {
403404
// This is where we get the 'sized_constraint', the type that is used to determine if
404405
// a given type is sized. This is an optional value -- None means "always sized"
@@ -451,7 +452,11 @@ fn get_sized_constraint<'tcx>(
451452
let Some(sized_constraint) = sized_constraint_opt else {
452453
return Ok(None);
453454
};
454-
let mut sized_constraint = sized_constraint.skip_binder();
455+
let mut sized_constraint = if let Some(substs) = substs {
456+
sized_constraint.instantiate(tcx, substs)
457+
} else {
458+
sized_constraint.skip_binder()
459+
};
455460

456461
let mut idx = 0;
457462
loop {
@@ -669,7 +674,7 @@ pub(crate) fn check_item_external<'tcx>(
669674
mode,
670675
ext_equal: vattrs.ext_equal,
671676
user_defined_invariant_fn: None,
672-
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def)?,
677+
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def, Some(substs_ref))?,
673678
destructor: external_adt_def.destructor(ctxt.tcx).is_some(),
674679
};
675680
vir.datatypes.push(ctxt.spanned_new(span, datatype));
@@ -707,7 +712,7 @@ pub(crate) fn check_item_external<'tcx>(
707712
mode,
708713
ext_equal: vattrs.ext_equal,
709714
user_defined_invariant_fn: None,
710-
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def)?,
715+
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def, Some(substs_ref))?,
711716
destructor: external_adt_def.destructor(ctxt.tcx).is_some(),
712717
};
713718
vir.datatypes.push(ctxt.spanned_new(span, datatype));
@@ -758,7 +763,7 @@ pub(crate) fn check_item_external<'tcx>(
758763
mode,
759764
ext_equal: vattrs.ext_equal,
760765
user_defined_invariant_fn: None,
761-
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def)?,
766+
sized_constraint: get_sized_constraint(span, ctxt, external_adt_def, Some(substs_ref))?,
762767
destructor: external_adt_def.destructor(ctxt.tcx).is_some(),
763768
};
764769
vir.datatypes.push(ctxt.spanned_new(span, datatype));

source/vir/src/ast_visitor.rs

Lines changed: 125 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,124 @@ pub(crate) trait AstVisitor<R: Returner, Err, Scope: Scoper> {
10891089
})
10901090
})
10911091
}
1092+
1093+
fn visit_field(&mut self, field: &Field) -> Result<R::Ret<Field>, Err> {
1094+
let (typ, mode, visibility) = &field.a;
1095+
let typ = self.visit_typ(typ)?;
1096+
R::ret(|| field.new_a((R::get(typ), *mode, visibility.clone())))
1097+
}
1098+
1099+
fn visit_fields(&mut self, fields: &Vec<Field>) -> Result<R::Vec<Field>, Err> {
1100+
R::map_vec(fields, &mut |b| self.visit_field(b))
1101+
}
1102+
1103+
fn visit_variant(&mut self, variant: &Variant) -> Result<R::Ret<Variant>, Err> {
1104+
let fields = self.visit_fields(&variant.fields)?;
1105+
R::ret(|| Variant {
1106+
name: variant.name.clone(),
1107+
fields: R::get_vec_a(fields),
1108+
ctor_style: variant.ctor_style.clone(),
1109+
})
1110+
}
1111+
1112+
fn visit_variants(&mut self, variants: &Vec<Variant>) -> Result<R::Vec<Variant>, Err> {
1113+
R::map_vec(variants, &mut |v| self.visit_variant(v))
1114+
}
1115+
1116+
fn visit_datatype(&mut self, datatype: &Datatype) -> Result<R::Ret<Datatype>, Err> {
1117+
let DatatypeX {
1118+
name,
1119+
proxy,
1120+
owning_module,
1121+
visibility,
1122+
transparency,
1123+
typ_params,
1124+
typ_bounds,
1125+
variants,
1126+
mode,
1127+
ext_equal,
1128+
user_defined_invariant_fn,
1129+
sized_constraint,
1130+
destructor,
1131+
} = &datatype.x;
1132+
let type_bounds = self.visit_generic_bounds(typ_bounds)?;
1133+
let variants = self.visit_variants(variants)?;
1134+
let sized_constraint = R::map_opt(sized_constraint, &mut |t| self.visit_typ(t))?;
1135+
R::ret(|| {
1136+
datatype.new_x(DatatypeX {
1137+
name: name.clone(),
1138+
proxy: proxy.clone(),
1139+
owning_module: owning_module.clone(),
1140+
visibility: visibility.clone(),
1141+
transparency: transparency.clone(),
1142+
typ_params: typ_params.clone(),
1143+
typ_bounds: R::get_vec_a(type_bounds),
1144+
variants: R::get_vec_a(variants),
1145+
mode: *mode,
1146+
ext_equal: *ext_equal,
1147+
user_defined_invariant_fn: user_defined_invariant_fn.clone(),
1148+
sized_constraint: R::get_opt(sized_constraint),
1149+
destructor: *destructor,
1150+
})
1151+
})
1152+
}
1153+
1154+
fn visit_assoc_type_impl(&mut self, imp: &AssocTypeImpl) -> Result<R::Ret<AssocTypeImpl>, Err> {
1155+
let AssocTypeImplX {
1156+
name,
1157+
impl_path,
1158+
typ_params,
1159+
typ_bounds,
1160+
trait_path,
1161+
trait_typ_args,
1162+
typ,
1163+
impl_paths,
1164+
} = &imp.x;
1165+
let type_bounds = self.visit_generic_bounds(typ_bounds)?;
1166+
let trait_typ_args = self.visit_typs(trait_typ_args)?;
1167+
let typ = self.visit_typ(typ)?;
1168+
R::ret(|| {
1169+
imp.new_x(AssocTypeImplX {
1170+
name: name.clone(),
1171+
impl_path: impl_path.clone(),
1172+
typ_params: typ_params.clone(),
1173+
typ_bounds: R::get_vec_a(type_bounds),
1174+
trait_path: trait_path.clone(),
1175+
trait_typ_args: R::get_vec_a(trait_typ_args),
1176+
typ: R::get(typ),
1177+
impl_paths: impl_paths.clone(),
1178+
})
1179+
})
1180+
}
1181+
1182+
fn visit_trait_impl(&mut self, imp: &TraitImpl) -> Result<R::Ret<TraitImpl>, Err> {
1183+
let TraitImplX {
1184+
impl_path,
1185+
typ_params,
1186+
typ_bounds,
1187+
trait_path,
1188+
trait_typ_args,
1189+
trait_typ_arg_impls,
1190+
owning_module,
1191+
auto_imported,
1192+
external_trait_blanket,
1193+
} = &imp.x;
1194+
let type_bounds = self.visit_generic_bounds(typ_bounds)?;
1195+
let trait_typ_args = self.visit_typs(trait_typ_args)?;
1196+
R::ret(|| {
1197+
imp.new_x(TraitImplX {
1198+
impl_path: impl_path.clone(),
1199+
typ_params: typ_params.clone(),
1200+
typ_bounds: R::get_vec_a(type_bounds),
1201+
trait_path: trait_path.clone(),
1202+
trait_typ_args: R::get_vec_a(trait_typ_args),
1203+
trait_typ_arg_impls: trait_typ_arg_impls.clone(),
1204+
owning_module: owning_module.clone(),
1205+
auto_imported: *auto_imported,
1206+
external_trait_blanket: *external_trait_blanket,
1207+
})
1208+
})
1209+
}
10921210
}
10931211

10941212
pub(crate) fn typ_visitor_check<E, MF>(typ: &Typ, mf: &mut MF) -> Result<(), E>
@@ -1154,6 +1272,7 @@ where
11541272
visitor.visit_typ(typ)
11551273
}
11561274

1275+
#[allow(dead_code)]
11571276
pub(crate) fn map_typs_visitor_env<E, FT>(typs: &Typs, env: &mut E, ft: &FT) -> Result<Typs, VirErr>
11581277
where
11591278
FT: Fn(&mut E, &Typ) -> Result<Typ, VirErr>,
@@ -1656,21 +1775,8 @@ pub(crate) fn map_datatype_visitor_env<E, FT>(
16561775
where
16571776
FT: Fn(&mut E, &Typ) -> Result<Typ, VirErr>,
16581777
{
1659-
let datatypex = datatype.x.clone();
1660-
let typ_bounds = map_generic_bounds_visitor(&datatypex.typ_bounds, env, ft)?;
1661-
let mut variants: Vec<Variant> = Vec::new();
1662-
for variant in datatypex.variants.iter() {
1663-
let mut fields: Vec<Field> = Vec::new();
1664-
for field in variant.fields.iter() {
1665-
let (typ, mode, vis) = &field.a;
1666-
let typ = map_typ_visitor_env(typ, env, ft)?;
1667-
fields.push(field.new_a((typ, *mode, vis.clone())));
1668-
}
1669-
let variant = Variant { fields: Arc::new(fields), ..variant.clone() };
1670-
variants.push(variant);
1671-
}
1672-
let variants = Arc::new(variants);
1673-
Ok(Spanned::new(datatype.span.clone(), DatatypeX { variants, typ_bounds, ..datatypex }))
1778+
let mut visitor = MapTypVisitorEnv { env, ft };
1779+
visitor.visit_datatype(datatype)
16741780
}
16751781

16761782
pub(crate) fn map_trait_impl_visitor_env<E, FT>(
@@ -1681,29 +1787,8 @@ pub(crate) fn map_trait_impl_visitor_env<E, FT>(
16811787
where
16821788
FT: Fn(&mut E, &Typ) -> Result<Typ, VirErr>,
16831789
{
1684-
let TraitImplX {
1685-
impl_path,
1686-
typ_params,
1687-
typ_bounds,
1688-
trait_path,
1689-
trait_typ_args,
1690-
trait_typ_arg_impls,
1691-
owning_module,
1692-
auto_imported,
1693-
external_trait_blanket,
1694-
} = &imp.x;
1695-
let impx = TraitImplX {
1696-
impl_path: impl_path.clone(),
1697-
typ_params: typ_params.clone(),
1698-
typ_bounds: map_generic_bounds_visitor(typ_bounds, env, ft)?,
1699-
trait_path: trait_path.clone(),
1700-
trait_typ_args: map_typs_visitor_env(trait_typ_args, env, ft)?,
1701-
trait_typ_arg_impls: trait_typ_arg_impls.clone(),
1702-
owning_module: owning_module.clone(),
1703-
auto_imported: *auto_imported,
1704-
external_trait_blanket: *external_trait_blanket,
1705-
};
1706-
Ok(Spanned::new(imp.span.clone(), impx))
1790+
let mut visitor = MapTypVisitorEnv { env, ft };
1791+
visitor.visit_trait_impl(imp)
17071792
}
17081793

17091794
pub(crate) fn map_assoc_type_impl_visitor_env<E, FT>(
@@ -1714,26 +1799,6 @@ pub(crate) fn map_assoc_type_impl_visitor_env<E, FT>(
17141799
where
17151800
FT: Fn(&mut E, &Typ) -> Result<Typ, VirErr>,
17161801
{
1717-
let AssocTypeImplX {
1718-
name,
1719-
impl_path,
1720-
typ_params,
1721-
typ_bounds,
1722-
trait_path,
1723-
trait_typ_args,
1724-
typ,
1725-
impl_paths,
1726-
} = &assoc.x;
1727-
let typ = map_typ_visitor_env(typ, env, ft)?;
1728-
let assocx = AssocTypeImplX {
1729-
name: name.clone(),
1730-
impl_path: impl_path.clone(),
1731-
typ_params: typ_params.clone(),
1732-
typ_bounds: map_generic_bounds_visitor(typ_bounds, env, ft)?,
1733-
trait_path: trait_path.clone(),
1734-
trait_typ_args: map_typs_visitor_env(trait_typ_args, env, ft)?,
1735-
typ,
1736-
impl_paths: impl_paths.clone(),
1737-
};
1738-
Ok(Spanned::new(assoc.span.clone(), assocx))
1802+
let mut visitor = MapTypVisitorEnv { env, ft };
1803+
visitor.visit_assoc_type_impl(assoc)
17391804
}

0 commit comments

Comments
 (0)