Implement a hacky version of the DAG support we ultimately want, leaving
a FIXME for later.
This commit is contained in:
parent
3046ac217f
commit
57c31b2849
src
@ -319,12 +319,58 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
|
||||
FulfillmentErrorCode<'tcx>>
|
||||
{
|
||||
match process_predicate1(selcx, pending_obligation, backtrace, region_obligations) {
|
||||
Ok(Some(v)) => Ok(Some(v.into_iter()
|
||||
.map(|o| PendingPredicateObligation {
|
||||
obligation: o,
|
||||
stalled_on: vec![]
|
||||
})
|
||||
.collect())),
|
||||
Ok(Some(v)) => {
|
||||
// FIXME the right thing to do here, I think, is to permit
|
||||
// DAGs. That is, we should detect whenever this predicate
|
||||
// has appeared somewhere in the current tree./ If it's a
|
||||
// parent, that's a cycle, and we should either error out
|
||||
// or consider it ok. But if it's NOT a parent, we can
|
||||
// ignore it, since it will be proven (or not) separately.
|
||||
// However, this is a touch tricky, so I'm doing something
|
||||
// a bit hackier for now so that the `huge-struct.rs` passes.
|
||||
|
||||
let retain_vec: Vec<_> = {
|
||||
let mut dedup = FnvHashSet();
|
||||
v.iter()
|
||||
.map(|o| {
|
||||
// Screen out obligations that we know globally
|
||||
// are true. This should really be the DAG check
|
||||
// mentioned above.
|
||||
if
|
||||
o.predicate.is_global() &&
|
||||
selcx.tcx().fulfilled_predicates.borrow().is_duplicate(&o.predicate)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we see two siblings that are exactly the
|
||||
// same, no need to add them twice.
|
||||
if !dedup.insert(&o.predicate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
let pending_predicate_obligations =
|
||||
v.into_iter()
|
||||
.zip(retain_vec)
|
||||
.flat_map(|(o, retain)| {
|
||||
if retain {
|
||||
Some(PendingPredicateObligation {
|
||||
obligation: o,
|
||||
stalled_on: vec![]
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Some(pending_predicate_obligations))
|
||||
}
|
||||
Ok(None) => Ok(None),
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ impl<'a> Publisher<'a> for MyStruct<'a> {
|
||||
//~^^ ERROR cannot infer
|
||||
//~| ERROR cannot infer
|
||||
//~| ERROR cannot infer
|
||||
//~| ERROR cannot infer
|
||||
//
|
||||
// The fact that `Publisher` is using an implicit lifetime is
|
||||
// what was causing the debruijn accounting to be off, so
|
||||
|
@ -19,8 +19,8 @@ impl<T:Dot> Dot for Cons<T> {
|
||||
self.head * other.head + self.tail.dot(other.tail)
|
||||
}
|
||||
}
|
||||
fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize {
|
||||
match n { 0 => {first.dot(second)} //~ ERROR overflow
|
||||
fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize { //~ ERROR recursion limit
|
||||
match n { 0 => {first.dot(second)}
|
||||
// FIXME(#4287) Error message should be here. It should be
|
||||
// a type error to instantiate `test` at a type other than T.
|
||||
_ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
|
||||
|
Loading…
x
Reference in New Issue
Block a user