Skip to content

Commit 149f76f

Browse files
committed
---
yaml --- r: 187211 b: refs/heads/try c: 4b09209 h: refs/heads/master i: 187209: c652347 187207: fcbbf45 v: v3
1 parent 07fa70e commit 149f76f

File tree

6 files changed

+240
-21
lines changed

6 files changed

+240
-21
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: b4c965ee803a4521d8b4575f634e036f93e408f3
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 3a96d6a9818fe2affc98a187fb1065120458cee9
5-
refs/heads/try: 58a8103df9077d581a7b17824a7a4b9be695ec5f
5+
refs/heads/try: 4b09209efea1ef7275b34ff3b9d3c4859aa45c8f
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
88
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596

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

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ pub enum Vtable<'tcx, N> {
222222
VtableImpl(VtableImplData<'tcx, N>),
223223

224224
/// Vtable for default trait implementations
225-
VtableDefaultTrait(ast::DefId),
225+
VtableDefaultTrait(VtableDefaultTraitData<N>),
226226

227227
/// Successful resolution to an obligation provided by the caller
228228
/// for some type parameter. The `Vec<N>` represents the
@@ -262,6 +262,12 @@ pub struct VtableImplData<'tcx, N> {
262262
pub nested: subst::VecPerParamSpace<N>
263263
}
264264

265+
#[derive(Debug,Clone)]
266+
pub struct VtableDefaultTraitData<N> {
267+
pub trait_def_id: ast::DefId,
268+
pub nested: subst::VecPerParamSpace<N>
269+
}
270+
265271
#[derive(Debug,Clone)]
266272
pub struct VtableBuiltinData<N> {
267273
pub nested: subst::VecPerParamSpace<N>
@@ -527,7 +533,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
527533
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
528534
match *self {
529535
VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
530-
VtableDefaultTrait(t) => VtableDefaultTrait(t),
536+
VtableDefaultTrait(ref t) => VtableDefaultTrait(t.map_nested(op)),
531537
VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
532538
VtableClosure(d, ref s) => VtableClosure(d, s.clone()),
533539
VtableParam(ref n) => VtableParam(n.iter().map(op).collect()),
@@ -543,7 +549,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
543549
VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
544550
VtableFnPointer(sig) => VtableFnPointer(sig),
545551
VtableClosure(d, s) => VtableClosure(d, s),
546-
VtableDefaultTrait(t) => VtableDefaultTrait(t),
552+
VtableDefaultTrait(t) => VtableDefaultTrait(t.map_move_nested(op)),
547553
VtableParam(n) => VtableParam(n.into_iter().map(op).collect()),
548554
VtableObject(p) => VtableObject(p),
549555
VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
@@ -578,6 +584,31 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
578584
}
579585
}
580586

587+
impl<N> VtableDefaultTraitData<N> {
588+
pub fn iter_nested(&self) -> Iter<N> {
589+
self.nested.iter()
590+
}
591+
592+
pub fn map_nested<M, F>(&self, op: F) -> VtableDefaultTraitData<M> where
593+
F: FnMut(&N) -> M,
594+
{
595+
VtableDefaultTraitData {
596+
trait_def_id: self.trait_def_id,
597+
nested: self.nested.map(op)
598+
}
599+
}
600+
601+
pub fn map_move_nested<M, F>(self, op: F) -> VtableDefaultTraitData<M> where
602+
F: FnMut(N) -> M,
603+
{
604+
let VtableDefaultTraitData { trait_def_id, nested } = self;
605+
VtableDefaultTraitData {
606+
trait_def_id: trait_def_id,
607+
nested: nested.map_move(op)
608+
}
609+
}
610+
}
611+
581612
impl<N> VtableBuiltinData<N> {
582613
pub fn iter_nested(&self) -> Iter<N> {
583614
self.nested.iter()

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

Lines changed: 152 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ use super::{DerivedObligationCause};
2121
use super::{project};
2222
use super::project::Normalized;
2323
use super::{PredicateObligation, TraitObligation, ObligationCause};
24-
use super::{ObligationCauseCode, BuiltinDerivedObligation};
24+
use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
2525
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
2626
use super::{Selection};
2727
use super::{SelectionResult};
2828
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
2929
VtableFnPointer, VtableObject, VtableDefaultTrait};
30-
use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
30+
use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableDefaultTraitData};
3131
use super::object_safety;
3232
use super::{util};
3333

