Skip to content

Commit a719de9

Browse files
committed
---
yaml --- r: 272634 b: refs/heads/auto c: 6acd90f h: refs/heads/master
1 parent 43cf04d commit a719de9

File tree

21 files changed

+81
-164
lines changed

21 files changed

+81
-164
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
88
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
99
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1010
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
11-
refs/heads/auto: 35dca7fb7b7304cfa8da027d1be6eea7142d90d6
11+
refs/heads/auto: 6acd90f0c91bfdb5ab2678fadaa571096a78ee5f
1212
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1313
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336
1414
refs/tags/0.2: 1754d02027f2924bed83b0160ee340c7f41d5ea1

branches/auto/src/libcore/ops.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,11 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
15391539
///
15401540
/// See the [`contains()`](#method.contains) method for its characterization.
15411541
///
1542+
/// Note: Currently, no overflow checking is done for the iterator
1543+
/// implementation; if you use an integer range and the integer overflows, it
1544+
/// might panic in debug mode or create an endless loop in release mode. This
1545+
/// overflow behavior might change in the future.
1546+
///
15421547
/// # Examples
15431548
///
15441549
/// ```

branches/auto/src/librustc/diagnostics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1543,5 +1543,4 @@ register_diagnostics! {
15431543
E0490, // a value of type `..` is borrowed for too long
15441544
E0491, // in type `..`, reference has a longer lifetime than the data it...
15451545
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
1546-
E0524, // expected a closure that implements `..` but this closure only implements `..`
15471546
}

branches/auto/src/librustc/middle/free_region.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ impl FreeRegionMap {
5959
ty::Predicate::Equate(..) |
6060
ty::Predicate::WellFormed(..) |
6161
ty::Predicate::ObjectSafe(..) |
62-
ty::Predicate::ClosureKind(..) |
6362
ty::Predicate::TypeOutlives(..) => {
6463
// No region bounds here
6564
}

branches/auto/src/librustc/traits/error_reporting.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -495,21 +495,6 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
495495
err.emit();
496496
}
497497

498-
ty::Predicate::ClosureKind(closure_def_id, kind) => {
499-
let found_kind = infcx.closure_kind(closure_def_id).unwrap();
500-
let closure_span = infcx.tcx.map.span_if_local(closure_def_id).unwrap();
501-
let mut err = struct_span_err!(
502-
infcx.tcx.sess, closure_span, E0524,
503-
"expected a closure that implements the `{}` trait, but this closure \
504-
only implements `{}`",
505-
kind,
506-
found_kind);
507-
err.span_note(
508-
obligation.cause.span,
509-
&format!("the requirement to implement `{}` derives from here", kind));
510-
err.emit();
511-
}
512-
513498
ty::Predicate::WellFormed(ty) => {
514499
// WF predicates cannot themselves make
515500
// errors. They can only block due to

branches/auto/src/librustc/traits/fulfill.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -652,21 +652,6 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
652652
}
653653
}
654654

