@@ -801,22 +801,50 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
801801 // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
802802 let const_stab = attrs:: find_attr!( attrs, AttributeKind :: ConstStability { stability, ..} => * stability) ;
803803
804+ let unstable_feature_stab =
805+ find_attr ! ( attrs, AttributeKind :: AllowUnstableFeature ( i) => i)
806+ . map ( |i| i. as_slice ( ) )
807+ . unwrap_or_default ( ) ;
808+
804809 // If this impl block has an #[unstable] attribute, give an
805810 // error if all involved types and traits are stable, because
806811 // it will have no effect.
807812 // See: https://github.com/rust-lang/rust/issues/55436
813+ //
814+ // The exception is when there are both #[unstable_feature_bound(..)] and
815+ // #![unstable(feature = "..", issue = "..")] that have the same symbol because
816+ // that can effectively mark an impl as unstable.
817+ //
818+ // For example:
819+ // ```
820+ // #[unstable_feature_bound(feat_foo)]
821+ // #![unstable(feature = "feat_foo", issue = "none")]
822+ // impl Foo for Bar {}
823+ // ```
808824 if let Some ( (
809- Stability { level : attrs:: StabilityLevel :: Unstable { .. } , .. } ,
825+ Stability { level : attrs:: StabilityLevel :: Unstable { .. } , feature } ,
810826 span,
811827 ) ) = stab
812828 {
813829 let mut c = CheckTraitImplStable { tcx : self . tcx , fully_stable : true } ;
814830 c. visit_ty_unambig ( self_ty) ;
815831 c. visit_trait_ref ( t) ;
816832
833+ // Skip the lint if the impl is marked as unstable using
834+ // #[unstable_feature_bound(..)]
835+ let mut unstable_feature_bound_in_effect = false ;
836+ for ( unstable_bound_feat_name, _) in unstable_feature_stab {
837+ if * unstable_bound_feat_name == feature {
838+ unstable_feature_bound_in_effect = true ;
839+ }
840+ }
841+
817842 // do not lint when the trait isn't resolved, since resolution error should
818843 // be fixed first
819- if t. path . res != Res :: Err && c. fully_stable {
844+ if t. path . res != Res :: Err
845+ && c. fully_stable
846+ && !unstable_feature_bound_in_effect
847+ {
820848 self . tcx . emit_node_span_lint (
821849 INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
822850 item. hir_id ( ) ,
0 commit comments