Skip to content

Commit 6392e99

Browse files
committed
change: replace unresolved user-defined predicates with ForallPred
1 parent a7f23e8 commit 6392e99

2 files changed

Lines changed: 45 additions & 18 deletions

File tree

src/analyze/annot_fn.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::rc::Rc;
55
use pretty::{termcolor, Pretty};
66
use rustc_hir::{def_id::LocalDefId, HirId};
77
use rustc_index::IndexVec;
8-
use rustc_middle::ty::{self as mir_ty, TyCtxt};
8+
use rustc_middle::ty::{self as mir_ty, TyCtxt, TypeFoldable};
99

1010
use crate::analyze::{self, did_cache::DefIdCache, TypeParamMap};
1111
use crate::annot::AnnotFormula;
@@ -224,26 +224,44 @@ impl<'tcx> AnnotFnTranslator<'tcx> {
224224
}
225225
}
226226

227+
fn instantiate_generics<T>(
228+
&self,
229+
ty: T,
230+
generic_args: mir_ty::GenericArgsRef<'tcx>,
231+
) -> Option<T>
232+
where
233+
T: TypeFoldable<TyCtxt<'tcx>>,
234+
{
235+
if !self.generic_args.is_empty() {
236+
Some(mir_ty::EarlyBinder::bind(ty).instantiate(self.tcx, generic_args))
237+
} else {
238+
None
239+
}
240+
}
241+
227242
fn expr_ty(&self, expr: &'tcx rustc_hir::Expr<'tcx>) -> mir_ty::Ty<'tcx> {
228243
let ty = self.typeck.expr_ty(expr);
229-
let instantiated = mir_ty::EarlyBinder::bind(ty).instantiate(self.tcx, self.generic_args);
244+
let instantiated = self.instantiate_generics(ty, self.generic_args).unwrap_or(ty);
230245
let typing_env = mir_ty::TypingEnv::fully_monomorphized();
231246
self.tcx.normalize_erasing_regions(typing_env, instantiated)
232247
}
233248

234249
fn pat_ty(&self, pat: &'tcx rustc_hir::Pat<'tcx>) -> mir_ty::Ty<'tcx> {
235250
let ty = self.typeck.pat_ty(pat);
236-
let instantiated = mir_ty::EarlyBinder::bind(ty).instantiate(self.tcx, self.generic_args);
251+
let instantiated = self.instantiate_generics(ty, self.generic_args).unwrap_or(ty);
237252
let typing_env = mir_ty::TypingEnv::fully_monomorphized();
238253
self.tcx.normalize_erasing_regions(typing_env, instantiated)
239254
}
240255

241256
pub fn to_formula_fn(&self) -> FormulaFn<'tcx> {
242257
let formula = self.to_formula(self.body.value);
243-
let params = self
244-
.tcx
245-
.fn_sig(self.local_def_id.to_def_id())
246-
.instantiate(self.tcx, self.generic_args)
258+
let fn_sig = self.tcx.fn_sig(self.local_def_id.to_def_id());
259+
let binder = if self.generic_args.is_empty() {
260+
fn_sig.skip_binder()
261+
} else {
262+
fn_sig.instantiate(self.tcx, self.generic_args)
263+
};
264+
let params = binder
247265
.skip_binder()
248266
.inputs()
249267
.to_vec();
@@ -515,23 +533,27 @@ impl<'tcx> AnnotFnTranslator<'tcx> {
515533
outer_generic_args = ?self.generic_args,
516534
"resolving predicate call in formula"
517535
);
518-
let generic_args = mir_ty::EarlyBinder::bind(generic_args)
519-
.instantiate(self.tcx, self.generic_args);
536+
let (is_unresolved_args, generic_args) = match self.instantiate_generics(generic_args, self.generic_args) {
537+
Some(args) => (false, args),
538+
None => (true, generic_args)
539+
};
540+
520541
let instance = mir_ty::Instance::try_resolve(
521542
self.tcx,
522543
typing_env,
523544
def_id,
524545
generic_args,
525546
)
526547
.unwrap();
527-
let pred_def_id = if let Some(instance) = instance {
528-
instance.def_id()
548+
let pred_def_id = instance.map_or(def_id, |instance| instance.def_id());
549+
550+
let pred = if is_unresolved_args {
551+
refine::user_defined_pred(self.tcx, pred_def_id).into()
529552
} else {
530-
def_id
553+
refine::forall_pred(self.tcx, pred_def_id).into()
531554
};
532-
let pred = refine::user_defined_pred(self.tcx, pred_def_id);
533555
let arg_terms = args.iter().map(|e| self.to_term(e)).collect();
534-
let atom = chc::Atom::new(pred.into(), arg_terms);
556+
let atom = chc::Atom::new(pred, arg_terms);
535557
return FormulaOrTerm::Formula(chc::Formula::Atom(atom));
536558
}
537559
}

src/refine.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ pub use env::{
1818
Assumption, EnumDefProvider, Env, PlaceType, PlaceTypeBuilder, PlaceTypeVar, TempVarIdx, Var,
1919
};
2020

21-
use crate::chc::{DatatypeSymbol, UserDefinedPred};
21+
use crate::chc::{DatatypeSymbol, ForallPred, UserDefinedPred};
2222
use rustc_middle::ty as mir_ty;
2323
use rustc_span::def_id::DefId;
2424

25-
fn stable_def_id_symbol(tcx: mir_ty::TyCtxt<'_>, did: DefId) -> String {
25+
fn stable_def_id_symbol(tcx: mir_ty::TyCtxt<'_>, did: DefId, prefix: &str) -> String {
2626
let hash = tcx.def_path_hash(did);
2727
let path = tcx.def_path(did);
2828
if let Some(name) = path.data.last().and_then(|d| d.data.get_opt_name()) {
29-
format!("{}_{}", name, hash.0.to_hex())
29+
tracing::debug!("stable_def_id_symbol: name={}", name);
30+
format!("{}_{}_{}", prefix, name, hash.0.to_hex())
3031
} else {
3132
hash.0.to_hex()
3233
}
@@ -37,5 +38,9 @@ pub fn datatype_symbol(tcx: mir_ty::TyCtxt<'_>, did: DefId) -> DatatypeSymbol {
3738
}
3839

3940
pub fn user_defined_pred(tcx: mir_ty::TyCtxt<'_>, did: DefId) -> UserDefinedPred {
40-
UserDefinedPred::new(stable_def_id_symbol(tcx, did))
41+
UserDefinedPred::new(stable_def_id_symbol(tcx, did, "p"))
42+
}
43+
44+
pub fn forall_pred(tcx: mir_ty::TyCtxt<'_>, did: DefId) -> ForallPred {
45+
ForallPred::new(stable_def_id_symbol(tcx, did, "q"))
4146
}

0 commit comments

Comments
 (0)