Skip to content

Commit 44548a6

Browse files
arielb1Ariel Ben-Yehuda
authored andcommitted
---
yaml --- r: 225963 b: refs/heads/stable c: 21fd312 h: refs/heads/master i: 225961: bf921e8 225959: ed53646 v: v3
1 parent 25679ce commit 44548a6

File tree

8 files changed

+170
-49
lines changed

8 files changed

+170
-49
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ refs/heads/tmp: e5d90d98402475b6e154ce216f9efcb80da1a747
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: 1fe32ca12c51afcd761d9962f51a74ff0d07a591
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 56d765d0eb2121e4a345656351a24cb0d9d68b22
32+
refs/heads/stable: 21fd312043818d0e92f44223a49a0d66d1e2880b
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b

branches/stable/src/librustc/middle/traits/mod.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ pub enum Vtable<'tcx, N> {
245245
/// Vtable automatically generated for a closure. The def ID is the ID
246246
/// of the closure expression. This is a `VtableImpl` in spirit, but the
247247
/// impl is generated by the compiler and does not appear in the source.
248-
VtableClosure(ast::DefId, subst::Substs<'tcx>),
248+
VtableClosure(VtableClosureData<'tcx, N>),
249249

250250
/// Same as above, but for a fn pointer type with the given signature.
251251
VtableFnPointer(ty::Ty<'tcx>),
@@ -268,7 +268,16 @@ pub struct VtableImplData<'tcx, N> {
268268
pub nested: Vec<N>
269269
}
270270

271-
#[derive(Debug,Clone)]
271+
#[derive(Clone, PartialEq, Eq)]
272+
pub struct VtableClosureData<'tcx, N> {
273+
pub closure_def_id: ast::DefId,
274+
pub substs: subst::Substs<'tcx>,
275+
/// Nested obligations. This can be non-empty if the closure
276+
/// signature contains associated types.
277+
pub nested: Vec<N>
278+
}
279+
280+
#[derive(Debug, Clone)]
272281
pub struct VtableDefaultImplData<N> {
273282
pub trait_def_id: ast::DefId,
274283
pub nested: Vec<N>
@@ -502,8 +511,8 @@ impl<'tcx, N> Vtable<'tcx, N> {
502511
VtableParam(n) => n,
503512
VtableBuiltin(i) => i.nested,
504513
VtableDefaultImpl(d) => d.nested,
505-
VtableObject(_) | VtableFnPointer(..) |
506-
VtableClosure(..) => vec![]
514+
VtableClosure(c) => c.nested,
515+
VtableObject(_) | VtableFnPointer(..) => vec![]
507516
}
508517
}
509518

@@ -524,7 +533,11 @@ impl<'tcx, N> Vtable<'tcx, N> {
524533
nested: d.nested.into_iter().map(f).collect()
525534
}),
526535
VtableFnPointer(f) => VtableFnPointer(f),
527-
VtableClosure(d, s) => VtableClosure(d, s),
536+
VtableClosure(c) => VtableClosure(VtableClosureData {
537+
closure_def_id: c.closure_def_id,
538+
substs: c.substs,
539+
nested: c.nested.into_iter().map(f).collect()
540+
})
528541
}
529542
}
530543
}

branches/stable/src/librustc/middle/traits/project.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ use super::ObligationCause;
1717
use super::PredicateObligation;
1818
use super::SelectionContext;
1919
use super::SelectionError;
20+
use super::VtableClosureData;
2021
use super::VtableImplData;
2122
use super::util;
2223