@@ -1535,7 +1535,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15351535
ty::struct_fields(self.tcx(), def_id, substs).iter()
15361536
.map(|f| f.mt.ty)
15371537
.collect();
1538-
nominal(self, bound, def_id, types)
1538+
nominal(bound, types)
15391539
}
15401540

15411541
ty::ty_enum(def_id, substs) => {
@@ -1545,7 +1545,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15451545
.flat_map(|variant| variant.args.iter())
15461546
.cloned()
15471547
.collect();
1548-
nominal(self, bound, def_id, types)
1548+
nominal(bound, types)
15491549
}
15501550

15511551
ty::ty_projection(_) |
@@ -1594,9 +1594,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15941594
}
15951595
};
15961596

1597-
fn nominal<'cx, 'tcx>(this: &mut SelectionContext<'cx, 'tcx>,
1598-
bound: ty::BuiltinBound,
1599-
def_id: ast::DefId,
1597+
fn nominal<'cx, 'tcx>(bound: ty::BuiltinBound,
16001598
types: Vec<Ty<'tcx>>)
16011599
-> Result<BuiltinBoundConditions<'tcx>,SelectionError<'tcx>>
16021600
{
@@ -1615,6 +1613,89 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16151613
}
16161614
}
16171615

1616+
fn constituent_types(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
1617+
match t.sty {
1618+
ty::ty_uint(_) |
1619+
ty::ty_int(_) |
1620+
ty::ty_bool |
1621+
ty::ty_float(_) |
1622+
ty::ty_bare_fn(..) |
1623+
ty::ty_str |
1624+
ty::ty_err |
1625+
ty::ty_char => {
1626+
Vec::new()
1627+
}
1628+
1629+
ty::ty_projection(..) |
1630+
ty::ty_param(..) |
1631+
ty::ty_infer(..) => {
1632+
self.tcx().sess.bug(
1633+
&format!(
1634+
"asked to assemble constituent types of unexpected type: {}",
1635+
t.repr(self.tcx()))[]);
1636+
}
1637+
1638+
ty::ty_uniq(referent_ty) => { // Box<T>
1639+
vec![referent_ty]
1640+
}
1641+
1642+
1643+
ty::ty_trait(ref data) => {
1644+
// Recursively check all supertraits to find out if any further
1645+
// bounds are required and thus we must fulfill.
1646+
let principal =
1647+
data.principal_trait_ref_with_self_ty(self.tcx(),
1648+
self.tcx().types.err);
1649+
1650+
1651+
util::supertraits(self.tcx(), principal).map(|tr| tr.self_ty()).collect()
1652+
}
1653+
1654+
ty::ty_open(element_ty) => {vec![element_ty]},
1655+
1656+
ty::ty_ptr(ty::mt { ty: element_ty, ..}) |
1657+
ty::ty_rptr(_, ty::mt { ty: element_ty, ..}) => {
1658+
vec![element_ty]
1659+
},
1660+
1661+
ty::ty_vec(element_ty, _) => {
1662+
vec![element_ty]
1663+
}
1664+
1665+
ty::ty_tup(ref tys) => {
1666+
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
1667+
tys.clone()
1668+
}
1669+
1670+
ty::ty_closure(def_id, _, substs) => {
1671+
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
1672+
1673+
match self.closure_typer.closure_upvars(def_id, substs) {
1674+
Some(upvars) => {
1675+
upvars.iter().map(|c| c.ty).collect()
1676+
}
1677+
None => {
1678+
Vec::new()
1679+
}
1680+
}
1681+
}
1682+
1683+
ty::ty_struct(def_id, substs) => {
1684+
ty::struct_fields(self.tcx(), def_id, substs).iter()
1685+
.map(|f| f.mt.ty)
1686+
.collect()
1687+
}
1688+
1689+
ty::ty_enum(def_id, substs) => {
1690+
ty::substd_enum_variants(self.tcx(), def_id, substs)
1691+
.iter()
1692+
.flat_map(|variant| variant.args.iter())
1693+
.map(|&ty| ty)
1694+
.collect()
1695+
}
1696+
}
1697+
}
1698+
16181699
///////////////////////////////////////////////////////////////////////////
16191700
// CONFIRMATION
16201701
//
@@ -1648,7 +1729,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16481729
}
16491730

