Skip to content

Commit c602c27

Browse files
committed
---
yaml --- r: 273139 b: refs/heads/beta c: 1f34086 h: refs/heads/master i: 273137: 3362c7c 273135: d67c8f6
1 parent 78a52f6 commit c602c27

File tree

18 files changed

+255
-220
lines changed

18 files changed

+255
-220
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: c5849e4dff28784ec0c3d5ace090b1da9439ec1f
26+
refs/heads/beta: 1f34086e947139d498847dce49ba437748f17c2d
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/librustc/dep_graph/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ could invalidate work done for other items. So, for example:
5151
not shared state, because if it changes it does not itself
5252
invalidate other functions (though it may be that it causes new
5353
monomorphizations to occur, but that's handled independently).
54-
54+
5555
Put another way: if the HIR for an item changes, we are going to
5656
recompile that item for sure. But we need the dep tracking map to tell
5757
us what *else* we have to recompile. Shared state is anything that is
@@ -177,7 +177,7 @@ reads from `item`, there would be missing edges in the graph:
177177
| ^
178178
| |
179179
+---------------------------------+ // added by `visit_all_items_in_krate`
180-
180+
181181
In particular, the edge from `Hir(X)` to `ItemSignature(X)` is only
182182
present because we called `read` ourselves when entering the `ItemSignature(X)`
183183
task.
@@ -273,8 +273,8 @@ should not exist. In contrast, using the memoized helper, you get:
273273
... -> MapVariant(key) -> A
274274
|
275275
+----------> B
276-
277-
which is much cleaner.
276+
277+
which is much cleaner.
278278

279279
**Be aware though that the closure is executed with `MapVariant(key)`
280280
pushed onto the stack as the current task!** That means that you must
@@ -387,4 +387,3 @@ RUST_DEP_GRAPH_FILTER='Hir&foo -> TypeckItemBody & bar'
387387
This will dump out all the nodes that lead from `Hir(foo)` to
388388
`TypeckItemBody(bar)`, from which you can (hopefully) see the source
389389
of the erroneous edge.
390-

branches/beta/src/librustc/middle/cstore.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ pub trait CrateStore<'tcx> : Any {
176176
-> Option<ty::adjustment::CustomCoerceUnsized>;
177177
fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
178178
-> Vec<Rc<ty::AssociatedConst<'tcx>>>;
179+
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
179180

180181
// trait/impl-item info
181182
fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
@@ -346,6 +347,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
346347
{ unimplemented!() }
347348
fn associated_consts(&self, tcx: &TyCtxt<'tcx>, def: DefId)
348349
-> Vec<Rc<ty::AssociatedConst<'tcx>>> { unimplemented!() }
350+
fn impl_parent(&self, def: DefId) -> Option<DefId> { unimplemented!() }
349351

350352
// trait/impl-item info
351353
fn trait_of_item(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)

branches/beta/src/librustc/middle/traits/coherence.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ use syntax::codemap::DUMMY_SP;
2323
#[derive(Copy, Clone)]
2424
struct InferIsLocal(bool);
2525

26-
/// If there are types that satisfy both impls, returns an `ImplTy`
27-
/// with those types substituted (by updating the given `infcx`)
26+
/// If there are types that satisfy both impls, returns a suitably-freshened
27+
/// `ImplHeader` with those types substituted
2828
pub fn overlapping_impls<'cx, 'tcx>(infcx: &InferCtxt<'cx, 'tcx>,
2929
impl1_def_id: DefId,
3030
impl2_def_id: DefId)
@@ -85,7 +85,10 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
8585
return None
8686
}
8787

88-
Some(selcx.infcx().resolve_type_vars_if_possible(&a_impl_header))
88+
let substituted = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
89+
let freshened = selcx.infcx().freshen(substituted);
90+
91+
Some(freshened)
8992
}
9093