2324
use middle::infer;
24-
use middle::subst::{Subst, Substs};
25+
use middle::subst::Subst;
2526
use middle::ty::{self, AsPredicate, ReferencesError, RegionEscape,
2627
HasProjectionTypes, ToPolyTraitRef, Ty};
2728
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
28-
use syntax::ast;
2929
use syntax::parse::token;
3030
use util::common::FN_OUTPUT_NAME;
3131
use util::ppaux::Repr;
@@ -57,7 +57,7 @@ pub struct MismatchedProjectionTypes<'tcx> {
5757
enum ProjectionTyCandidate<'tcx> {
5858
ParamEnv(ty::PolyProjectionPredicate<'tcx>),
5959
Impl(VtableImplData<'tcx, PredicateObligation<'tcx>>),
60-
Closure(ast::DefId, Substs<'tcx>),
60+
Closure(VtableClosureData<'tcx, PredicateObligation<'tcx>>),
6161
FnPointer(Ty<'tcx>),
6262
}
6363

@@ -162,11 +162,16 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
162162
self_ty,
163163
&closure_type.sig,
164164
util::TupleArgumentsFlag::No);
165+
// We don't have to normalize the return type here - this is only
166+
// reached for TyClosure: Fn inputs where the closure kind is
167+
// still unknown, which should only occur in typeck where the
168+
// closure type is already normalized.
165169
let (ret_type, _) =
166170
infcx.replace_late_bound_regions_with_fresh_var(
167171
obligation.cause.span,
168172
infer::AssocTypeProjection(obligation.predicate.projection_ty.item_name),
169173
&ty::Binder(ret_type));
174+
170175
debug!("consider_unification_despite_ambiguity: ret_type={:?}",
171176
ret_type.repr(selcx.tcx()));
172177
let origin = infer::RelateOutputImplTypes(obligation.cause.span);
@@ -686,9 +691,9 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
686691
selcx, obligation, obligation_trait_ref, candidate_set,
687692
data.object_ty);
688693
}
689-
super::VtableClosure(closure_def_id, substs) => {
694+
super::VtableClosure(data) => {
690695
candidate_set.vec.push(
691-
ProjectionTyCandidate::Closure(closure_def_id, substs));
696+
ProjectionTyCandidate::Closure(data));
692697
}
693698
super::VtableFnPointer(fn_type) => {
694699
candidate_set.vec.push(
@@ -755,8 +760,8 @@ fn confirm_candidate<'cx,'tcx>(
755760
confirm_impl_candidate(selcx, obligation, impl_vtable)
756761
}
757762

758-
ProjectionTyCandidate::Closure(def_id, substs) => {
759-
confirm_closure_candidate(selcx, obligation, def_id, &substs)
763+
ProjectionTyCandidate::Closure(closure_vtable) => {
764+
confirm_closure_candidate(selcx, obligation, closure_vtable)
760765
}
761766

762767
ProjectionTyCandidate::FnPointer(fn_type) => {
@@ -779,13 +784,24 @@ fn confirm_fn_pointer_candidate<'cx,'tcx>(
779784
fn confirm_closure_candidate<'cx,'tcx>(
780785
selcx: &mut SelectionContext<'cx,'tcx>,
781786
obligation: &ProjectionTyObligation<'tcx>,
782-
closure_def_id: ast::DefId,
783-
substs: &Substs<'tcx>)
787+
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>)
784788
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
785789
{
786790
let closure_typer = selcx.closure_typer();
787-
let closure_type = closure_typer.closure_type(closure_def_id, substs);
788-
confirm_callable_candidate(selcx, obligation, &closure_type.sig, util::TupleArgumentsFlag::No)
791+
let closure_type = closure_typer.closure_type(vtable.closure_def_id, &vtable.substs);
792+
let Normalized {
793+
value: closure_type,
794+
mut obligations
795+
} = normalize_with_depth(selcx,
796+
obligation.cause.clone(),
797+
obligation.recursion_depth+1,
798+
&closure_type);
799+
let (ty, mut cc_obligations) = confirm_callable_candidate(selcx,
800+
obligation,
801+
&closure_type.sig,
802+
util::TupleArgumentsFlag::No);
803+
obligations.append(&mut cc_obligations);
804+
(ty, obligations)
789805
}
790806

791807
fn confirm_callable_candidate<'cx,'tcx>(
@@ -797,7 +813,7 @@ fn confirm_callable_candidate<'cx,'tcx>(
797813
{
798814
let tcx = selcx.tcx();
799815

800-
debug!("confirm_closure_candidate({},{})",
816+
debug!("confirm_callable_candidate({},{})",
801817
obligation.repr(tcx),
802818
fn_sig.repr(tcx));
803819

@@ -921,8 +937,8 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
921937
format!("ParamEnv({})", data.repr(tcx)),
922938
ProjectionTyCandidate::Impl(ref data) =>
923939
format!("Impl({})", data.repr(tcx)),
924-
ProjectionTyCandidate::Closure(ref a, ref b) =>
925-
format!("Closure(({},{}))", a.repr(tcx), b.repr(tcx)),
940+
ProjectionTyCandidate::Closure(ref data) =>
941+
format!("Closure({})", data.repr(tcx)),
926942
ProjectionTyCandidate::FnPointer(a) =>
927943
format!("FnPointer(({}))", a.repr(tcx)),
928944
}

branches/stable/src/librustc/middle/traits/select.rs

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ use super::Selection;
3131
use super::SelectionResult;
3232
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
3333
VtableFnPointer, VtableObject, VtableDefaultImpl};
34-
use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableDefaultImplData};
34+
use super::{VtableImplData, VtableObjectData, VtableBuiltinData,
35+
VtableClosureData, VtableDefaultImplData};
3536
use super::object_safety;
3637
use super::util;
3738

@@ -355,7 +356,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
355356
};
356357
assert!(!substs.has_escaping_regions());
357358

358-
let closure_trait_ref = self.closure_trait_ref(obligation, closure_def_id, substs);
359+
// It is OK to call the unnormalized variant here - this is only
360+
// reached for TyClosure: Fn inputs where the closure kind is
361+
// still unknown, which should only occur in typeck where the
362+
// closure type is already normalized.
363+
let closure_trait_ref = self.closure_trait_ref_unnormalized(obligation,
364+
closure_def_id,
365+
substs);
366+
359367
match self.confirm_poly_trait_refs(obligation.cause.clone(),
360368
obligation.predicate.to_poly_trait_ref(),
361369
closure_trait_ref) {
@@ -2001,8 +2009,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20012009
}
20022010

20032011
ClosureCandidate(closure_def_id, substs) => {
2004-
try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
2005-
Ok(VtableClosure(closure_def_id, substs))
2012+
let vtable_closure =
2013+
try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
2014+
Ok(VtableClosure(vtable_closure))
20062015
}
20072016

20082017
BuiltinObjectCandidate => {
@@ -2343,24 +2352,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23432352
obligation: &TraitObligation<'tcx>,
23442353
closure_def_id: ast::DefId,
23452354
substs: &Substs<'tcx>)
2346-
-> Result<(),SelectionError<'tcx>>
2355+
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
2356+
SelectionError<'tcx>>
23472357
{
23482358
debug!("confirm_closure_candidate({},{},{})",
23492359
obligation.repr(self.tcx()),
23502360
closure_def_id.repr(self.tcx()),
23512361
substs.repr(self.tcx()));
23522362

2353-
let trait_ref = self.closure_trait_ref(obligation,
2354-
closure_def_id,
2355-
substs);
2363+
let Normalized {
2364+
value: trait_ref,
2365+
obligations
2366+
} = self.closure_trait_ref(obligation, closure_def_id, substs);
23562367

2357-
debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={})",
2368+
debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={}, obligations={})",
23582369
closure_def_id.repr(self.tcx()),
2359-
trait_ref.repr(self.tcx()));
2370+
trait_ref.repr(self.tcx()),
2371+
obligations.repr(self.tcx()));
2372+
2373+
try!(self.confirm_poly_trait_refs(obligation.cause.clone(),
2374+
obligation.predicate.to_poly_trait_ref(),
2375+
trait_ref));
23602376

2361-
self.confirm_poly_trait_refs(obligation.cause.clone(),
2362-
obligation.predicate.to_poly_trait_ref(),
2363-
trait_ref)
2377+
Ok(VtableClosureData {
2378+
closure_def_id: closure_def_id,
2379+
substs: substs.clone(),
2380+
nested: obligations
2381+
})
23642382
}
23652383

23662384
/// In the case of closure types and fn pointers,
@@ -2819,11 +2837,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28192837
}
28202838
}
28212839