16501731
DefaultTraitCandidate(trait_def_id) => {
1651-
Ok(VtableDefaultTrait(trait_def_id))
1732+
let data = try!(self.confirm_default_impl_candidate(obligation, trait_def_id));
1733+
Ok(VtableDefaultTrait(data))
16521734
}
16531735

16541736
ImplCandidate(impl_def_id) => {
@@ -1783,6 +1865,68 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17831865
VtableBuiltinData { nested: obligations }
17841866
}
17851867

1868+
fn confirm_default_impl_candidate(&mut self,
1869+
obligation: &TraitObligation<'tcx>,
1870+
impl_def_id: ast::DefId)
1871+
-> Result<VtableDefaultTraitData<PredicateObligation<'tcx>>,
1872+
SelectionError<'tcx>>
1873+
{
1874+
debug!("confirm_default_impl_candidate({}, {})",
1875+
obligation.repr(self.tcx()),
1876+
impl_def_id.repr(self.tcx()));
1877+
1878+
let self_ty = self.infcx.shallow_resolve(obligation.predicate.0.self_ty());
1879+
let types = self.constituent_types(self_ty);
1880+
Ok(self.vtable_default_impl(obligation, impl_def_id, types))
1881+
}
1882+
1883+
fn vtable_default_impl(&mut self,
1884+
obligation: &TraitObligation<'tcx>,
1885+
trait_def_id: ast::DefId,
1886+
nested: Vec<Ty<'tcx>>)
1887+
-> VtableDefaultTraitData<PredicateObligation<'tcx>>
1888+
{
1889+
let derived_cause = self.derived_cause(obligation, ImplDerivedObligation);
1890+
let obligations = nested.iter().map(|&nested_ty| {
1891+
// the obligation might be higher-ranked, e.g. for<'a> &'a
1892+
// int : Copy. In that case, we will wind up with
1893+
// late-bound regions in the `nested` vector. So for each
1894+
// one we instantiate to a skolemized region, do our work
1895+
// to produce something like `&'0 int : Copy`, and then
1896+
// re-bind it. This is a bit of busy-work but preserves
1897+
// the invariant that we only manipulate free regions, not
1898+
// bound ones.
1899+
self.infcx.try(|snapshot| {
1900+
let (skol_ty, skol_map) =
1901+
self.infcx().skolemize_late_bound_regions(&ty::Binder(nested_ty), snapshot);
1902+
let skol_predicate =
1903+
util::predicate_for_default_trait_impl(
1904+
self.tcx(),
1905+
derived_cause.clone(),
1906+
trait_def_id,
1907+
obligation.recursion_depth + 1,
1908+
skol_ty);
1909+
match skol_predicate {
1910+
Ok(skol_predicate) => Ok(self.infcx().plug_leaks(skol_map, snapshot,
1911+
&skol_predicate)),
1912+
Err(ErrorReported) => Err(ErrorReported)
1913+
}
1914+
})
1915+
}).collect::<Result<_, _>>();
1916+
let obligations = match obligations {
1917+
Ok(o) => o,
1918+
Err(ErrorReported) => Vec::new()
1919+
};
1920+
1921+
let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
1922+
debug!("vtable_default_impl_data: obligations={}", obligations.repr(self.tcx()));
1923+
1924+
VtableDefaultTraitData {
1925+
trait_def_id: trait_def_id,
1926+
nested: obligations
1927+
}
1928+
}
1929+
17861930
fn confirm_impl_candidate(&mut self,
17871931
obligation: &TraitObligation<'tcx>,
17881932
impl_def_id: ast::DefId)

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

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use util::nodemap::FnvHashSet;
2020
use util::ppaux::Repr;
2121

2222
use super::{Obligation, ObligationCause, PredicateObligation,
23-
VtableImpl, VtableParam, VtableImplData};
23+
VtableImpl, VtableParam, VtableImplData, VtableDefaultTraitData};
2424

