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

Fix ICE building gluon_vm #41377

Merged
merged 2 commits into from
Apr 20, 2017
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
10 changes: 7 additions & 3 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// generic so we don't have to do anything quite this
// terrible.
let trace = TypeTrace::dummy(self.tcx);
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
// We can intentionally ignore obligations here, since
// this is part of a simple test for general
// "equatability". However, it's not entirely clear
// that we *ought* to be, perhaps a better thing would
// be to use a mini-fulfillment context or something
// like that.
})
})
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,15 @@ 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.
match selcx.infcx().eq_impl_headers(true,
let obligations = match selcx.infcx().eq_impl_headers(true,
&ObligationCause::dummy(),
&a_impl_header,
&b_impl_header) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
obligations
}
Err(_) => return None
}
};

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

Expand All @@ -78,6 +77,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
.map(|p| Obligation { cause: ObligationCause::dummy(),
recursion_depth: 0,
predicate: p })
.chain(obligations)
.find(|o| !selcx.evaluate_obligation(o));

if let Some(failing_obligation) = opt_failing_obligation {
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
});
}

pub fn register_predicate_obligations(&mut self,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
obligations: Vec<PredicateObligation<'tcx>>)
{
for obligation in obligations {
self.register_predicate_obligation(infcx, obligation);
}
}


pub fn region_obligations(&self,
body_id: ast::NodeId)
-> &[RegionObligation<'tcx>]
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-> Result<&'tcx Substs<'tcx>, ()> {
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
target_impl,
target_substs);

Expand All @@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
&ObligationCause::dummy(),
source_trait_ref,
target_trait_ref) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty())
Ok(InferOk { obligations: o, .. }) => {
obligations.extend(o);
}
Err(_) => {
debug!("fulfill_implication: {:?} does not unify with {:?}",
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
match self.sub(t1, t2) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());
}
Err(ref e) => {
Expand All @@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
match self.lub(t1, t2) {
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_lub);
Expand All @@ -415,7 +415,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
match self.glb(t1, t2) {
Err(e) => panic!("unexpected error computing LUB: {:?}", e),
Ok(InferOk { obligations, value: t }) => {
// FIXME(#32730) once obligations are being propagated, assert the right thing.
// None of these tests should require nested obligations:
assert!(obligations.is_empty());

self.assert_eq(t, t_glb);
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
.map(|InferOk { obligations, .. }| {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
});
.map(|InferOk { obligations, .. }| {
inh.register_predicates(obligations);
});

if let Err(terr) = sub_result {
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
Expand Down
5 changes: 2 additions & 3 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
// check that the impl type can be made to match the trait type.

let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
let tcx = infcx.tcx;
let mut fulfillment_cx = traits::FulfillmentContext::new();

Expand All @@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
fulfillment_cx.register_predicate_obligations(infcx, obligations);
}
Err(_) => {
let item_span = tcx.hir.span(self_type_node_id);
Expand Down
17 changes: 12 additions & 5 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use rustc::infer::InferOk;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
use session::config;
use util::common::time;

Expand Down Expand Up @@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
-> bool {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
let mut fulfill_cx = FulfillmentContext::new();
match infcx.eq_types(false, &cause, expected, actual) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations
assert!(obligations.is_empty());
true
fulfill_cx.register_predicate_obligations(infcx, obligations);
}
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
}

match fulfill_cx.select_all_or_error(infcx) {
Ok(()) => true,
Err(errors) => {
infcx.report_fulfillment_errors(&errors);
false
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/test/run-pass/issue-41298.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Function<T, F> { t: T, f: F }

impl<T, R> Function<T, fn() -> R> { fn foo() { } }
impl<T, R> Function<T, fn() -> R> { fn bar() { } }

fn main() { }