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