2525
struct PredicateSet<'a,'tcx:'a> {
2626
tcx: &'a ty::ctxt<'tcx>,
@@ -323,22 +323,47 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
323323
}
324324
}
325325

326-
pub fn predicate_for_builtin_bound<'tcx>(
326+
pub fn predicate_for_trait_ref<'tcx>(
327327
tcx: &ty::ctxt<'tcx>,
328328
cause: ObligationCause<'tcx>,
329-
builtin_bound: ty::BuiltinBound,
330-
recursion_depth: uint,
331-
param_ty: Ty<'tcx>)
329+
trait_ref: Rc<ty::TraitRef<'tcx>>,
330+
recursion_depth: uint)
332331
-> Result<PredicateObligation<'tcx>, ErrorReported>
333332
{
334-
let trait_ref = try!(trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty));
335333
Ok(Obligation {
336334
cause: cause,
337335
recursion_depth: recursion_depth,
338336
predicate: trait_ref.as_predicate(),
339337
})
340338
}
341339

340+
pub fn predicate_for_default_trait_impl<'tcx>(
341+
tcx: &ty::ctxt<'tcx>,
342+
cause: ObligationCause<'tcx>,
343+
trait_def_id: ast::DefId,
344+
recursion_depth: uint,
345+
param_ty: Ty<'tcx>)
346+
-> Result<PredicateObligation<'tcx>, ErrorReported>
347+
{
348+
let trait_ref = Rc::new(ty::TraitRef {
349+
def_id: trait_def_id,
350+
substs: tcx.mk_substs(Substs::empty().with_self_ty(param_ty))
351+
});
352+
predicate_for_trait_ref(tcx, cause, trait_ref, recursion_depth)
353+
}
354+
355+
pub fn predicate_for_builtin_bound<'tcx>(
356+
tcx: &ty::ctxt<'tcx>,
357+
cause: ObligationCause<'tcx>,
358+
builtin_bound: ty::BuiltinBound,
359+
recursion_depth: uint,
360+
param_ty: Ty<'tcx>)
361+
-> Result<PredicateObligation<'tcx>, ErrorReported>
362+
{
363+
let trait_ref = try!(trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty));
364+
predicate_for_trait_ref(tcx, cause, trait_ref, recursion_depth)
365+
}
366+
342367
/// Cast a trait reference into a reference to one of its super
343368
/// traits; returns `None` if `target_trait_def_id` is not a
344369
/// supertrait.
@@ -445,7 +470,7 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
445470
v.repr(tcx),
446471

447472
super::VtableDefaultTrait(ref t) =>
448-
format!("VtableDefaultTrait({:?})", t),
473+
t.repr(tcx),
449474

450475
super::VtableClosure(ref d, ref s) =>
451476
format!("VtableClosure({},{})",
@@ -486,6 +511,14 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableBuiltinData<N> {
486511
}
487512
}
488513

514+
impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableDefaultTraitData<N> {
515+
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
516+
format!("VtableDefaultTraitData(trait_def_id={}, nested={})",
517+
self.trait_def_id.repr(tcx),
518+
self.nested.repr(tcx))
519+
}
520+
}
521+
489522
impl<'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
490523
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
491524
format!("VtableObject(object_ty={})",

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5175,6 +5175,9 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
51755175
&None => None
51765176
}
51775177
}
5178+
ast::ItemDefTrait(_, ref ast_trait_ref) => {
5179+
Some(ty::node_id_to_trait_ref(cx, ast_trait_ref.ref_id))
5180+
}
51785181
_ => None
51795182
}
51805183
}
@@ -5999,7 +6002,6 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
59996002
/// Records a trait-to-implementation mapping.
60006003
pub fn record_default_trait_implementation(tcx: &ctxt, trait_def_id: DefId) {
60016004

6002-
//assert!(did.krate != ast::LOCAL_CRATE);
60036005
if tcx.default_trait_impls.borrow().contains(&trait_def_id) {
60046006
return;
60056007
}

0 commit comments

Comments
 (0)