Skip to content

Commit 6f00e7d

Browse files
committed
---
yaml --- r: 277071 b: refs/heads/try c: 2b5d24a h: refs/heads/master i: 277069: 075d038 277067: 588fb95 277063: 5f27d0c 277055: 40bcaf2
1 parent 4a94925 commit 6f00e7d

File tree

38 files changed

+694
-119
lines changed

38 files changed

+694
-119
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 6dbb0e86aec11050480beb76eade6fb805010ba7
33
refs/heads/snap-stage3: 235d77457d80b549dad3ac36d94f235208a1eafb
4-
refs/heads/try: 05a3fea8f6b425889f905c7b1dca47139e7df63f
4+
refs/heads/try: 2b5d24ac5a3b5dc2ca8efe317f3c0771295ba8fd
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
/stage3/
7979
/test/
8080
/tmp/
81+
/obj/
8182
TAGS
8283
TAGS.emacs
8384
TAGS.vi

branches/try/RELEASES.md

Lines changed: 288 additions & 0 deletions
Large diffs are not rendered by default.

branches/try/src/bootstrap/build/step.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ fn top_level(build: &Build) -> Vec<Step> {
150150
src: Source::Llvm { _dummy: () },
151151
target: &build.config.build,
152152
};
153-
targets.push(t.doc(stage));
153+
if build.config.docs {
154+
targets.push(t.doc(stage));
155+
}
154156
for host in build.config.host.iter() {
155157
if !build.flags.host.contains(host) {
156158
continue
@@ -356,7 +358,9 @@ impl<'a> Step<'a> {
356358
let compiler = self.compiler(stage);
357359
for target in build.config.target.iter() {
358360
let target = self.target(target);
359-
base.push(target.dist_docs(stage));
361+
if build.config.docs {
362+
base.push(target.dist_docs(stage));
363+
}
360364
base.push(target.dist_std(compiler));
361365
}
362366
}

branches/try/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/try/src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,4 +1543,5 @@ 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 `..`
15461547
}

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

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

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,21 @@ 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+
498513
ty::Predicate::WellFormed(ty) => {
499514
// WF predicates cannot themselves make
500515
// errors. They can only block due to

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,21 @@ 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+
655670
ty::Predicate::WellFormed(ty) => {
656671
match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
657672
ty, obligation.cause.span) {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ 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(..) |
168169
ty::Predicate::Equate(..) => {
169170
false
170171
}
@@ -207,6 +208,7 @@ fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
207208
ty::Predicate::RegionOutlives(..) |
208209
ty::Predicate::WellFormed(..) |
209210
ty::Predicate::ObjectSafe(..) |
211+
ty::Predicate::ClosureKind(..) |
210212
ty::Predicate::TypeOutlives(..) => {
211213
false
212214
}

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

Lines changed: 31 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,10 @@ 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
202-
/// anonymous types generated for a `||` expression.
203-
ClosureCandidate(/* closure */ DefId, &'tcx ty::ClosureSubsts<'tcx>),
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),
204205

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

322323
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
323324
match self.candidate_from_obligation(&stack)? {
324-
None => {
325-
self.consider_unification_despite_ambiguity(obligation);
326-
Ok(None)
327-
}
325+
None => Ok(None),
328326
Some(candidate) => Ok(Some(self.confirm_candidate(obligation, candidate)?)),
329327
}
330328
}
331329

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-
393330
///////////////////////////////////////////////////////////////////////////
394331
// EVALUATION
395332
//
@@ -532,6 +469,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
532469
}
533470
}
534471
}
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+
}
535487
}
536488
}
537489

@@ -1282,12 +1234,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12821234
Some(closure_kind) => {
12831235
debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
12841236
if closure_kind.extends(kind) {
1285-
candidates.vec.push(ClosureCandidate(closure_def_id, substs));
1237+
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
12861238
}
12871239
}
12881240
None => {
12891241
debug!("assemble_unboxed_candidates: closure_kind not yet known");
1290-
candidates.ambiguous = true;
1242+
candidates.vec.push(ClosureCandidate(closure_def_id, substs, kind));
12911243
}
12921244
}
12931245

@@ -2071,9 +2023,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20712023
Ok(VtableImpl(vtable_impl))
20722024
}
20732025

