@@ -802,22 +802,50 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
802
802
// FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
803
803
let const_stab = attrs:: find_attr!( attrs, AttributeKind :: ConstStability { stability, ..} => * stability) ;
804
804
805
+ let unstable_feature_stab =
806
+ find_attr ! ( attrs, AttributeKind :: UnstableFeatureBound ( i) => i)
807
+ . map ( |i| i. as_slice ( ) )
808
+ . unwrap_or_default ( ) ;
809
+
805
810
// If this impl block has an #[unstable] attribute, give an
806
811
// error if all involved types and traits are stable, because
807
812
// it will have no effect.
808
813
// 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
+ // ```
809
825
if let Some ( (
810
- Stability { level : attrs:: StabilityLevel :: Unstable { .. } , .. } ,
826
+ Stability { level : attrs:: StabilityLevel :: Unstable { .. } , feature } ,
811
827
span,
812
828
) ) = stab
813
829
{
814
830
let mut c = CheckTraitImplStable { tcx : self . tcx , fully_stable : true } ;
815
831
c. visit_ty_unambig ( self_ty) ;
816
832
c. visit_trait_ref ( t) ;
817
833
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
+
818
843
// do not lint when the trait isn't resolved, since resolution error should
819
844
// 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
+ {
821
849
self . tcx . emit_node_span_lint (
822
850
INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
823
851
item. hir_id ( ) ,
0 commit comments