Skip to content

Commit a33199b

Browse files
vl0wAurel300
authored andcommitted
assoc type normaliser by Jonas (viperproject#980)
1 parent 49e9ac8 commit a33199b

File tree

1 file changed

+43
-14
lines changed
  • prusti-interface/src/environment

1 file changed

+43
-14
lines changed

prusti-interface/src/environment/mod.rs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -612,22 +612,51 @@ impl<'tcx> Environment<'tcx> {
612612

613613
/// Normalizes associated types in foldable types,
614614
/// i.e. this resolves projection types ([ty::TyKind::Projection]s)
615-
/// **Important:** Regions while be erased during this process
616-
pub fn resolve_assoc_types<T: ty::TypeFoldable<'tcx> + std::fmt::Debug + Copy>(&self, normalizable: T, param_env: ty::ParamEnv<'tcx>) -> T {
617-
let norm_res = self.tcx.try_normalize_erasing_regions(
618-
param_env,
619-
normalizable
620-
);
615+
pub fn resolve_assoc_types<T: ty::TypeFoldable<'tcx> + std::fmt::Debug>(&self, normalizable: T, param_env: ty::ParamEnv<'tcx>) -> T {
616+
struct Normalizer<'a, 'tcx> {
617+
tcx: &'a ty::TyCtxt<'tcx>,
618+
param_env: ty::ParamEnv<'tcx>,
619+
}
620+
impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for Normalizer<'a, 'tcx> {
621+
fn tcx(&self) -> ty::TyCtxt<'tcx> {
622+
*self.tcx
623+
}
624+
625+
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
626+
// rustc by default panics when we execute this TypeFolder on a mir::* type,
627+
// but we want to resolve associated types when we retrieve a local mir::Body
628+
c
629+
}
621630

622-
match norm_res {
623-
Ok(normalized) => {
624-
debug!("Normalized {:?}: {:?}", normalizable, normalized);
625-
normalized
626-
},
627-
Err(err) => {
628-
debug!("Error while resolving associated types for {:?}: {:?}", normalizable, err);
629-
normalizable
631+
fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> {
632+
match ty.kind() {
633+
ty::TyKind::Projection(_) => {
634+
let normalized = self.tcx.infer_ctxt().enter(|infcx| {
635+
use prusti_rustc_interface::trait_selection::traits::{fully_normalize, FulfillmentContext};
636+
637+
let normalization_result = fully_normalize(
638+
&infcx,
639+
FulfillmentContext::new(),
640+
ObligationCause::dummy(),
641+
self.param_env,
642+
ty
643+
);
644+
645+
match normalization_result {
646+
Ok(res) => res,
647+
Err(errors) => {
648+
debug!("Error while resolving associated types: {:?}", errors);
649+
ty
650+
}
651+
}
652+
});
653+
normalized.super_fold_with(self)
654+
}
655+
_ => ty.super_fold_with(self)
656+
}
630657
}
631658
}
659+
660+
normalizable.fold_with(&mut Normalizer {tcx: &self.tcx, param_env})
632661
}
633662
}

0 commit comments

Comments
 (0)