Skip to content

Commit 298946b

Browse files
committed
---
yaml --- r: 219391 b: refs/heads/snap-stage3 c: 5726026 h: refs/heads/master i: 219389: 7112926 219387: eb5c059 219383: f548767 219375: ead05ef 219359: 9eb34fe 219327: fe4b198 219263: a123f1a 219135: 196ee9c v: v3
1 parent b67d769 commit 298946b

File tree

15 files changed

+115
-267
lines changed

15 files changed

+115
-267
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: c044791d80ea0dc5c4b57b6030a67b69f8510239
3-
refs/heads/snap-stage3: da55e244a6829e94ef94c4e43243a3436b6a2dd4
3+
refs/heads/snap-stage3: 57260262e76ec35f05d4a9fad4d13cda212f2c62
44
refs/heads/try: b53c0f93eedcdedd4fd89bccc5a3a09d1c5cd23e
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

branches/snap-stage3/src/librustc/middle/traits/mod.rs

Lines changed: 64 additions & 34 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(VtableClosureData<'tcx, N>),
248+
VtableClosure(ast::DefId, subst::Substs<'tcx>),
249249

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

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)]
271+
#[derive(Debug,Clone)]
281272
pub struct VtableDefaultImplData<N> {
282273
pub trait_def_id: ast::DefId,
283274
pub nested: Vec<N>
@@ -313,12 +304,12 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
313304
/// `bound` or is not known to meet bound (note that this is
314305
/// conservative towards *no impl*, which is the opposite of the
315306
/// `evaluate` methods).
316-
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
317-
typer: &ty::ClosureTyper<'tcx>,
318-
ty: Ty<'tcx>,
319-
bound: ty::BuiltinBound,
320-
span: Span)
321-
-> bool
307+
pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
308+
typer: &ty::ClosureTyper<'tcx>,
309+
ty: Ty<'tcx>,
310+
bound: ty::BuiltinBound,
311+
span: Span)
312+
-> SelectionResult<'tcx, ()>
322313
{
323314
debug!("type_known_to_meet_builtin_bound(ty={}, bound={:?})",
324315
ty.repr(infcx.tcx),
@@ -336,18 +327,61 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
336327
// Note: we only assume something is `Copy` if we can
337328
// *definitively* show that it implements `Copy`. Otherwise,
338329
// assume it is move; linear is always ok.
339-
match fulfill_cx.select_all_or_error(infcx, typer) {
340-
Ok(()) => {
341-
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} success",
342-
ty.repr(infcx.tcx),
343-
bound);
330+
let result = match fulfill_cx.select_all_or_error(infcx, typer) {
331+
Ok(()) => Ok(Some(())), // Success, we know it implements Copy.
332+
Err(errors) => {
333+
// If there were any hard errors, propagate an arbitrary
334+
// one of those. If no hard errors at all, report
335+
// ambiguity.
336+
let sel_error =
337+
errors.iter()
338+
.filter_map(|err| {
339+
match err.code {
340+
CodeAmbiguity => None,
341+
CodeSelectionError(ref e) => Some(e.clone()),
342+
CodeProjectionError(_) => {
343+
infcx.tcx.sess.span_bug(
344+
span,
345+
"projection error while selecting?")
346+
}
347+
}
348+
})
349+
.next();
350+
match sel_error {
351+
None => { Ok(None) }
352+
Some(e) => { Err(e) }
353+
}
354+
}
355+
};
356+
357+
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} result={:?}",
358+
ty.repr(infcx.tcx),
359+
bound,
360+
result);
361+
362+
result
363+
}
364+
365+
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
366+
typer: &ty::ClosureTyper<'tcx>,
367+
ty: Ty<'tcx>,
368+
bound: ty::BuiltinBound,
369+
span: Span)
370+
-> bool
371+
{
372+
match evaluate_builtin_bound(infcx, typer, ty, bound, span) {
373+
Ok(Some(())) => {
374+
// definitely impl'd
344375
true
345376
}
346-
Err(e) => {
347-
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} errors={}",
348-
ty.repr(infcx.tcx),
349-
bound,
350-
e.repr(infcx.tcx));
377+
Ok(None) => {
378+
// ambiguous: if coherence check was successful, shouldn't
379+
// happen, but we might have reported an error and been
380+
// soldering on, so just treat this like not implemented
381+
false
382+
}
383+
Err(_) => {
384+
// errors: not implemented.
351385
false
352386
}
353387
}
@@ -511,8 +545,8 @@ impl<'tcx, N> Vtable<'tcx, N> {
511545
VtableParam(n) => n,
512546
VtableBuiltin(i) => i.nested,
513547
VtableDefaultImpl(d) => d.nested,
514-
VtableClosure(c) => c.nested,
515-
VtableObject(_) | VtableFnPointer(..) => vec![]
548+
VtableObject(_) | VtableFnPointer(..) |
549+
VtableClosure(..) => vec![]
516550
}
517551
}
518552

@@ -533,11 +567,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
533567
nested: d.nested.into_iter().map(f).collect()
534568
}),
535569
VtableFnPointer(f) => VtableFnPointer(f),
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-
})
570+
VtableClosure(d, s) => VtableClosure(d, s),
541571
}
542572
}
543573
}

branches/snap-stage3/src/librustc/middle/traits/project.rs

Lines changed: 14 additions & 30 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;
2120
use super::VtableImplData;
2221
use super::util;
2322