9194
pub fn trait_ref_is_knowable<'tcx>(tcx: &TyCtxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> bool

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub use self::select::SelectionContext;
5050
pub use self::select::SelectionCache;
5151
pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
5252
pub use self::select::{MethodMatchedData}; // intentionally don't export variants
53+
pub use self::specialize::{Overlap, SpecializationGraph, specializes};
5354
pub use self::util::elaborate_predicates;
5455
pub use self::util::get_vtable_index_of_object_method;
5556
pub use self::util::trait_ref_for_builtin_bound;
@@ -67,6 +68,7 @@ mod fulfill;
6768
mod project;
6869
mod object_safety;
6970
mod select;
71+
mod specialize;
7072
mod structural_impls;
7173
mod util;
7274

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

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use middle::infer;
4040
use middle::infer::{InferCtxt, TypeFreshener, TypeOrigin};
4141
use middle::subst::{Subst, Substs, TypeSpace};
4242
use middle::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
43+
use middle::traits;
4344
use middle::ty::fast_reject;
4445
use middle::ty::relate::TypeRelation;
4546

@@ -224,6 +225,12 @@ struct SelectionCandidateSet<'tcx> {
224225
ambiguous: bool,
225226
}
226227

228+
#[derive(PartialEq,Eq,Debug,Clone)]
229+
struct EvaluatedCandidate<'tcx> {
230+
candidate: SelectionCandidate<'tcx>,
231+
evaluation: EvaluationResult,
232+
}
233+
227234
enum BuiltinBoundConditions<'tcx> {
228235
If(ty::Binder<Vec<Ty<'tcx>>>),
229236
ParameterBuiltin,
@@ -746,6 +753,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
746753
candidate
747754
}
748755

756+
// Treat negative impls as unimplemented
757+
fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>)
758+
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
759+
if let ImplCandidate(def_id) = candidate {
760+
if self.tcx().trait_impl_polarity(def_id) == Some(hir::ImplPolarity::Negative) {
761+
return Err(Unimplemented)
762+
}
763+
}
764+
Ok(Some(candidate))
765+
}
766+
749767
fn candidate_from_obligation_no_cache<'o>(&mut self,
750768
stack: &TraitObligationStack<'o, 'tcx>)
751769
-> SelectionResult<'tcx, SelectionCandidate<'tcx>>
@@ -803,12 +821,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
803821
// we were to winnow, we'd wind up with zero candidates.
804822
// Instead, we select the right impl now but report `Bar does
805823
// not implement Clone`.
806-
if candidates.len() > 1 {
807-
candidates.retain(|c| self.evaluate_candidate(stack, c).may_apply())
808-
}
824+
if candidates.len() == 1 {
825+
return self.filter_negative_impls(candidates.pop().unwrap());
826+
}
827+
828+
// Winnow, but record the exact outcome of evaluation, which
829+
// is needed for specialization.
830+
let mut candidates: Vec<_> = candidates.into_iter().filter_map(|c| {
831+
let eval = self.evaluate_candidate(stack, &c);
832+
if eval.may_apply() {
833+
Some(EvaluatedCandidate {
834+
candidate: c,
835+
evaluation: eval,
836+
})
837+
} else {
838+
None
839+
}
840+
}).collect();
809841

810-
// If there are STILL multiple candidate, we can further reduce
811-
// the list by dropping duplicates.
842+
// If there are STILL multiple candidate, we can further
843+
// reduce the list by dropping duplicates -- including
844+
// resolving specializations.
812845
if candidates.len() > 1 {
813846
let mut i = 0;
814847
while i < candidates.len() {
@@ -850,19 +883,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
850883
}
851884

852885
// Just one candidate left.
853-
let candidate = candidates.pop().unwrap();
854-
855-
match candidate {
856-
ImplCandidate(def_id) => {
857-
match self.tcx().trait_impl_polarity(def_id) {
858-
Some(hir::ImplPolarity::Negative) => return Err(Unimplemented),
859-
_ => {}
860-
}
861-
}
862-
_ => {}
863-
}
864-
865-
Ok(Some(candidate))
886+
self.filter_negative_impls(candidates.pop().unwrap().candidate)
866887
}
867888

