@@ -76,7 +76,7 @@ fn check_method_is_structurally_compatible<'tcx>(
7676 Ok ( ( ) )
7777}
7878
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:
8080///
8181/// ```rust
8282/// trait Trait<'t, T> {
@@ -120,7 +120,7 @@ fn check_method_is_structurally_compatible<'tcx>(
120120/// types:
121121///
122122/// ```rust,ignore (pseudo-Rust)
123- /// <'b> fn(t: &'i0 U0, m: &'b) -> Foo
123+ /// <'b> fn(t: &'i0 U0, m: &'b N0 ) -> Foo
124124/// ```
125125///
126126/// We now want to extract and substitute the type of the *trait*
@@ -137,7 +137,7 @@ fn check_method_is_structurally_compatible<'tcx>(
137137/// Applying this to the trait method type yields:
138138///
139139/// ```rust,ignore (pseudo-Rust)
140- /// <'a> fn(t: &'i0 U0, m: &'a) -> Foo
140+ /// <'a> fn(t: &'i0 U0, m: &'a N0 ) -> Foo
141141/// ```
142142///
143143/// This type is also the same but the name of the bound region (`'a`
@@ -258,8 +258,6 @@ fn compare_method_predicate_entailment<'tcx>(
258258 // type.
259259
260260 // Compute placeholder form of impl and trait method tys.
261- let tcx = infcx. tcx ;
262-
263261 let mut wf_tys = FxIndexSet :: default ( ) ;
264262
265263 let unnormalized_impl_sig = infcx. instantiate_binder_with_fresh_vars (
@@ -1668,19 +1666,19 @@ fn compare_synthetic_generics<'tcx>(
16681666/// ```rust,ignore (pseudo-Rust)
16691667/// trait Foo {
16701668/// fn foo<const N: u8>();
1671- /// type bar <const N: u8>;
1669+ /// type Bar <const N: u8>;
16721670/// fn baz<const N: u32>();
1673- /// type blah <T>;
1671+ /// type Blah <T>;
16741672/// }
16751673///
16761674/// impl Foo for () {
16771675/// fn foo<const N: u64>() {}
16781676/// //~^ error
1679- /// type bar <const N: u64> {}
1677+ /// type Bar <const N: u64> = ();
16801678/// //~^ error
16811679/// fn baz<T>() {}
16821680/// //~^ error
1683- /// type blah <const N: i64> = u32;
1681+ /// type Blah <const N: i64> = u32;
16841682/// //~^ error
16851683/// }
16861684/// ```
@@ -1769,36 +1767,82 @@ pub(super) fn compare_impl_const_raw(
17691767 let trait_const_item = tcx. associated_item ( trait_const_item_def) ;
17701768 let impl_trait_ref =
17711769 tcx. impl_trait_ref ( impl_const_item. container_id ( tcx) ) . unwrap ( ) . instantiate_identity ( ) ;
1772- debug ! ( "compare_const_impl(impl_trait_ref={:?})" , impl_trait_ref) ;
17731770
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 ) ;
17751772
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) ;
17791789
17801790 // The below is for the most part highly similar to the procedure
17811791 // for methods above. It is simpler in many respects, especially
17821792 // because we shouldn't really have to deal with lifetimes or
17831793 // predicates. In fact some of this should probably be put into
17841794 // 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 ) ;
17861798
17871799 // Create a parameter environment that represents the implementation's
17881800 // method.
17891801 // 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) ,
18001832 ) ;
18011833
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+
18021846 // There is no "body" here, so just pass dummy id.
18031847 let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
18041848
@@ -1817,20 +1861,20 @@ pub(super) fn compare_impl_const_raw(
18171861 ) ;
18181862
18191863 // 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 ( ) ;
18211865 cause. span = ty. span ;
18221866
18231867 let mut diag = struct_span_err ! (
18241868 tcx. sess,
18251869 cause. span,
18261870 E0326 ,
18271871 "implemented const `{}` has an incompatible type for trait" ,
1828- trait_const_item . name
1872+ trait_ct . name
18291873 ) ;
18301874
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 | {
18321876 // 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 ( ) ;
18341878 ty. span
18351879 } ) ;
18361880
@@ -1857,7 +1901,7 @@ pub(super) fn compare_impl_const_raw(
18571901 }
18581902
18591903 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)
18611905}
18621906
18631907pub ( super ) fn compare_impl_ty < ' tcx > (
@@ -1899,7 +1943,7 @@ fn compare_type_predicate_entailment<'tcx>(
18991943 return Ok ( ( ) ) ;
19001944 }
19011945
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
19031947 // `ObligationCause` (and the `FnCtxt`). This is what
19041948 // `regionck_item` expects.
19051949 let impl_ty_def_id = impl_ty. def_id . expect_local ( ) ;
@@ -1918,7 +1962,7 @@ fn compare_type_predicate_entailment<'tcx>(
19181962 debug ! ( "compare_type_predicate_entailment: bounds={:?}" , hybrid_preds) ;
19191963
19201964 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) ;
19221966 let param_env = ty:: ParamEnv :: new ( tcx. mk_clauses ( & hybrid_preds. predicates ) , Reveal :: UserFacing ) ;
19231967 let param_env = traits:: normalize_param_env_or_error ( tcx, param_env, normalize_cause) ;
19241968 let infcx = tcx. infer_ctxt ( ) . build ( ) ;
@@ -1963,7 +2007,7 @@ fn compare_type_predicate_entailment<'tcx>(
19632007///
19642008/// trait X { type Y: Copy } impl X for T { type Y = S; }
19652009///
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
19672011/// impl is well-formed we have to prove `S: Copy`.
19682012///
19692013/// For default associated types the normalization is not possible (the value
0 commit comments