2074-
ClosureCandidate(closure_def_id, substs) => {
2026+
ClosureCandidate(closure_def_id, substs, kind) => {
20752027
let vtable_closure =
2076-
self.confirm_closure_candidate(obligation, closure_def_id, substs)?;
2028+
self.confirm_closure_candidate(obligation, closure_def_id, substs, kind)?;
20772029
Ok(VtableClosure(vtable_closure))
20782030
}
20792031

@@ -2430,7 +2382,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24302382
fn confirm_closure_candidate(&mut self,
24312383
obligation: &TraitObligation<'tcx>,
24322384
closure_def_id: DefId,
2433-
substs: &ty::ClosureSubsts<'tcx>)
2385+
substs: &ty::ClosureSubsts<'tcx>,
2386+
kind: ty::ClosureKind)
24342387
-> Result<VtableClosureData<'tcx, PredicateObligation<'tcx>>,
24352388
SelectionError<'tcx>>
24362389
{
@@ -2441,7 +2394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
24412394

24422395
let Normalized {
24432396
value: trait_ref,
2444-
obligations
2397+
mut obligations
24452398
} = self.closure_trait_ref(obligation, closure_def_id, substs);
24462399

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

2409+
obligations.push(Obligation::new(
2410+
obligation.cause.clone(),
2411+
ty::Predicate::ClosureKind(closure_def_id, kind)));
2412+
24562413
Ok(VtableClosureData {
24572414
closure_def_id: closure_def_id,
24582415
substs: substs.clone(),

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ 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)
6366
};
6467
self.set.insert(normalized_pred)
6568
}
@@ -156,6 +159,9 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
156159
ty::Predicate::Projection(..) => {
157160
// Nothing to elaborate in a projection predicate.
158161
}
162+
ty::Predicate::ClosureKind(..) => {
163+
// Nothing to elaborate when waiting for a closure's kind to be inferred.
164+
}
159165
ty::Predicate::RegionOutlives(..) |
160166
ty::Predicate::TypeOutlives(..) => {
161167
// Currently, we do not "elaborate" predicates like

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,11 @@ 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),
835840
}
836841

837842
impl<'tcx> Predicate<'tcx> {
@@ -921,6 +926,8 @@ impl<'tcx> Predicate<'tcx> {
921926
Predicate::WellFormed(data.subst(tcx, substs)),
922927
Predicate::ObjectSafe(trait_def_id) =>
923928
Predicate::ObjectSafe(trait_def_id),
929+
Predicate::ClosureKind(closure_def_id, kind) =>
930+
Predicate::ClosureKind(closure_def_id, kind),
924931
}
925932
}
926933
}
@@ -1108,6 +1115,9 @@ impl<'tcx> Predicate<'tcx> {
11081115
ty::Predicate::ObjectSafe(_trait_def_id) => {
11091116
vec![]
11101117
}
1118+
ty::Predicate::ClosureKind(_closure_def_id, _kind) => {
1119+
vec![]
1120+
}
11111121
};
11121122

11131123
// The only reason to collect into a vector here is that I was
@@ -1128,6 +1138,7 @@ impl<'tcx> Predicate<'tcx> {
11281138
Predicate::RegionOutlives(..) |
11291139
Predicate::WellFormed(..) |
11301140
Predicate::ObjectSafe(..) |
1141+
Predicate::ClosureKind(..) |
11311142
Predicate::TypeOutlives(..) => {
11321143
None
11331144
}
@@ -1783,7 +1794,7 @@ pub struct ItemSubsts<'tcx> {
17831794
pub substs: Substs<'tcx>,
17841795
}
17851796

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

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,8 @@ 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),
647649
ty::Predicate::ObjectSafe(trait_def_id) =>
648650
ty::Predicate::ObjectSafe(trait_def_id),
649651
}
@@ -657,6 +659,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
657659
ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
658660
ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
659661
ty::Predicate::WellFormed(data) => data.visit_with(visitor),
662+
ty::Predicate::ClosureKind(_closure_def_id, _kind) => false,
660663
ty::Predicate::ObjectSafe(_trait_def_id) => false,
661664
}
662665
}

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

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

0 commit comments

Comments
 (0)