Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4/n] rustc: harden against InferOk having obligations in more cases. #37404

Merged
merged 1 commit into from
Nov 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
})
})
}

Expand Down Expand Up @@ -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>> {
Expand Down
14 changes: 8 additions & 6 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fyi, I've got a branch that aims to fix #32730 -- I haven't poked at it in a while, I was just retrying to rebase it today. I'll probably try to land some of the initial refactorings first in any case. (Have to see if this interferes with some of what you have going on later on...)

assert!(obligations.is_empty());
}
Err(_) => return None
}

debug!("overlap: unification check succeeded");
Expand Down
22 changes: 13 additions & 9 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
28 changes: 17 additions & 11 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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) {
Expand Down
20 changes: 12 additions & 8 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_>>();

Expand Down
17 changes: 11 additions & 6 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
}
}
})
}
Expand Down