rustc: harden against InferOk having obligations in more cases.
This commit is contained in:
parent
161f2623bd
commit
aee1ee3cc2
@ -1069,7 +1069,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.probe(|_| {
|
||||
let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
|
||||
let trace = TypeTrace::types(origin, true, a, b);
|
||||
self.sub(true, trace, &a, &b).map(|_| ())
|
||||
self.sub(true, trace, &a, &b).map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -1592,8 +1595,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// anyhow. We should make this typetrace stuff more
|
||||
// generic so we don't have to do anything quite this
|
||||
// terrible.
|
||||
self.equate(true, TypeTrace::dummy(self.tcx), a, b)
|
||||
}).map(|_| ())
|
||||
let trace = TypeTrace::dummy(self.tcx);
|
||||
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
|
||||
|
@ -14,7 +14,7 @@ use super::{SelectionContext, Obligation, ObligationCause};
|
||||
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
use infer::{InferCtxt, InferOk, TypeOrigin};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -55,11 +55,13 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||
debug!("overlap: b_impl_header={:?}", b_impl_header);
|
||||
|
||||
// Do `a` and `b` unify? If not, no overlap.
|
||||
if let Err(_) = selcx.infcx().eq_impl_headers(true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
&a_impl_header,
|
||||
&b_impl_header) {
|
||||
return None;
|
||||
match selcx.infcx().eq_impl_headers(true, TypeOrigin::Misc(DUMMY_SP), &a_impl_header,
|
||||
&b_impl_header) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
}
|
||||
Err(_) => return None
|
||||
}
|
||||
|
||||
debug!("overlap: unification check succeeded");
|
||||
|
@ -22,7 +22,7 @@ use super::util::impl_trait_ref_and_oblig;
|
||||
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use hir::def_id::DefId;
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
use infer::{InferCtxt, InferOk, TypeOrigin};
|
||||
use middle::region;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use traits::{self, Reveal, ObligationCause};
|
||||
@ -222,14 +222,18 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
target_substs);
|
||||
|
||||
// do the impls unify? If not, no specialization.
|
||||
if let Err(_) = infcx.eq_trait_refs(true,
|
||||
TypeOrigin::Misc(DUMMY_SP),
|
||||
source_trait_ref,
|
||||
target_trait_ref) {
|
||||
debug!("fulfill_implication: {:?} does not unify with {:?}",
|
||||
source_trait_ref,
|
||||
target_trait_ref);
|
||||
return Err(());
|
||||
match infcx.eq_trait_refs(true, TypeOrigin::Misc(DUMMY_SP), source_trait_ref,
|
||||
target_trait_ref) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty())
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("fulfill_implication: {:?} does not unify with {:?}",
|
||||
source_trait_ref,
|
||||
target_trait_ref);
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to prove all of the predicates for impl2 given those for impl1
|
||||
|
@ -298,7 +298,13 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
|
||||
|
||||
if let Err(terr) = infcx.sub_types(false, origin, impl_fty, trait_fty) {
|
||||
let sub_result = infcx.sub_types(false, origin, impl_fty, trait_fty)
|
||||
.map(|InferOk { obligations, .. }| {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
});
|
||||
|
||||
if let Err(terr) = sub_result {
|
||||
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
|
||||
impl_fty,
|
||||
trait_fty);
|
||||
|
@ -13,7 +13,7 @@ use check::regionck::RegionCtxt;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use rustc::infer;
|
||||
use rustc::infer::{self, InferOk};
|
||||
use middle::region;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
||||
@ -93,16 +93,22 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
||||
infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did);
|
||||
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
|
||||
|
||||
if let Err(_) = infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
|
||||
named_type, fresh_impl_self_ty) {
|
||||
let item_span = tcx.map.span(self_type_node_id);
|
||||
struct_span_err!(tcx.sess, drop_impl_span, E0366,
|
||||
"Implementations of Drop cannot be specialized")
|
||||
.span_note(item_span,
|
||||
"Use same sequence of generic type and region \
|
||||
parameters that is on the struct/enum definition")
|
||||
.emit();
|
||||
return Err(());
|
||||
match infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
|
||||
named_type, fresh_impl_self_ty) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
}
|
||||
Err(_) => {
|
||||
let item_span = tcx.map.span(self_type_node_id);
|
||||
struct_span_err!(tcx.sess, drop_impl_span, E0366,
|
||||
"Implementations of Drop cannot be specialized")
|
||||
.span_note(item_span,
|
||||
"Use same sequence of generic type and region \
|
||||
parameters that is on the struct/enum definition")
|
||||
.emit();
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
|
@ -415,15 +415,19 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
||||
|
||||
if f.unsubst_ty().is_phantom_data() {
|
||||
// Ignore PhantomData fields
|
||||
None
|
||||
} else if infcx.sub_types(false, origin, b, a).is_ok() {
|
||||
// Ignore fields that aren't significantly changed
|
||||
None
|
||||
} else {
|
||||
// Collect up all fields that were significantly changed
|
||||
// i.e. those that contain T in coerce_unsized T -> U
|
||||
Some((i, a, b))
|
||||
return None;
|
||||
}
|
||||
|
||||
// Ignore fields that aren't significantly changed
|
||||
if let Ok(ok) = infcx.sub_types(false, origin, b, a) {
|
||||
if ok.obligations.is_empty() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect up all fields that were significantly changed
|
||||
// i.e. those that contain T in coerce_unsized T -> U
|
||||
Some((i, a, b))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -106,7 +106,7 @@ pub use rustc::util;
|
||||
|
||||
use dep_graph::DepNode;
|
||||
use hir::map as hir_map;
|
||||
use rustc::infer::TypeOrigin;
|
||||
use rustc::infer::{InferOk, TypeOrigin};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::traits::{self, Reveal};
|
||||
@ -198,11 +198,16 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
actual: Ty<'tcx>)
|
||||
-> bool {
|
||||
ccx.tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
|
||||
if let Err(err) = infcx.eq_types(false, origin.clone(), expected, actual) {
|
||||
infcx.report_mismatched_types(origin, expected, actual, err);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
match infcx.eq_types(false, origin.clone(), expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
// FIXME(#32730) propagate obligations
|
||||
assert!(obligations.is_empty());
|
||||
true
|
||||
}
|
||||
Err(err) => {
|
||||
infcx.report_mismatched_types(origin, expected, actual, err);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user