trait_sel: only test predicates w/ no substs
This commit modifies the `substitute_normalize_and_test_predicates` query, renaming it to `impossible_predicates` and only checking predicates which do not require substs. By making this change, polymorphization doesn't have to explicitly support vtables. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
c6ed442f40
commit
ce7c48fa15
5 changed files with 20 additions and 20 deletions
|
@ -168,7 +168,7 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
MonoItem::GlobalAsm(..) => return true,
|
||||
};
|
||||
|
||||
tcx.substitute_normalize_and_test_predicates((def_id, &substs))
|
||||
!tcx.subst_and_check_impossible_predicates((def_id, &substs))
|
||||
}
|
||||
|
||||
pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
|
||||
|
|
|
@ -1461,9 +1461,9 @@ rustc_queries! {
|
|||
desc { "normalizing `{:?}`", goal }
|
||||
}
|
||||
|
||||
query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
|
||||
query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
|
||||
desc { |tcx|
|
||||
"testing substituted normalized predicates:`{}`",
|
||||
"impossible substituted predicates:`{}`",
|
||||
tcx.def_path_str(key.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
|
|||
.predicates
|
||||
.iter()
|
||||
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
|
||||
if !traits::normalize_and_test_predicates(
|
||||
if traits::impossible_predicates(
|
||||
tcx,
|
||||
traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(),
|
||||
) {
|
||||
|
|
|
@ -418,15 +418,14 @@ where
|
|||
Ok(resolved_value)
|
||||
}
|
||||
|
||||
/// Normalizes the predicates and checks whether they hold in an empty
|
||||
/// environment. If this returns false, then either normalize
|
||||
/// encountered an error or one of the predicates did not hold. Used
|
||||
/// when creating vtables to check for unsatisfiable methods.
|
||||
pub fn normalize_and_test_predicates<'tcx>(
|
||||
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
||||
/// returns true, then either normalize encountered an error or one of the predicates did not
|
||||
/// hold. Used when creating vtables to check for unsatisfiable methods.
|
||||
pub fn impossible_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicates: Vec<ty::Predicate<'tcx>>,
|
||||
) -> bool {
|
||||
debug!("normalize_and_test_predicates(predicates={:?})", predicates);
|
||||
debug!("impossible_predicates(predicates={:?})", predicates);
|
||||
|
||||
let result = tcx.infer_ctxt().enter(|infcx| {
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
|
@ -443,22 +442,23 @@ pub fn normalize_and_test_predicates<'tcx>(
|
|||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
|
||||
fulfill_cx.select_all_or_error(&infcx).is_ok()
|
||||
fulfill_cx.select_all_or_error(&infcx).is_err()
|
||||
});
|
||||
debug!("normalize_and_test_predicates(predicates={:?}) = {:?}", predicates, result);
|
||||
debug!("impossible_predicates(predicates={:?}) = {:?}", predicates, result);
|
||||
result
|
||||
}
|
||||
|
||||
fn substitute_normalize_and_test_predicates<'tcx>(
|
||||
fn subst_and_check_impossible_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: (DefId, SubstsRef<'tcx>),
|
||||
) -> bool {
|
||||
debug!("substitute_normalize_and_test_predicates(key={:?})", key);
|
||||
debug!("subst_and_check_impossible_predicates(key={:?})", key);
|
||||
|
||||
let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
|
||||
let result = normalize_and_test_predicates(tcx, predicates);
|
||||
let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
|
||||
predicates.retain(|predicate| !predicate.needs_subst());
|
||||
let result = impossible_predicates(tcx, predicates);
|
||||
|
||||
debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result);
|
||||
debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result);
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -510,7 +510,7 @@ fn vtable_methods<'tcx>(
|
|||
// Note that this method could then never be called, so we
|
||||
// do not want to try and codegen it, in that case (see #23435).
|
||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
|
||||
if !normalize_and_test_predicates(tcx, predicates.predicates) {
|
||||
if impossible_predicates(tcx, predicates.predicates) {
|
||||
debug!("vtable_methods: predicates do not hold");
|
||||
return None;
|
||||
}
|
||||
|
@ -558,8 +558,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||
specializes: specialize::specializes,
|
||||
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
|
||||
vtable_methods,
|
||||
substitute_normalize_and_test_predicates,
|
||||
type_implements_trait,
|
||||
subst_and_check_impossible_predicates,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1346,7 +1346,7 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool {
|
|||
.predicates
|
||||
.iter()
|
||||
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
|
||||
!traits::normalize_and_test_predicates(
|
||||
traits::impossible_predicates(
|
||||
cx.tcx,
|
||||
traits::elaborate_predicates(cx.tcx, predicates)
|
||||
.map(|o| o.predicate)
|
||||
|
|
Loading…
Reference in a new issue