2423
use middle::infer;
25-
use middle::subst::Subst;
24+
use middle::subst::{Subst, Substs};
2625
use middle::ty::{self, AsPredicate, ReferencesError, RegionEscape,
2726
HasProjectionTypes, ToPolyTraitRef, Ty};
2827
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(VtableClosureData<'tcx, PredicateObligation<'tcx>>),
60+
Closure(ast::DefId, Substs<'tcx>),
6161
FnPointer(Ty<'tcx>),
6262
}
6363

@@ -162,16 +162,11 @@ 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.
169165
let (ret_type, _) =
170166
infcx.replace_late_bound_regions_with_fresh_var(
171167
obligation.cause.span,
172168
infer::AssocTypeProjection(obligation.predicate.projection_ty.item_name),
173169
&ty::Binder(ret_type));
174-
175170
debug!("consider_unification_despite_ambiguity: ret_type={:?}",
176171
ret_type.repr(selcx.tcx()));
177172
let origin = infer::RelateOutputImplTypes(obligation.cause.span);
@@ -691,9 +686,9 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
691686
selcx, obligation, obligation_trait_ref, candidate_set,
692687
data.object_ty);
693688
}
694-
super::VtableClosure(data) => {
689+
super::VtableClosure(closure_def_id, substs) => {
695690
candidate_set.vec.push(
696-
ProjectionTyCandidate::Closure(data));
691+
ProjectionTyCandidate::Closure(closure_def_id, substs));
697692
}
698693
super::VtableFnPointer(fn_type) => {
699694
candidate_set.vec.push(
@@ -760,8 +755,8 @@ fn confirm_candidate<'cx,'tcx>(
760755
confirm_impl_candidate(selcx, obligation, impl_vtable)
761756
}
762757

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

767762
ProjectionTyCandidate::FnPointer(fn_type) => {
@@ -784,24 +779,13 @@ fn confirm_fn_pointer_candidate<'cx,'tcx>(
784779
fn confirm_closure_candidate<'cx,'tcx>(
785780
selcx: &mut SelectionContext<'cx,'tcx>,
786781
obligation: &ProjectionTyObligation<'tcx>,
787-
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>)
782+
closure_def_id: ast::DefId,
783+
substs: &Substs<'tcx>)
788784
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
789785
{
790786
let closure_typer = selcx.closure_typer();
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)
787+
let closure_type = closure_typer.closure_type(closure_def_id, substs);
788+
confirm_callable_candidate(selcx, obligation, &closure_type.sig, util::TupleArgumentsFlag::No)
805789
}
806790

807791
fn confirm_callable_candidate<'cx,'tcx>(
@@ -813,7 +797,7 @@ fn confirm_callable_candidate<'cx,'tcx>(
813797
{
814798
let tcx = selcx.tcx();
815799

816-
debug!("confirm_callable_candidate({},{})",
800+
debug!("confirm_closure_candidate({},{})",
817801
obligation.repr(tcx),
818802
fn_sig.repr(tcx));
819803

@@ -937,8 +921,8 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
937921
format!("ParamEnv({})", data.repr(tcx)),
938922
ProjectionTyCandidate::Impl(ref data) =>
939923
format!("Impl({})", data.repr(tcx)),
940-
ProjectionTyCandidate::Closure(ref data) =>
941-
format!("Closure({})", data.repr(tcx)),
924+
ProjectionTyCandidate::Closure(ref a, ref b) =>
925+
format!("Closure(({},{}))", a.repr(tcx), b.repr(tcx)),
942926
ProjectionTyCandidate::FnPointer(a) =>
943927
format!("FnPointer(({}))", a.repr(tcx)),
944928
}

branches/snap-stage3/src/librustc/middle/traits/select.rs

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

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

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-
358+
let closure_trait_ref = self.closure_trait_ref(obligation, closure_def_id, substs);
367359
match self.confirm_poly_trait_refs(obligation.cause.clone(),
368360
obligation.predicate.to_poly_trait_ref(),
369361
closure_trait_ref) {
@@ -2009,9 +2001,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20092001
}
20102002

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

20172008
BuiltinObjectCandidate => {
@@ -2352,33 +2343,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23522343
obligation: &TraitObligation<'tcx>,
23532344
closure_def_id: ast::DefId,
23542345
substs: &Substs<'tcx>)
2355-
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
2356-
SelectionError<'tcx>>
2346+
-> Result<(),SelectionError<'tcx>>
23572347
{
23582348
debug!("confirm_closure_candidate({},{},{})",
23592349
obligation.repr(self.tcx()),
23602350
closure_def_id.repr(self.tcx()),
23612351
substs.repr(self.tcx()));
23622352

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

2368-
debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={}, obligations={})",
2357+
debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={})",
23692358
closure_def_id.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));
2359+
trait_ref.repr(self.tcx()));
23762360

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

23842366
/// In the case of closure types and fn pointers,
@@ -2837,11 +2819,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28372819
}
28382820
}
28392821

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>
2822+
fn closure_trait_ref(&self,
2823+
obligation: &TraitObligation<'tcx>,
2824+
closure_def_id: ast::DefId,
2825+
substs: &Substs<'tcx>)
2826+
-> ty::PolyTraitRef<'tcx>
28452827
{
28462828
let closure_type = self.closure_typer.closure_type(closure_def_id, substs);
28472829
let ty::Binder((trait_ref, _)) =
@@ -2850,6 +2832,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28502832
obligation.predicate.0.self_ty(), // (1)
28512833
&closure_type.sig,
28522834
util::TupleArgumentsFlag::No);
2835+
28532836
// (1) Feels icky to skip the binder here, but OTOH we know
28542837
// that the self-type is an unboxed closure type and hence is
28552838
// in fact unparameterized (or at least does not reference any
@@ -2859,23 +2842,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28592842
ty::Binder(trait_ref)
28602843
}
28612844

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-
28792845
/// Returns the obligations that are implied by instantiating an
28802846
/// impl or trait. The obligations are substituted and fully
28812847
/// normalized. This is used when confirming an impl or default

0 commit comments

Comments
 (0)