@@ -181,9 +181,11 @@ use std::{iter, vec};
181181pub ( crate ) use StaticFields :: * ;
182182pub ( crate ) use SubstructureFields :: * ;
183183use rustc_ast:: ptr:: P ;
184+ use rustc_ast:: token:: { IdentIsRaw , LitKind , Token , TokenKind } ;
185+ use rustc_ast:: tokenstream:: { DelimSpan , Spacing , TokenTree } ;
184186use rustc_ast:: {
185- self as ast, AnonConst , BindingMode , ByRef , EnumDef , Expr , GenericArg , GenericParamKind ,
186- Generics , Mutability , PatKind , VariantData ,
187+ self as ast, AnonConst , AttrArgs , BindingMode , ByRef , DelimArgs , EnumDef , Expr , GenericArg ,
188+ GenericParamKind , Generics , Mutability , PatKind , Safety , VariantData ,
187189} ;
188190use rustc_attr_data_structures:: { AttributeKind , ReprPacked } ;
189191use rustc_attr_parsing:: AttributeParser ;
@@ -222,6 +224,8 @@ pub(crate) struct TraitDef<'a> {
222224 pub associated_types : Vec < ( Ident , Ty ) > ,
223225
224226 pub is_const : bool ,
227+
228+ pub is_staged_api_crate : bool ,
225229}
226230
227231pub ( crate ) struct MethodDef < ' a > {
@@ -784,8 +788,45 @@ impl<'a> TraitDef<'a> {
784788 // Create the type of `self`.
785789 let path = cx. path_all ( self . span , false , vec ! [ type_ident] , self_params) ;
786790 let self_type = cx. ty_path ( path) ;
791+ let rustc_const_unstable =
792+ cx. path_ident ( self . span , Ident :: new ( sym:: rustc_const_unstable, self . span ) ) ;
793+
794+ let mut attrs = thin_vec ! [ cx. attr_word( sym:: automatically_derived, self . span) , ] ;
795+
796+ // Only add `rustc_const_unstable` attributes if `derive_const` is used within libcore/libstd,
797+ // Other crates don't need stability attributes, so adding them is not useful, but libcore needs them
798+ // on all const trait impls.
799+ if self . is_const && self . is_staged_api_crate {
800+ attrs. push (
801+ cx. attr_nested (
802+ rustc_ast:: AttrItem {
803+ unsafety : Safety :: Default ,
804+ path : rustc_const_unstable,
805+ args : AttrArgs :: Delimited ( DelimArgs {
806+ dspan : DelimSpan :: from_single ( self . span ) ,
807+ delim : rustc_ast:: token:: Delimiter :: Parenthesis ,
808+ tokens : [
809+ TokenKind :: Ident ( sym:: feature, IdentIsRaw :: No ) ,
810+ TokenKind :: Eq ,
811+ TokenKind :: lit ( LitKind :: Str , sym:: derive_const, None ) ,
812+ TokenKind :: Comma ,
813+ TokenKind :: Ident ( sym:: issue, IdentIsRaw :: No ) ,
814+ TokenKind :: Eq ,
815+ TokenKind :: lit ( LitKind :: Str , sym:: derive_const_issue, None ) ,
816+ ]
817+ . into_iter ( )
818+ . map ( |kind| {
819+ TokenTree :: Token ( Token { kind, span : self . span } , Spacing :: Alone )
820+ } )
821+ . collect ( ) ,
822+ } ) ,
823+ tokens : None ,
824+ } ,
825+ self . span ,
826+ ) ,
827+ )
828+ }
787829
788- let attrs = thin_vec ! [ cx. attr_word( sym:: automatically_derived, self . span) , ] ;
789830 let opt_trait_ref = Some ( trait_ref) ;
790831
791832 cx. item (
0 commit comments