Skip to content

Commit 622c1d4

Browse files
author
Ariel Ben-Yehuda
committed
make stalled_on more comprehensive
Basically fixes rust-lang#25916
1 parent 9a07087 commit 622c1d4

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

src/librustc/middle/traits/fulfill.rs

+30-12
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use dep_graph::DepGraph;
1212
use middle::infer::InferCtxt;
13-
use middle::ty::{self, Ty, TypeFoldable};
13+
use middle::ty::{self, Ty, TypeFoldable, ToPolyTraitRef};
1414
use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error};
1515
use std::iter;
1616
use syntax::ast;
@@ -378,6 +378,20 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
378378
}
379379
}
380380

381+
/// Return the set of type variables contained in a trait ref
382+
fn trait_ref_type_vars<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>,
383+
t: ty::PolyTraitRef<'tcx>) -> Vec<Ty<'tcx>>
384+
{
385+
t.skip_binder() // ok b/c this check doesn't care about regions
386+
.input_types()
387+
.iter()
388+
.map(|t| selcx.infcx().resolve_type_vars_if_possible(t))
389+
.filter(|t| t.has_infer_types())
390+
.flat_map(|t| t.walk())
391+
.filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false })
392+
.collect()
393+
}
394+
381395
/// Processes a predicate obligation and returns either:
382396
/// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true
383397
/// - `Ok(None)` if we don't have enough info to be sure
@@ -394,7 +408,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
394408
// doing more work yet
395409
if !pending_obligation.stalled_on.is_empty() {
396410
if pending_obligation.stalled_on.iter().all(|&ty| {
397-
let resolved_ty = selcx.infcx().resolve_type_vars_if_possible(&ty);
411+
let resolved_ty = selcx.infcx().shallow_resolve(&ty);
398412
resolved_ty == ty // nothing changed here
399413
}) {
400414
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
@@ -441,14 +455,7 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
441455
// of its type, and those types are resolved at
442456
// the same time.
443457
pending_obligation.stalled_on =
444-
data.skip_binder() // ok b/c this check doesn't care about regions
445-
.input_types()
446-
.iter()
447-
.map(|t| selcx.infcx().resolve_type_vars_if_possible(t))
448-
.filter(|t| t.has_infer_types())
449-
.flat_map(|t| t.walk())
450-
.filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false })
451-
.collect();
458+
trait_ref_type_vars(selcx, data.to_poly_trait_ref());
452459

453460
debug!("process_predicate: pending obligation {:?} now stalled on {:?}",
454461
selcx.infcx().resolve_type_vars_if_possible(obligation),
@@ -514,6 +521,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
514521
ty::Predicate::Projection(ref data) => {
515522
let project_obligation = obligation.with(data.clone());
516523
match project::poly_project_and_unify_type(selcx, &project_obligation) {
524+
Ok(None) => {
525+
pending_obligation.stalled_on =
526+
trait_ref_type_vars(selcx, data.to_poly_trait_ref());
527+
Ok(None)
528+
}
517529
Ok(v) => Ok(v),
518530
Err(e) => Err(CodeProjectionError(e))
519531
}
@@ -528,8 +540,14 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
528540
}
529541

530542
ty::Predicate::WellFormed(ty) => {
531-
Ok(ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
532-
ty, obligation.cause.span))
543+
match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
544+
ty, obligation.cause.span) {
545+
None => {
546+
pending_obligation.stalled_on = vec![ty];
547+
Ok(None)
548+
}
549+
s => Ok(s)
550+
}
533551
}
534552
}
535553
}

src/librustc/middle/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ impl<'tcx> ToPolyTraitRef<'tcx> for TraitRef<'tcx> {
917917

918918
impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
919919
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
920-
self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
920+
self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
921921
}
922922
}
923923

@@ -928,7 +928,7 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
928928
// This is because here `self` has a `Binder` and so does our
929929
// return value, so we are preserving the number of binding
930930
// levels.
931-
ty::Binder(self.0.projection_ty.trait_ref.clone())
931+
ty::Binder(self.0.projection_ty.trait_ref)
932932
}
933933
}
934934

src/test/run-pass/issue-25916.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
fn main() {
2+
macro_rules! f {
3+
() => { 0 + 0 }
4+
}
5+
// 16 per line
6+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
7+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
8+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
9+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
10+
11+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
12+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
13+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
14+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
15+
16+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
17+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
18+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
19+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
20+
21+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
22+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
23+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
24+
f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();
25+
}

0 commit comments

Comments
 (0)