2822-
fn closure_trait_ref(&self,
2823-
obligation: &TraitObligation<'tcx>,
2824-
closure_def_id: ast::DefId,
2825-
substs: &Substs<'tcx>)
2826-
-> ty::PolyTraitRef<'tcx>
2840+
fn closure_trait_ref_unnormalized(&mut self,
2841+
obligation: &TraitObligation<'tcx>,
2842+
closure_def_id: ast::DefId,
2843+
substs: &Substs<'tcx>)
2844+
-> ty::PolyTraitRef<'tcx>
28272845
{
28282846
let closure_type = self.closure_typer.closure_type(closure_def_id, substs);
28292847
let ty::Binder((trait_ref, _)) =
@@ -2832,7 +2850,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28322850
obligation.predicate.0.self_ty(), // (1)
28332851
&closure_type.sig,
28342852
util::TupleArgumentsFlag::No);
2835-
28362853
// (1) Feels icky to skip the binder here, but OTOH we know
28372854
// that the self-type is an unboxed closure type and hence is
28382855
// in fact unparameterized (or at least does not reference any
@@ -2842,6 +2859,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28422859
ty::Binder(trait_ref)
28432860
}
28442861

2862+
fn closure_trait_ref(&mut self,
2863+
obligation: &TraitObligation<'tcx>,
2864+
closure_def_id: ast::DefId,
2865+
substs: &Substs<'tcx>)
2866+
-> Normalized<'tcx, ty::PolyTraitRef<'tcx>>
2867+
{
2868+
let trait_ref = self.closure_trait_ref_unnormalized(
2869+
obligation, closure_def_id, substs);
2870+
2871+
// A closure signature can contain associated types which
2872+
// must be normalized.
2873+
normalize_with_depth(self,
2874+
obligation.cause.clone(),
2875+
obligation.recursion_depth+1,
2876+
&trait_ref)
2877+
}
2878+
28452879
/// Returns the obligations that are implied by instantiating an
28462880
/// impl or trait. The obligations are substituted and fully
28472881
/// normalized. This is used when confirming an impl or default

branches/stable/src/librustc/middle/traits/util.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,12 @@ impl<'tcx, N> fmt::Debug for VtableImplData<'tcx, N> {
308308
}
309309
}
310310

311+
impl<'tcx, N> fmt::Debug for super::VtableClosureData<'tcx, N> {
312+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
313+
write!(f, "VtableClosure({:?})", self.closure_def_id)
314+
}
315+
}
316+
311317
impl<'tcx> fmt::Debug for super::VtableObjectData<'tcx> {
312318
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
313319
write!(f, "VtableObject(...)")
@@ -497,10 +503,8 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
497503
super::VtableDefaultImpl(ref t) =>
498504
t.repr(tcx),
499505

500-
super::VtableClosure(ref d, ref s) =>
501-
format!("VtableClosure({},{})",
502-
d.repr(tcx),
503-
s.repr(tcx)),
506+
super::VtableClosure(ref d) =>
507+
d.repr(tcx),
504508

505509
super::VtableFnPointer(ref d) =>
506510
format!("VtableFnPointer({})",
@@ -529,6 +533,15 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableImplData<'tcx, N> {
529533
}
530534
}
531535

