@@ -76,7 +76,7 @@ fn check_method_is_structurally_compatible<'tcx>(
76
76
Ok ( ( ) )
77
77
}
78
78
79
- /// This function is best explained by example. Consider a trait with it's implementation:
79
+ /// This function is best explained by example. Consider a trait with its implementation:
80
80
///
81
81
/// ```rust
82
82
/// trait Trait<'t, T> {
@@ -120,7 +120,7 @@ fn check_method_is_structurally_compatible<'tcx>(
120
120
/// types:
121
121
///
122
122
/// ```rust,ignore (pseudo-Rust)
123
- /// <'b> fn(t: &'i0 U0, m: &'b) -> Foo
123
+ /// <'b> fn(t: &'i0 U0, m: &'b N0 ) -> Foo
124
124
/// ```
125
125
///
126
126
/// We now want to extract and substitute the type of the *trait*
@@ -137,7 +137,7 @@ fn check_method_is_structurally_compatible<'tcx>(
137
137
/// Applying this to the trait method type yields:
138
138
///
139
139
/// ```rust,ignore (pseudo-Rust)
140
- /// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
140
+ /// <'a> fn(t: &'i0 U0, m: &'a N0 ) -> Foo
141
141
/// ```
142
142
///
143
143
/// This type is also the same but the name of the bound region (`'a`
@@ -258,8 +258,6 @@ fn compare_method_predicate_entailment<'tcx>(
258
258
// type.
259
259
260
260
// Compute placeholder form of impl and trait method tys.
261
- let tcx = infcx. tcx ;
262
-
263
261
let mut wf_tys = FxIndexSet :: default ( ) ;
264
262
265
263
let unnormalized_impl_sig = infcx. instantiate_binder_with_fresh_vars (
@@ -1668,19 +1666,19 @@ fn compare_synthetic_generics<'tcx>(
1668
1666
/// ```rust,ignore (pseudo-Rust)
1669
1667
/// trait Foo {
1670
1668
/// fn foo<const N: u8>();
1671
- /// type bar <const N: u8>;
1669
+ /// type Bar <const N: u8>;
1672
1670
/// fn baz<const N: u32>();
1673
- /// type blah <T>;
1671
+ /// type Blah <T>;
1674
1672
/// }
1675
1673
///
1676
1674
/// impl Foo for () {
1677
1675
/// fn foo<const N: u64>() {}
1678
1676
/// //~^ error
1679
- /// type bar <const N: u64> {}
1677
+ /// type Bar <const N: u64> = ();
1680
1678
/// //~^ error
1681
1679
/// fn baz<T>() {}
1682
1680
/// //~^ error
1683
- /// type blah <const N: i64> = u32;
1681
+ /// type Blah <const N: i64> = u32;
1684
1682
/// //~^ error
1685
1683
/// }
1686
1684
/// ```
@@ -1769,36 +1767,82 @@ pub(super) fn compare_impl_const_raw(
1769
1767
let trait_const_item = tcx. associated_item ( trait_const_item_def) ;
1770
1768
let impl_trait_ref =
1771
1769
tcx. impl_trait_ref ( impl_const_item. container_id ( tcx) ) . unwrap ( ) . instantiate_identity ( ) ;
1772
- debug ! ( "compare_const_impl(impl_trait_ref={:?})" , impl_trait_ref) ;
1773
1770
1774
- let impl_c_span = tcx . def_span ( impl_const_item_def . to_def_id ( ) ) ;
1771
+ debug ! ( "compare_impl_const(impl_trait_ref={:?})" , impl_trait_ref ) ;
1775
1772
1776
- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
1777
- let param_env = tcx. param_env ( impl_const_item_def. to_def_id ( ) ) ;
1778
- let ocx = ObligationCtxt :: new ( & infcx) ;
1773
+ compare_number_of_generics ( tcx, impl_const_item, trait_const_item, false ) ?;
1774
+ compare_generic_param_kinds ( tcx, impl_const_item, trait_const_item, false ) ?;
1775
+ compare_const_predicate_entailment ( tcx, impl_const_item, trait_const_item, impl_trait_ref)
1776
+ }
1777
+
1778
+ /// The equivalent of [compare_method_predicate_entailment], but for associated constants
1779
+ /// instead of associated functions.
1780
+ // FIXME(generic_const_items): If possible extract the common parts of `compare_{type,const}_predicate_entailment`.
1781
+ fn compare_const_predicate_entailment < ' tcx > (
1782
+ tcx : TyCtxt < ' tcx > ,
1783
+ impl_ct : ty:: AssocItem ,
1784
+ trait_ct : ty:: AssocItem ,
1785
+ impl_trait_ref : ty:: TraitRef < ' tcx > ,
1786
+ ) -> Result < ( ) , ErrorGuaranteed > {
1787
+ let impl_ct_def_id = impl_ct. def_id . expect_local ( ) ;
1788
+ let impl_ct_span = tcx. def_span ( impl_ct_def_id) ;
1779
1789
1780
1790
// The below is for the most part highly similar to the procedure
1781
1791
// for methods above. It is simpler in many respects, especially
1782
1792
// because we shouldn't really have to deal with lifetimes or
1783
1793
// predicates. In fact some of this should probably be put into
1784
1794
// shared functions because of DRY violations...
1785
- let trait_to_impl_args = impl_trait_ref. args ;
1795
+ let impl_args = GenericArgs :: identity_for_item ( tcx, impl_ct. def_id ) ;
1796
+ let trait_to_impl_args =
1797
+ impl_args. rebase_onto ( tcx, impl_ct. container_id ( tcx) , impl_trait_ref. args ) ;
1786
1798
1787
1799
// Create a parameter environment that represents the implementation's
1788
1800
// method.
1789
1801
// Compute placeholder form of impl and trait const tys.
1790
- let impl_ty = tcx. type_of ( impl_const_item_def. to_def_id ( ) ) . instantiate_identity ( ) ;
1791
- let trait_ty = tcx. type_of ( trait_const_item_def) . instantiate ( tcx, trait_to_impl_args) ;
1792
- let mut cause = ObligationCause :: new (
1793
- impl_c_span,
1794
- impl_const_item_def,
1795
- ObligationCauseCode :: CompareImplItemObligation {
1796
- impl_item_def_id : impl_const_item_def,
1797
- trait_item_def_id : trait_const_item_def,
1798
- kind : impl_const_item. kind ,
1799
- } ,
1802
+ let impl_ty = tcx. type_of ( impl_ct_def_id) . instantiate_identity ( ) ;
1803
+
1804
+ let trait_ty = tcx. type_of ( trait_ct. def_id ) . instantiate ( tcx, trait_to_impl_args) ;
1805
+ let code = ObligationCauseCode :: CompareImplItemObligation {
1806
+ impl_item_def_id : impl_ct_def_id,
1807
+ trait_item_def_id : trait_ct. def_id ,
1808
+ kind : impl_ct. kind ,
1809
+ } ;
1810
+ let mut cause = ObligationCause :: new ( impl_ct_span, impl_ct_def_id, code. clone ( ) ) ;
1811
+
1812
+ let impl_ct_predicates = tcx. predicates_of ( impl_ct. def_id ) ;
1813
+ let trait_ct_predicates = tcx. predicates_of ( trait_ct. def_id ) ;
1814
+
1815
+ check_region_bounds_on_impl_item ( tcx, impl_ct, trait_ct, false ) ?;
1816
+
1817
+ // The predicates declared by the impl definition, the trait and the
1818
+ // associated const in the trait are assumed.
1819
+ let impl_predicates = tcx. predicates_of ( impl_ct_predicates. parent . unwrap ( ) ) ;
1820
+ let mut hybrid_preds = impl_predicates. instantiate_identity ( tcx) ;
1821
+ hybrid_preds. predicates . extend (
1822
+ trait_ct_predicates
1823
+ . instantiate_own ( tcx, trait_to_impl_args)
1824
+ . map ( |( predicate, _) | predicate) ,
1825
+ ) ;
1826
+
1827
+ let param_env = ty:: ParamEnv :: new ( tcx. mk_clauses ( & hybrid_preds. predicates ) , Reveal :: UserFacing ) ;
1828
+ let param_env = traits:: normalize_param_env_or_error (
1829
+ tcx,
1830
+ param_env,
1831
+ ObligationCause :: misc ( impl_ct_span, impl_ct_def_id) ,
1800
1832
) ;
1801
1833
1834
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
1835
+ let ocx = ObligationCtxt :: new ( & infcx) ;
1836
+
1837
+ let impl_ct_own_bounds = impl_ct_predicates. instantiate_own ( tcx, impl_args) ;
1838
+ for ( predicate, span) in impl_ct_own_bounds {
1839
+ let cause = ObligationCause :: misc ( span, impl_ct_def_id) ;
1840
+ let predicate = ocx. normalize ( & cause, param_env, predicate) ;
1841
+
1842
+ let cause = ObligationCause :: new ( span, impl_ct_def_id, code. clone ( ) ) ;
1843
+ ocx. register_obligation ( traits:: Obligation :: new ( tcx, cause, param_env, predicate) ) ;
1844
+ }
1845
+
1802
1846
// There is no "body" here, so just pass dummy id.
1803
1847
let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1804
1848
@@ -1817,20 +1861,20 @@ pub(super) fn compare_impl_const_raw(
1817
1861
) ;
1818
1862
1819
1863
// Locate the Span containing just the type of the offending impl
1820
- let ( ty, _) = tcx. hir ( ) . expect_impl_item ( impl_const_item_def ) . expect_const ( ) ;
1864
+ let ( ty, _) = tcx. hir ( ) . expect_impl_item ( impl_ct_def_id ) . expect_const ( ) ;
1821
1865
cause. span = ty. span ;
1822
1866
1823
1867
let mut diag = struct_span_err ! (
1824
1868
tcx. sess,
1825
1869
cause. span,
1826
1870
E0326 ,
1827
1871
"implemented const `{}` has an incompatible type for trait" ,
1828
- trait_const_item . name
1872
+ trait_ct . name
1829
1873
) ;
1830
1874
1831
- let trait_c_span = trait_const_item_def . as_local ( ) . map ( |trait_c_def_id | {
1875
+ let trait_c_span = trait_ct . def_id . as_local ( ) . map ( |trait_ct_def_id | {
1832
1876
// Add a label to the Span containing just the type of the const
1833
- let ( ty, _) = tcx. hir ( ) . expect_trait_item ( trait_c_def_id ) . expect_const ( ) ;
1877
+ let ( ty, _) = tcx. hir ( ) . expect_trait_item ( trait_ct_def_id ) . expect_const ( ) ;
1834
1878
ty. span
1835
1879
} ) ;
1836
1880
@@ -1857,7 +1901,7 @@ pub(super) fn compare_impl_const_raw(
1857
1901
}
1858
1902
1859
1903
let outlives_env = OutlivesEnvironment :: new ( param_env) ;
1860
- ocx. resolve_regions_and_report_errors ( impl_const_item_def , & outlives_env)
1904
+ ocx. resolve_regions_and_report_errors ( impl_ct_def_id , & outlives_env)
1861
1905
}
1862
1906
1863
1907
pub ( super ) fn compare_impl_ty < ' tcx > (
@@ -1899,7 +1943,7 @@ fn compare_type_predicate_entailment<'tcx>(
1899
1943
return Ok ( ( ) ) ;
1900
1944
}
1901
1945
1902
- // This `HirId ` should be used for the `body_id` field on each
1946
+ // This `DefId ` should be used for the `body_id` field on each
1903
1947
// `ObligationCause` (and the `FnCtxt`). This is what
1904
1948
// `regionck_item` expects.
1905
1949
let impl_ty_def_id = impl_ty. def_id . expect_local ( ) ;
@@ -1918,7 +1962,7 @@ fn compare_type_predicate_entailment<'tcx>(
1918
1962
debug ! ( "compare_type_predicate_entailment: bounds={:?}" , hybrid_preds) ;
1919
1963
1920
1964
let impl_ty_span = tcx. def_span ( impl_ty_def_id) ;
1921
- let normalize_cause = traits :: ObligationCause :: misc ( impl_ty_span, impl_ty_def_id) ;
1965
+ let normalize_cause = ObligationCause :: misc ( impl_ty_span, impl_ty_def_id) ;
1922
1966
let param_env = ty:: ParamEnv :: new ( tcx. mk_clauses ( & hybrid_preds. predicates ) , Reveal :: UserFacing ) ;
1923
1967
let param_env = traits:: normalize_param_env_or_error ( tcx, param_env, normalize_cause) ;
1924
1968
let infcx = tcx. infer_ctxt ( ) . build ( ) ;
@@ -1963,7 +2007,7 @@ fn compare_type_predicate_entailment<'tcx>(
1963
2007
///
1964
2008
/// trait X { type Y: Copy } impl X for T { type Y = S; }
1965
2009
///
1966
- /// We are able to normalize `<T as X>::U ` to `S`, and so when we check the
2010
+ /// We are able to normalize `<T as X>::Y ` to `S`, and so when we check the
1967
2011
/// impl is well-formed we have to prove `S: Copy`.
1968
2012
///
1969
2013
/// For default associated types the normalization is not possible (the value
0 commit comments