@@ -8,8 +8,9 @@ use std::iter;
88
99use rustc_data_structures:: fx:: FxIndexSet ;
1010use rustc_errors:: { Applicability , E0806 , struct_span_code_err} ;
11+ use rustc_hir:: attrs:: { AttributeKind , EiiImplResolution } ;
1112use rustc_hir:: def_id:: { DefId , LocalDefId } ;
12- use rustc_hir:: { self as hir, FnSig , HirId , ItemKind } ;
13+ use rustc_hir:: { self as hir, FnSig , HirId , ItemKind , find_attr } ;
1314use rustc_infer:: infer:: { self , InferCtxt , TyCtxtInferExt } ;
1415use rustc_infer:: traits:: { ObligationCause , ObligationCauseCode } ;
1516use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
@@ -169,11 +170,23 @@ fn check_no_generics<'tcx>(
169170 eii_attr_span : Span ,
170171) -> Result < ( ) , ErrorGuaranteed > {
171172 let generics = tcx. generics_of ( external_impl) ;
172- if generics. own_requires_monomorphization ( ) {
173+ if generics. own_requires_monomorphization ( )
174+ // When an EII implementation is automatically generated by the `#[eii]` macro,
175+ // it will directly refer to the foreign item, not through a macro.
176+ // We don't want to emit this error if it's an implementation that's generated by the `#[eii]` macro,
177+ // since in that case it looks like a duplicate error: the declaration of the EII already can't contain generics.
178+ // So, we check here if at least one of the eii impls has ImplResolution::Macro, which indicates it's
179+ // not generated as part of the declaration.
180+ && find_attr ! (
181+ tcx. get_all_attrs( external_impl) ,
182+ AttributeKind :: EiiImpls ( impls) if impls. iter( ) . any( |i| matches!( i. resolution, EiiImplResolution :: Macro ( _) ) )
183+ )
184+ {
173185 tcx. dcx ( ) . emit_err ( EiiWithGenerics {
174186 span : tcx. def_span ( external_impl) ,
175187 attr : eii_attr_span,
176188 eii_name,
189+ impl_name : tcx. item_name ( external_impl) ,
177190 } ) ;
178191 }
179192
0 commit comments