536+
impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableClosureData<'tcx, N> {
537+
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
538+
format!("VtableClosure(closure_def_id={}, substs={}, nested={})",
539+
self.closure_def_id.repr(tcx),
540+
self.substs.repr(tcx),
541+
self.nested.repr(tcx))
542+
}
543+
}
544+
532545
impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableBuiltinData<N> {
533546
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
534547
format!("VtableBuiltin(nested={})",

branches/stable/src/librustc/middle/ty_fold.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,16 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<
479479
}
480480
}
481481

482+
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
483+
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableClosureData<'tcx, N> {
484+
traits::VtableClosureData {
485+
closure_def_id: self.closure_def_id,
486+
substs: self.substs.fold_with(folder),
487+
nested: self.nested.fold_with(folder),
488+
}
489+
}
490+
}
491+
482492
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData<N> {
483493
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableDefaultImplData<N> {
484494
traits::VtableDefaultImplData {
@@ -501,8 +511,8 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
501511
match *self {
502512
traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
503513
traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)),
504-
traits::VtableClosure(d, ref s) => {
505-
traits::VtableClosure(d, s.fold_with(folder))
514+
traits::VtableClosure(ref d) => {
515+
traits::VtableClosure(d.fold_with(folder))
506516
}
507517
traits::VtableFnPointer(ref d) => {
508518
traits::VtableFnPointer(d.fold_with(folder))

0 commit comments

Comments
 (0)