@@ -21,13 +21,13 @@ use super::{DerivedObligationCause};
21
21
use super :: { project} ;
22
22
use super :: project:: Normalized ;
23
23
use super :: { PredicateObligation , TraitObligation , ObligationCause } ;
24
- use super :: { ObligationCauseCode , BuiltinDerivedObligation } ;
24
+ use super :: { ObligationCauseCode , BuiltinDerivedObligation , ImplDerivedObligation } ;
25
25
use super :: { SelectionError , Unimplemented , Overflow , OutputTypeParameterMismatch } ;
26
26
use super :: { Selection } ;
27
27
use super :: { SelectionResult } ;
28
28
use super :: { VtableBuiltin , VtableImpl , VtableParam , VtableClosure ,
29
29
VtableFnPointer , VtableObject , VtableDefaultTrait } ;
30
- use super :: { VtableImplData , VtableObjectData , VtableBuiltinData } ;
30
+ use super :: { VtableImplData , VtableObjectData , VtableBuiltinData , VtableDefaultTraitData } ;
31
31
use super :: object_safety;
32
32
use super :: { util} ;
33
33
@@ -1535,7 +1535,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1535
1535
ty:: struct_fields ( self . tcx ( ) , def_id, substs) . iter ( )
1536
1536
. map ( |f| f. mt . ty )
1537
1537
. collect ( ) ;
1538
- nominal ( self , bound, def_id , types)
1538
+ nominal ( bound, types)
1539
1539
}
1540
1540
1541
1541
ty:: ty_enum( def_id, substs) => {
@@ -1545,7 +1545,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1545
1545
. flat_map ( |variant| variant. args . iter ( ) )
1546
1546
. cloned ( )
1547
1547
. collect ( ) ;
1548
- nominal ( self , bound, def_id , types)
1548
+ nominal ( bound, types)
1549
1549
}
1550
1550
1551
1551
ty:: ty_projection( _) |
@@ -1594,9 +1594,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1594
1594
}
1595
1595
} ;
1596
1596
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 ,
1600
1598
types : Vec < Ty < ' tcx > > )
1601
1599
-> Result < BuiltinBoundConditions < ' tcx > , SelectionError < ' tcx > >
1602
1600
{
@@ -1615,6 +1613,89 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1615
1613
}
1616
1614
}
1617
1615
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
+
1618
1699
///////////////////////////////////////////////////////////////////////////
1619
1700
// CONFIRMATION
1620
1701
//
@@ -1648,7 +1729,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1648
1729
}
1649
1730
1650
1731
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) )
1652
1734
}
1653
1735
1654
1736
ImplCandidate ( impl_def_id) => {
@@ -1783,6 +1865,68 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1783
1865
VtableBuiltinData { nested : obligations }
1784
1866
}
1785
1867
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
+
1786
1930
fn confirm_impl_candidate ( & mut self ,
1787
1931
obligation : & TraitObligation < ' tcx > ,
1788
1932
impl_def_id : ast:: DefId )
0 commit comments