@@ -58,6 +58,7 @@ use rustc_hir::def_id::DefId;
5858use rustc_hir:: intravisit:: Visitor ;
5959use rustc_hir:: lang_items:: LangItem ;
6060use rustc_hir:: { self as hir} ;
61+ use rustc_infer:: infer:: DefineOpaqueTypes ;
6162use rustc_macros:: extension;
6263use rustc_middle:: bug;
6364use rustc_middle:: dep_graph:: DepContext ;
@@ -72,12 +73,17 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym};
7273use tracing:: { debug, instrument} ;
7374
7475use crate :: error_reporting:: TypeErrCtxt ;
76+ use crate :: error_reporting:: traits:: ambiguity:: {
77+ CandidateSource , compute_applicable_impls_for_diagnostics,
78+ } ;
7579use crate :: errors:: { ObligationCauseFailureCode , TypeErrorAdditionalDiags } ;
7680use crate :: infer;
7781use crate :: infer:: relate:: { self , RelateResult , TypeRelation } ;
7882use crate :: infer:: { InferCtxt , InferCtxtExt as _, TypeTrace , ValuePairs } ;
7983use crate :: solve:: deeply_normalize_for_diagnostics;
80- use crate :: traits:: { MatchExpressionArmCause , ObligationCause , ObligationCauseCode } ;
84+ use crate :: traits:: {
85+ MatchExpressionArmCause , Obligation , ObligationCause , ObligationCauseCode , specialization_graph,
86+ } ;
8187
8288mod note_and_explain;
8389mod suggest;
@@ -149,11 +155,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
149155 actual : Ty < ' tcx > ,
150156 err : TypeError < ' tcx > ,
151157 ) -> Diag < ' a > {
152- self . report_and_explain_type_error (
158+ let mut diag = self . report_and_explain_type_error (
153159 TypeTrace :: types ( cause, expected, actual) ,
154160 param_env,
155161 err,
156- )
162+ ) ;
163+
164+ self . suggest_param_env_shadowing ( & mut diag, expected, actual, param_env) ;
165+
166+ diag
157167 }
158168
159169 pub fn report_mismatched_consts (
@@ -240,6 +250,76 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
240250 false
241251 }
242252
253+ fn suggest_param_env_shadowing (
254+ & self ,
255+ diag : & mut Diag < ' _ > ,
256+ expected : Ty < ' tcx > ,
257+ found : Ty < ' tcx > ,
258+ param_env : ty:: ParamEnv < ' tcx > ,
259+ ) {
260+ let ( alias, concrete) = match ( expected. kind ( ) , found. kind ( ) ) {
261+ ( ty:: Alias ( ty:: Projection , proj) , _) => ( proj, found) ,
262+ ( _, ty:: Alias ( ty:: Projection , proj) ) => ( proj, expected) ,
263+ _ => return ,
264+ } ;
265+
266+ let tcx = self . tcx ;
267+
268+ let trait_ref = alias. trait_ref ( tcx) ;
269+ let obligation =
270+ Obligation :: new ( tcx, ObligationCause :: dummy ( ) , param_env, ty:: Binder :: dummy ( trait_ref) ) ;
271+
272+ let applicable_impls = compute_applicable_impls_for_diagnostics ( self . infcx , & obligation) ;
273+
274+ for candidate in applicable_impls {
275+ let impl_def_id = match candidate {
276+ CandidateSource :: DefId ( did) => did,
277+ CandidateSource :: ParamEnv ( _) => continue ,
278+ } ;
279+
280+ let is_shadowed = self . infcx . probe ( |_| {
281+ let impl_substs = self . infcx . fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
282+ let impl_trait_ref = tcx. impl_trait_ref ( impl_def_id) . instantiate ( tcx, impl_substs) ;
283+
284+ let expected_trait_ref = alias. trait_ref ( tcx) ;
285+
286+ if let Err ( _) = self . infcx . at ( & ObligationCause :: dummy ( ) , param_env) . eq (
287+ DefineOpaqueTypes :: No ,
288+ expected_trait_ref,
289+ impl_trait_ref,
290+ ) {
291+ return false ;
292+ }
293+
294+ let leaf_def = match specialization_graph:: assoc_def ( tcx, impl_def_id, alias. def_id )
295+ {
296+ Ok ( leaf) => leaf,
297+ Err ( _) => return false ,
298+ } ;
299+
300+ let trait_def_id = alias. trait_def_id ( tcx) ;
301+ let rebased_args = alias. args . rebase_onto ( tcx, trait_def_id, impl_substs) ;
302+
303+ let impl_item_def_id = leaf_def. item . def_id ;
304+ let impl_assoc_ty = tcx. type_of ( impl_item_def_id) . instantiate ( tcx, rebased_args) ;
305+
306+ self . infcx . can_eq ( param_env, impl_assoc_ty, concrete)
307+ } ) ;
308+
309+ if is_shadowed {
310+ diag. note ( format ! (
311+ "the associated type `{}` is defined as `{}` in the implementation, \
312+ but the where-bound `{}` shadows this definition\n \
313+ see issue #152409 <https://github.com/rust-lang/rust/issues/152409> for more information",
314+ self . ty_to_string( tcx. mk_ty_from_kind( ty:: Alias ( ty:: Projection , * alias) ) ) ,
315+ self . ty_to_string( concrete) ,
316+ self . ty_to_string( alias. self_ty( ) )
317+ ) ) ;
318+ return ;
319+ }
320+ }
321+ }
322+
243323 fn note_error_origin (
244324 & self ,
245325 err : & mut Diag < ' _ > ,
0 commit comments