Skip to content

Commit 424f41d

Browse files
committed
rustc: harden against InferOk having obligations in more cases.
1 parent affc3b7 commit 424f41d

File tree

7 files changed

+78
-44
lines changed

7 files changed

+78
-44
lines changed

src/librustc/infer/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10611061
self.probe(|_| {
10621062
let origin = TypeOrigin::Misc(syntax_pos::DUMMY_SP);
10631063
let trace = TypeTrace::types(origin, true, a, b);
1064-
self.sub(true, trace, &a, &b).map(|_| ())
1064+
self.sub(true, trace, &a, &b).map(|InferOk { obligations, .. }| {
1065+
// FIXME(#32730) propagate obligations
1066+
assert!(obligations.is_empty());
1067+
})
10651068
})
10661069
}
10671070

@@ -1602,8 +1605,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16021605
// anyhow. We should make this typetrace stuff more
16031606
// generic so we don't have to do anything quite this
16041607
// terrible.
1605-
self.equate(true, TypeTrace::dummy(self.tcx), a, b)
1606-
}).map(|_| ())
1608+
let trace = TypeTrace::dummy(self.tcx);
1609+
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
1610+
// FIXME(#32730) propagate obligations
1611+
assert!(obligations.is_empty());
1612+
})
1613+
})
16071614
}
16081615