655-
ty::Predicate::ClosureKind(closure_def_id, kind) => {
656-
match selcx.infcx().closure_kind(closure_def_id) {
657-
Some(closure_kind) => {
658-
if closure_kind.extends(kind) {
659-
Ok(Some(vec![]))
660-
} else {
661-
Err(CodeSelectionError(Unimplemented))
662-
}
663-
}
664-
None => {
665-
Ok(None)
666-
}
667-
}
668-
}
669-
670655
ty::Predicate::WellFormed(ty) => {
671656
match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
672657
ty, obligation.cause.span) {

branches/auto/src/librustc/traits/object_safety.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ pub fn supertraits_reference_self<'tcx>(tcx: &TyCtxt<'tcx>,
165165
ty::Predicate::ObjectSafe(..) |
166166
ty::Predicate::TypeOutlives(..) |
167167
ty::Predicate::RegionOutlives(..) |
168-
ty::Predicate::ClosureKind(..) |
169168
ty::Predicate::Equate(..) => {
170169
false
171170
}
@@ -208,7 +207,6 @@ fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
208207
ty::Predicate::RegionOutlives(..) |
209208
ty::Predicate::WellFormed(..) |
210209
ty::Predicate::ObjectSafe(..) |
211-
ty::Predicate::ClosureKind(..) |
212210
ty::Predicate::TypeOutlives(..) => {
213211
false
214212
}

branches/auto/src/librustc/traits/select.rs

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,9 @@ enum SelectionCandidate<'tcx> {
198198
/// we found an applicable bound in the trait definition.
199199
ProjectionCandidate,
200200

201-
/// Implementation of a `Fn`-family trait by one of the anonymous types
202-
/// generated for a `||` expression. The ty::ClosureKind informs the
203-
/// confirmation step what ClosureKind obligation to emit.
204-
ClosureCandidate(/* closure */ DefId, &'tcx ty::ClosureSubsts<'tcx>, ty::ClosureKind),
201+
/// Implementation of a `Fn`-family trait by one of the
202+
/// anonymous types generated for a `||` expression.
203+
ClosureCandidate(/* closure */ DefId, &'tcx ty::ClosureSubsts<'tcx>),
205204

206205
/// Implementation of a `Fn`-family trait by one of the anonymous
207206
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
@@ -322,11 +321,75 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
322321

323322
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
324323
match self.candidate_from_obligation(&stack)? {
325-
None => Ok(None),
324+
None => {
325+
self.consider_unification_despite_ambiguity(obligation);
326+
Ok(None)
327+
}
326328
Some(candidate) => Ok(Some(self.confirm_candidate(obligation, candidate)?)),
327329
}
328330
}
329331

332+
/// In the particular case of unboxed closure obligations, we can
333+
/// sometimes do some amount of unification for the
334+
/// argument/return types even though we can't yet fully match obligation.
335+
/// The particular case we are interesting in is an obligation of the form:
336+
///
337+
/// C : FnFoo<A>
338+
///
339+
/// where `C` is an unboxed closure type and `FnFoo` is one of the
340+
/// `Fn` traits. Because we know that users cannot write impls for closure types
341+
/// themselves, the only way that `C : FnFoo` can fail to match is under two
342+
/// conditions:
343+
///
344+
/// 1. The closure kind for `C` is not yet known, because inference isn't complete.
345+
/// 2. The closure kind for `C` *is* known, but doesn't match what is needed.
346+
/// For example, `C` may be a `FnOnce` closure, but a `Fn` closure is needed.
347+
///
348+
/// In either case, we always know what argument types are
349+
/// expected by `C`, no matter what kind of `Fn` trait it
350+
/// eventually matches. So we can go ahead and unify the argument
351+
/// types, even though the end result is ambiguous.
352+
///
353+
/// Note that this is safe *even if* the trait would never be
354+
/// matched (case 2 above). After all, in that case, an error will
355+
/// result, so it kind of doesn't matter what we do --- unifying
356+
/// the argument types can only be helpful to the user, because
357+
/// once they patch up the kind of closure that is expected, the
358+
/// argment types won't really change.
359+
fn consider_unification_despite_ambiguity(&mut self, obligation: &TraitObligation<'tcx>) {
360+
// Is this a `C : FnFoo(...)` trait reference for some trait binding `FnFoo`?
361+
match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) {
362+
Some(_) => { }
363+
None => { return; }
364+
}
365+
366+
// Is the self-type a closure type? We ignore bindings here
367+
// because if it is a closure type, it must be a closure type from
368+
// within this current fn, and hence none of the higher-ranked
369+
// lifetimes can appear inside the self-type.
370+
let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
371+
let (closure_def_id, substs) = match self_ty.sty {
372+
ty::TyClosure(id, ref substs) => (id, substs),
373+
_ => { return; }
374+
};
375+
assert!(!substs.has_escaping_regions());
376+
377+
// It is OK to call the unnormalized variant here - this is only
378+
// reached for TyClosure: Fn inputs where the closure kind is
379+
// still unknown, which should only occur in typeck where the
380+
// closure type is already normalized.
381+
let closure_trait_ref = self.closure_trait_ref_unnormalized(obligation,
382+
closure_def_id,
383+
substs);
384+
385+
match self.confirm_poly_trait_refs(obligation.cause.clone(),
386+
obligation.predicate.to_poly_trait_ref(),
387+
closure_trait_ref) {
388+
Ok(()) => { }
389+
Err(_) => { /* Silently ignore errors. */ }
390+
}
391+
}
392+
330393
///////////////////////////////////////////////////////////////////////////
331394
// EVALUATION
332395
//
@@ -469,21 +532,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
469532
}
470533
}
471534
}
472-
473-
ty::Predicate::ClosureKind(closure_def_id, kind) => {
474-
match self.infcx.closure_kind(closure_def_id) {
475-
Some(closure_kind) => {
476-
if closure_kind.extends(kind) {
477-
EvaluatedToOk
478-
} else {
479-
EvaluatedToErr
480-
}
481-
}
482-
None => {
483-
EvaluatedToAmbig
484-
}
485-
}
486-
}
487535
}
488536
}
489537

