@@ -1716,6 +1716,60 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1716
1716
}
1717
1717
}
1718
1718
1719
+ fn collect_predicates_for_types ( & mut self ,
1720
+ obligation : & TraitObligation < ' tcx > ,
1721
+ trait_def_id : ast:: DefId ,
1722
+ types : Vec < Ty < ' tcx > > ) -> Vec < PredicateObligation < ' tcx > > {
1723
+
1724
+ let derived_cause = match self . tcx ( ) . lang_items . to_builtin_kind ( trait_def_id) {
1725
+ Some ( _) => {
1726
+ self . derived_cause ( obligation, BuiltinDerivedObligation )
1727
+ } ,
1728
+ None => {
1729
+ self . derived_cause ( obligation, ImplDerivedObligation )
1730
+ }
1731
+ } ;
1732
+
1733
+ let normalized = project:: normalize_with_depth ( self , obligation. cause . clone ( ) ,
1734
+ obligation. recursion_depth + 1 ,
1735
+ & types) ;
1736
+
1737
+ let obligations = normalized. value . iter ( ) . map ( |& nested_ty| {
1738
+ // the obligation might be higher-ranked, e.g. for<'a> &'a
1739
+ // int : Copy. In that case, we will wind up with
1740
+ // late-bound regions in the `nested` vector. So for each
1741
+ // one we instantiate to a skolemized region, do our work
1742
+ // to produce something like `&'0 int : Copy`, and then
1743
+ // re-bind it. This is a bit of busy-work but preserves
1744
+ // the invariant that we only manipulate free regions, not
1745
+ // bound ones.
1746
+ self . infcx . try ( |snapshot| {
1747
+ let ( skol_ty, skol_map) =
1748
+ self . infcx ( ) . skolemize_late_bound_regions ( & ty:: Binder ( nested_ty) , snapshot) ;
1749
+ let skol_predicate =
1750
+ util:: predicate_for_trait_def (
1751
+ self . tcx ( ) ,
1752
+ derived_cause. clone ( ) ,
1753
+ trait_def_id,
1754
+ obligation. recursion_depth + 1 ,
1755
+ skol_ty) ;
1756
+ match skol_predicate {
1757
+ Ok ( skol_predicate) => Ok ( self . infcx ( ) . plug_leaks ( skol_map, snapshot,
1758
+ & skol_predicate) ) ,
1759
+ Err ( ErrorReported ) => Err ( ErrorReported )
1760
+ }
1761
+ } )
1762
+ } ) . collect :: < Result < Vec < PredicateObligation < ' tcx > > , _ > > ( ) ;
1763
+
1764
+ match obligations {
1765
+ Ok ( mut obls) => {
1766
+ obls. push_all ( normalized. obligations . as_slice ( ) ) ;
1767
+ obls
1768
+ } ,
1769
+ Err ( ErrorReported ) => Vec :: new ( )
1770
+ }
1771
+ }
1772
+
1719
1773
///////////////////////////////////////////////////////////////////////////
1720
1774
// CONFIRMATION
1721
1775
//
@@ -1854,38 +1908,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1854
1908
nested : Vec < Ty < ' tcx > > )
1855
1909
-> VtableBuiltinData < PredicateObligation < ' tcx > >
1856
1910
{
1857
- let derived_cause = self . derived_cause ( obligation, BuiltinDerivedObligation ) ;
1858
- let obligations = nested. iter ( ) . map ( |& bound_ty| {
1859
- // the obligation might be higher-ranked, e.g. for<'a> &'a
1860
- // int : Copy. In that case, we will wind up with
1861
- // late-bound regions in the `nested` vector. So for each
1862
- // one we instantiate to a skolemized region, do our work
1863
- // to produce something like `&'0 int : Copy`, and then
1864
- // re-bind it. This is a bit of busy-work but preserves
1865
- // the invariant that we only manipulate free regions, not
1866
- // bound ones.
1867
- self . infcx . try ( |snapshot| {
1868
- let ( skol_ty, skol_map) =
1869
- self . infcx ( ) . skolemize_late_bound_regions ( & ty:: Binder ( bound_ty) , snapshot) ;
1870
- let skol_predicate =
1871
- util:: predicate_for_builtin_bound (
1872
- self . tcx ( ) ,
1873
- derived_cause. clone ( ) ,
1874
- bound,
1875
- obligation. recursion_depth + 1 ,
1876
- skol_ty) ;
1877
- match skol_predicate {
1878
- Ok ( skol_predicate) => Ok ( self . infcx ( ) . plug_leaks ( skol_map, snapshot,
1879
- & skol_predicate) ) ,
1880
- Err ( ErrorReported ) => Err ( ErrorReported )
1881
- }
1882
- } )
1883
- } ) . collect :: < Result < _ , _ > > ( ) ;
1884
- let obligations = match obligations {
1885
- Ok ( o) => o,
1886
- Err ( ErrorReported ) => Vec :: new ( ) ,
1911
+ let trait_def = match self . tcx ( ) . lang_items . from_builtin_kind ( bound) {
1912
+ Ok ( def_id) => def_id,
1913
+ Err ( _) => {
1914
+ self . tcx ( ) . sess . bug ( "builtin trait definition not found" ) ;
1915
+ }
1887
1916
} ;
1888
1917
1918
+ let obligations = self . collect_predicates_for_types ( obligation, trait_def, nested) ;
1919
+
1889
1920
let obligations = VecPerParamSpace :: new ( obligations, Vec :: new ( ) , Vec :: new ( ) ) ;
1890
1921
1891
1922
debug ! ( "vtable_builtin_data: obligations={}" ,
@@ -1928,39 +1959,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1928
1959
nested : Vec < Ty < ' tcx > > )
1929
1960
-> VtableDefaultImplData < PredicateObligation < ' tcx > >
1930
1961
{
1931
- let derived_cause = self . derived_cause ( obligation, ImplDerivedObligation ) ;
1932
1962
1933
- let obligations = nested. iter ( ) . map ( |& nested_ty| {
1934
- // the obligation might be higher-ranked, e.g. for<'a> &'a
1935
- // int : Copy. In that case, we will wind up with
1936
- // late-bound regions in the `nested` vector. So for each
1937
- // one we instantiate to a skolemized region, do our work
1938
- // to produce something like `&'0 int : Copy`, and then
1939
- // re-bind it. This is a bit of busy-work but preserves
1940
- // the invariant that we only manipulate free regions, not
1941
- // bound ones.
1942
- self . infcx . try ( |snapshot| {
1943
- let ( skol_ty, skol_map) =
1944
- self . infcx ( ) . skolemize_late_bound_regions ( & ty:: Binder ( nested_ty) , snapshot) ;
1945
- let skol_predicate =
1946
- util:: predicate_for_default_trait_impl (
1947
- self . tcx ( ) ,
1948
- derived_cause. clone ( ) ,
1949
- trait_def_id,
1950
- obligation. recursion_depth + 1 ,
1951
- skol_ty) ;
1952
- match skol_predicate {
1953
- Ok ( skol_predicate) => Ok ( self . infcx ( ) . plug_leaks ( skol_map, snapshot,
1954
- & skol_predicate) ) ,
1955
- Err ( ErrorReported ) => Err ( ErrorReported )
1956
- }
1957
- } )
1958
- } ) . collect :: < Result < _ , _ > > ( ) ;
1959
-
1960
- let mut obligations = match obligations {
1961
- Ok ( o) => o,
1962
- Err ( ErrorReported ) => Vec :: new ( )
1963
- } ;
1963
+ let mut obligations = self . collect_predicates_for_types ( obligation,
1964
+ trait_def_id,
1965
+ nested) ;
1964
1966
1965
1967
let _: Result < ( ) , ( ) > = self . infcx . try ( |snapshot| {
1966
1968
let ( _, skol_map) =
0 commit comments