16091616
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {

src/librustc/traits/coherence.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use super::{SelectionContext, Obligation, ObligationCause};
1414

1515
use hir::def_id::{DefId, LOCAL_CRATE};
1616
use ty::{self, Ty, TyCtxt};
17-
use infer::{InferCtxt, TypeOrigin};
17+
use infer::{InferCtxt, InferOk, TypeOrigin};
1818
use syntax_pos::DUMMY_SP;
1919

2020
#[derive(Copy, Clone)]
@@ -55,11 +55,13 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
5555
debug!("overlap: b_impl_header={:?}", b_impl_header);
5656

5757
// Do `a` and `b` unify? If not, no overlap.
58-
if let Err(_) = selcx.infcx().eq_impl_headers(true,
59-
TypeOrigin::Misc(DUMMY_SP),
60-
&a_impl_header,
61-
&b_impl_header) {
62-
return None;
58+
match selcx.infcx().eq_impl_headers(true, TypeOrigin::Misc(DUMMY_SP), &a_impl_header,
59+
&b_impl_header) {
60+
Ok(InferOk { obligations, .. }) => {
61+
// FIXME(#32730) propagate obligations
62+
assert!(obligations.is_empty());
63+
}
64+
Err(_) => return None
6365
}
6466

6567
debug!("overlap: unification check succeeded");

src/librustc/traits/specialize/mod.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use super::util::impl_trait_ref_and_oblig;
2222

2323
use rustc_data_structures::fnv::FnvHashMap;
2424
use hir::def_id::DefId;
25-
use infer::{InferCtxt, TypeOrigin};
25+
use infer::{InferCtxt, InferOk, TypeOrigin};
2626
use middle::region;
2727
use ty::subst::{Subst, Substs};
2828
use traits::{self, Reveal, ObligationCause, Normalized};
@@ -227,14 +227,18 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
227227
target_substs);
228228

229229
// do the impls unify? If not, no specialization.
230-
if let Err(_) = infcx.eq_trait_refs(true,
231-
TypeOrigin::Misc(DUMMY_SP),
232-
source_trait_ref,
233-
target_trait_ref) {
234-
debug!("fulfill_implication: {:?} does not unify with {:?}",
235-
source_trait_ref,
236-
target_trait_ref);
237-
return Err(());
230+
match infcx.eq_trait_refs(true, TypeOrigin::Misc(DUMMY_SP), source_trait_ref,
231+
target_trait_ref) {
232+
Ok(InferOk { obligations, .. }) => {
233+
// FIXME(#32730) propagate obligations
234+
assert!(obligations.is_empty())
235+
}
236+
Err(_) => {
237+
debug!("fulfill_implication: {:?} does not unify with {:?}",
238+
source_trait_ref,
239+
target_trait_ref);
240+
return Err(());
241+
}
238242
}
239243

240244
// attempt to prove all of the predicates for impl2 given those for impl1

src/librustc_typeck/check/compare_method.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,13 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
419419

420420
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
421421

422-
if let Err(terr) = infcx.sub_types(false, origin, impl_fty, trait_fty) {
422+
let sub_result = infcx.sub_types(false, origin, impl_fty, trait_fty)
423+
.map(|InferOk { obligations, .. }| {
424+
// FIXME(#32730) propagate obligations
425+
assert!(obligations.is_empty());
426+
});
427+
428+
if let Err(terr) = sub_result {
423429
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
424430
impl_fty,
425431
trait_fty);

src/librustc_typeck/check/dropck.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use check::regionck::RegionCtxt;
1313

1414
use hir::def_id::DefId;
1515
use middle::free_region::FreeRegionMap;
16-
use rustc::infer;
16+
use rustc::infer::{self, InferOk};
1717
use middle::region;
1818
use rustc::ty::subst::{Subst, Substs};
1919
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
@@ -93,16 +93,22 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
9393
infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did);
9494
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
9595

96-
if let Err(_) = infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
97-
named_type, fresh_impl_self_ty) {
98-
let item_span = tcx.map.span(self_type_node_id);
99-
struct_span_err!(tcx.sess, drop_impl_span, E0366,
100-
"Implementations of Drop cannot be specialized")
101-
.span_note(item_span,
102-
"Use same sequence of generic type and region \
103-
parameters that is on the struct/enum definition")
104-
.emit();
105-
return Err(());
96+
match infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
97+
named_type, fresh_impl_self_ty) {
98+
Ok(InferOk { obligations, .. }) => {
99+
// FIXME(#32730) propagate obligations
100+
assert!(obligations.is_empty());
101+
}
102+
Err(_) => {
103+
let item_span = tcx.map.span(self_type_node_id);
104+
struct_span_err!(tcx.sess, drop_impl_span, E0366,
105+
"Implementations of Drop cannot be specialized")
106+
.span_note(item_span,
107+
"Use same sequence of generic type and region \
108+
parameters that is on the struct/enum definition")
109+
.emit();
110+
return Err(());
111+
}
106112
}
107113

108114
if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {

src/librustc_typeck/coherence/mod.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -415,15 +415,19 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
415415

416416
if f.unsubst_ty().is_phantom_data() {
417417
// Ignore PhantomData fields
418-
None
419-
} else if infcx.sub_types(false, origin, b, a).is_ok() {
420-
// Ignore fields that aren't significantly changed
421-
None
422-
} else {
423-
// Collect up all fields that were significantly changed
424-
// i.e. those that contain T in coerce_unsized T -> U
425-
Some((i, a, b))
418+
return None;
426419
}
420+
421+
// Ignore fields that aren't significantly changed
422+
if let Ok(ok) = infcx.sub_types(false, origin, b, a) {
423+
if ok.obligations.is_empty() {
424+
return None;
425+
}
426+
}
427+
428+
// Collect up all fields that were significantly changed
429+
// i.e. those that contain T in coerce_unsized T -> U
430+
Some((i, a, b))
427431
})
428432
.collect::<Vec<_>>();
429433

src/librustc_typeck/lib.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub use rustc::util;
106106

107107
use dep_graph::DepNode;
108108
use hir::map as hir_map;
109-
use rustc::infer::TypeOrigin;
109+
use rustc::infer::{InferOk, TypeOrigin};
110110
use rustc::ty::subst::Substs;
111111
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
112112
use rustc::traits::{self, Reveal};
@@ -198,11 +198,16 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
198198
t2: Ty<'tcx>)
199199
-> bool {
200200
ccx.tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
201-
if let Err(err) = infcx.eq_types(false, origin.clone(), t1, t2) {
202-
infcx.report_mismatched_types(origin, t1, t2, err);
203-
false
204-
} else {
205-
true
201+
match infcx.eq_types(false, origin.clone(), t1, t2) {
202+
Ok(InferOk { obligations, .. }) => {
203+
// FIXME(#32730) propagate obligations
204+
assert!(obligations.is_empty());
205+
true
206+
}
207+
Err(err) => {
208+
infcx.report_mismatched_types(origin, t1, t2, err);
209+
false
210+
}
206211
}
207212
})
208213
}

0 commit comments

Comments
 (0)