@@ -1234,12 +1282,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12341282
Some(closure_kind) => {
12351283
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
12361284
if closure_kind.extends(kind) {
1237-
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
1285+
candidates.vec.push(ClosureCandidate(closure_def_id, substs));
12381286
}
12391287
}
12401288
None => {
12411289
debug!("assemble_unboxed_candidates: closure_kind not yet known");
1242-
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
1290+
candidates.ambiguous = true;
12431291
}
12441292
}
12451293

@@ -2023,9 +2071,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20232071
Ok(VtableImpl(vtable_impl))
20242072
}
20252073

2026-
ClosureCandidate(closure_def_id, substs, kind) => {
2074+
ClosureCandidate(closure_def_id, substs) => {
20272075
let vtable_closure =
2028-
self.confirm_closure_candidate(obligation, closure_def_id, substs, kind)?;
2076+
self.confirm_closure_candidate(obligation, closure_def_id, substs)?;
20292077
Ok(VtableClosure(vtable_closure))
20302078
}
20312079

@@ -2382,8 +2430,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23822430
fn confirm_closure_candidate(&mut self,
23832431
obligation: &TraitObligation<'tcx>,
23842432
closure_def_id: DefId,
2385-
substs: &ty::ClosureSubsts<'tcx>,
2386-
kind: ty::ClosureKind)
2433+
substs: &ty::ClosureSubsts<'tcx>)
23872434
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
23882435
SelectionError<'tcx>>
23892436
{
@@ -2394,7 +2441,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23942441

23952442
let Normalized {
23962443
value: trait_ref,
2397-
mut obligations
2444+
obligations
23982445
} = self.closure_trait_ref(obligation, closure_def_id, substs);
23992446

24002447
debug!("confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
@@ -2406,10 +2453,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24062453
obligation.predicate.to_poly_trait_ref(),
24072454
trait_ref)?;
24082455

2409-
obligations.push(Obligation::new(
2410-
obligation.cause.clone(),
2411-
ty::Predicate::ClosureKind(closure_def_id, kind)));
2412-
24132456
Ok(VtableClosureData {
24142457
closure_def_id: closure_def_id,
24152458
substs: substs.clone(),

branches/auto/src/librustc/traits/util.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ impl<'a,'tcx> PredicateSet<'a,'tcx> {
6060

6161
ty::Predicate::ObjectSafe(data) =>
6262
ty::Predicate::ObjectSafe(data),
63-
64-
ty::Predicate::ClosureKind(closure_def_id, kind) =>
65-
ty::Predicate::ClosureKind(closure_def_id, kind)
6663
};
6764
self.set.insert(normalized_pred)
6865
}
@@ -159,9 +156,6 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
159156
ty::Predicate::Projection(..) => {
160157
// Nothing to elaborate in a projection predicate.
161158
}
162-
ty::Predicate::ClosureKind(..) => {
163-
// Nothing to elaborate when waiting for a closure's kind to be inferred.
164-
}
165159
ty::Predicate::RegionOutlives(..) |
166160
ty::Predicate::TypeOutlives(..) => {
167161
// Currently, we do not "elaborate" predicates like

branches/auto/src/librustc/ty/mod.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,6 @@ pub enum Predicate<'tcx> {
832832

833833
/// trait must be object-safe
834834
ObjectSafe(DefId),
835-
836-
/// No direct syntax. May be thought of as `where T : FnFoo<...>` for some 'TypeSpace'
837-
/// substitutions `...` and T being a closure type. Satisfied (or refuted) once we know the
838-
/// closure's kind.
839-
ClosureKind(DefId, ClosureKind),
840835
}
841836

842837
impl<'tcx> Predicate<'tcx> {
@@ -926,8 +921,6 @@ impl<'tcx> Predicate<'tcx> {
926921
Predicate::WellFormed(data.subst(tcx, substs)),
927922
Predicate::ObjectSafe(trait_def_id) =>
928923
Predicate::ObjectSafe(trait_def_id),
929-
Predicate::ClosureKind(closure_def_id, kind) =>
930-
Predicate::ClosureKind(closure_def_id, kind),
931924
}
932925
}
933926
}
@@ -1115,9 +1108,6 @@ impl<'tcx> Predicate<'tcx> {
11151108
ty::Predicate::ObjectSafe(_trait_def_id) => {
11161109
vec![]
11171110
}
1118-
ty::Predicate::ClosureKind(_closure_def_id, _kind) => {
1119-
vec![]
1120-
}
11211111
};
11221112

11231113
// The only reason to collect into a vector here is that I was
@@ -1138,7 +1128,6 @@ impl<'tcx> Predicate<'tcx> {
11381128
Predicate::RegionOutlives(..) |
11391129
Predicate::WellFormed(..) |
11401130
Predicate::ObjectSafe(..) |
1141-
Predicate::ClosureKind(..) |
11421131
Predicate::TypeOutlives(..) => {
11431132
None
11441133
}
@@ -1794,7 +1783,7 @@ pub struct ItemSubsts<'tcx> {
17941783
pub substs: Substs<'tcx>,
17951784
}
17961785

1797-
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
1786+
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
17981787
pub enum ClosureKind {
17991788
// Warning: Ordering is significant here! The ordering is chosen
18001789
// because the trait Fn is a subtrait of FnMut and so in turn, and

branches/auto/src/librustc/ty/structural_impls.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
644644
ty::Predicate::Projection(binder.fold_with(folder)),
645645
ty::Predicate::WellFormed(data) =>
646646
ty::Predicate::WellFormed(data.fold_with(folder)),
647-
ty::Predicate::ClosureKind(closure_def_id, kind) =>
648-
ty::Predicate::ClosureKind(closure_def_id, kind),
649647
ty::Predicate::ObjectSafe(trait_def_id) =>
650648
ty::Predicate::ObjectSafe(trait_def_id),
651649
}
@@ -659,7 +657,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
659657
ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
660658
ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
661659
ty::Predicate::WellFormed(data) => data.visit_with(visitor),
662-
ty::Predicate::ClosureKind(_closure_def_id, _kind) => false,
663660
ty::Predicate::ObjectSafe(_trait_def_id) => false,
664661
}
665662
}

branches/auto/src/librustc/ty/util.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ impl<'tcx> TyCtxt<'tcx> {
301301
ty::Predicate::Equate(..) |
302302
ty::Predicate::WellFormed(..) |
303303
ty::Predicate::ObjectSafe(..) |
304-
ty::Predicate::ClosureKind(..) |
305304
ty::Predicate::RegionOutlives(..) => {
306305
None
307306
}

branches/auto/src/librustc/ty/wf.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ pub fn predicate_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
9292
}
9393
ty::Predicate::ObjectSafe(_) => {
9494
}
95-
ty::Predicate::ClosureKind(..) => {
96-
}
9795
}
9896

9997
wf.normalize()
@@ -157,7 +155,6 @@ pub fn implied_bounds<'a,'tcx>(
157155
ty::Predicate::Trait(..) |
158156
ty::Predicate::Equate(..) |
159157
ty::Predicate::Projection(..) |
160-
ty::Predicate::ClosureKind(..) |
161158
ty::Predicate::ObjectSafe(..) =>
162159
vec![],
163160

0 commit comments

Comments
 (0)