868889
fn is_knowable<'o>(&mut self,
@@ -1564,41 +1585,55 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15641585
/// candidates and prefer where-clause candidates.
15651586
///
15661587
/// See the comment for "SelectionCandidate" for more details.
1567-
fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
1568-
victim: &SelectionCandidate<'tcx>,
1569-
other: &SelectionCandidate<'tcx>)
1570-
-> bool
1588+
fn candidate_should_be_dropped_in_favor_of<'o>(
1589+
&mut self,
1590+
victim: &EvaluatedCandidate<'tcx>,
1591+
other: &EvaluatedCandidate<'tcx>)
1592+
-> bool
15711593
{
1572-
if victim == other {
1594+
if victim.candidate == other.candidate {
15731595
return true;
15741596
}
15751597

1576-
match other {
1577-
&ObjectCandidate |
1578-
&ParamCandidate(_) | &ProjectionCandidate => match victim {
1579-
&DefaultImplCandidate(..) => {
1598+
match other.candidate {
1599+
ObjectCandidate |
1600+
ParamCandidate(_) | ProjectionCandidate => match victim.candidate {
1601+
DefaultImplCandidate(..) => {
15801602
self.tcx().sess.bug(
15811603
"default implementations shouldn't be recorded \
15821604
when there are other valid candidates");
15831605
}
1584-
&ImplCandidate(..) |
1585-
&ClosureCandidate(..) |
1586-
&FnPointerCandidate |
1587-
&BuiltinObjectCandidate |
1588-
&BuiltinUnsizeCandidate |
1589-
&DefaultImplObjectCandidate(..) |
1590-
&BuiltinCandidate(..) => {
1606+
ImplCandidate(..) |
1607+
ClosureCandidate(..) |
1608+
FnPointerCandidate |
1609+
BuiltinObjectCandidate |
1610+
BuiltinUnsizeCandidate |
1611+
DefaultImplObjectCandidate(..) |
1612+
BuiltinCandidate(..) => {
15911613
// We have a where-clause so don't go around looking
15921614
// for impls.
15931615
true
15941616
}
1595-
&ObjectCandidate |
1596-
&ProjectionCandidate => {
1617+
ObjectCandidate |
1618+
ProjectionCandidate => {
15971619
// Arbitrarily give param candidates priority
15981620
// over projection and object candidates.
15991621
true
16001622
},
1601-
&ParamCandidate(..) => false,
1623+
ParamCandidate(..) => false,
1624+
ErrorCandidate => false // propagate errors
1625+
},
1626+
ImplCandidate(other_def) => {
1627+
// See if we can toss out `victim` based on specialization.
1628+
// This requires us to know *for sure* that the `other` impl applies
1629+
// i.e. EvaluatedToOk:
1630+
if other.evaluation == EvaluatedToOk {
1631+
if let ImplCandidate(victim_def) = victim.candidate {
1632+
return traits::specializes(self.infcx(), other_def, victim_def);
1633+
}
1634+
}
1635+
1636+
false
16021637
},
16031638
_ => false
16041639
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
381381
}
382382
}
383383

384-
385384
pub fn predicate_for_trait_ref<'tcx>(
386385
cause: ObligationCause<'tcx>,
387386
trait_ref: ty::TraitRef<'tcx>,

branches/beta/src/librustc/middle/ty/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2456,8 +2456,13 @@ impl<'tcx> TyCtxt<'tcx> {
24562456
for impl_def_id in self.sess.cstore.implementations_of_trait(trait_id) {
24572457
let impl_items = self.sess.cstore.impl_items(impl_def_id);
24582458
let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
2459+
24592460
// Record the trait->implementation mapping.
2460-
def.record_impl(self, impl_def_id, trait_ref);
2461+
if let Some(parent) = self.sess.cstore.impl_parent(impl_def_id) {
2462+
def.record_remote_impl(self, impl_def_id, trait_ref, parent);
2463+
} else {
2464+
def.record_remote_impl(self, impl_def_id, trait_ref, trait_id);
2465+
}
24612466

24622467
// For any methods that use a default implementation, add them to
24632468
// the map. This is a bit unfortunate.

branches/beta/src/librustc/middle/ty/sty.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,13 @@ impl<'tcx> TyS<'tcx> {
11061106
}
11071107
}
11081108

1109+
pub fn has_concrete_skeleton(&self) -> bool {
1110+
match self.sty {
1111+
TyParam(_) | TyInfer(_) | TyError => false,
1112+
_ => true,
1113+
}
1114+
}
1115+
11091116
// Returns the type and mutability of *ty.
11101117
//
11111118
// The parameter `explicit` indicates if this is an *explicit* dereference.

0 commit comments

Comments
 (0)