@@ -3,11 +3,12 @@ use ast::ptr::P;
33use rustc_ast:: mut_visit:: MutVisitor ;
44use rustc_ast:: visit:: BoundKind ;
55use rustc_ast:: {
6- self as ast, GenericArg , GenericBound , GenericParamKind , ItemKind , MetaItem ,
6+ self as ast, GenericArg , GenericBound , GenericParamKind , Generics , ItemKind , MetaItem ,
77 TraitBoundModifiers , VariantData , WherePredicate ,
88} ;
99use rustc_attr_parsing as attr;
1010use rustc_data_structures:: flat_map_in_place:: FlatMapInPlace ;
11+ use rustc_errors:: E0802 ;
1112use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
1213use rustc_macros:: Diagnostic ;
1314use rustc_span:: { Ident , Span , Symbol , sym} ;
@@ -88,8 +89,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
8889 } else {
8990 let mut pointees = type_params
9091 . iter ( )
91- . filter_map ( |& ( idx, span, is_pointee) | is_pointee. then_some ( ( idx, span) ) )
92- . fuse ( ) ;
92+ . filter_map ( |& ( idx, span, is_pointee) | is_pointee. then_some ( ( idx, span) ) ) ;
9393 match ( pointees. next ( ) , pointees. next ( ) ) {
9494 ( Some ( ( idx, _span) ) , None ) => idx,
9595 ( None , _) => {
@@ -110,6 +110,52 @@ pub(crate) fn expand_deriving_coerce_pointee(
110110 // Declare helper function that adds implementation blocks.
111111 // FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
112112 let attrs = thin_vec ! [ cx. attr_word( sym:: automatically_derived, span) , ] ;
113+ // # Wellformed-ness assertion
114+ {
115+ let trait_path =
116+ cx. path_all ( span, true , path ! ( span, core:: marker:: CoercePointeeWellformed ) , vec ! [ ] ) ;
117+ let trait_ref = cx. trait_ref ( trait_path) ;
118+ push ( Annotatable :: Item (
119+ cx. item (
120+ span,
121+ Ident :: empty ( ) ,
122+ attrs. clone ( ) ,
123+ ast:: ItemKind :: Impl ( Box :: new ( ast:: Impl {
124+ safety : ast:: Safety :: Default ,
125+ polarity : ast:: ImplPolarity :: Positive ,
126+ defaultness : ast:: Defaultness :: Final ,
127+ constness : ast:: Const :: No ,
128+ generics : Generics {
129+ params : generics
130+ . params
131+ . iter ( )
132+ . map ( |p| match & p. kind {
133+ GenericParamKind :: Lifetime => {
134+ cx. lifetime_param ( p. span ( ) , p. ident , p. bounds . clone ( ) )
135+ }
136+ GenericParamKind :: Type { default : _ } => {
137+ cx. typaram ( p. span ( ) , p. ident , p. bounds . clone ( ) , None )
138+ }
139+ GenericParamKind :: Const { ty, kw_span : _, default : _ } => cx
140+ . const_param (
141+ p. span ( ) ,
142+ p. ident ,
143+ p. bounds . clone ( ) ,
144+ ty. clone ( ) ,
145+ None ,
146+ ) ,
147+ } )
148+ . collect ( ) ,
149+ where_clause : generics. where_clause . clone ( ) ,
150+ span : generics. span ,
151+ } ,
152+ of_trait : Some ( trait_ref) ,
153+ self_ty : self_type. clone ( ) ,
154+ items : ThinVec :: new ( ) ,
155+ } ) ) ,
156+ ) ,
157+ ) ) ;
158+ }
113159 let mut add_impl_block = |generics, trait_symbol, trait_args| {
114160 let mut parts = path ! ( span, core:: ops) ;
115161 parts. push ( Ident :: new ( trait_symbol, span) ) ;
@@ -430,35 +476,35 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b>
430476}
431477
432478#[ derive( Diagnostic ) ]
433- #[ diag( builtin_macros_coerce_pointee_requires_transparent) ]
479+ #[ diag( builtin_macros_coerce_pointee_requires_transparent, code = E0802 ) ]
434480struct RequireTransparent {
435481 #[ primary_span]
436482 span : Span ,
437483}
438484
439485#[ derive( Diagnostic ) ]
440- #[ diag( builtin_macros_coerce_pointee_requires_one_field) ]
486+ #[ diag( builtin_macros_coerce_pointee_requires_one_field, code = E0802 ) ]
441487struct RequireOneField {
442488 #[ primary_span]
443489 span : Span ,
444490}
445491
446492#[ derive( Diagnostic ) ]
447- #[ diag( builtin_macros_coerce_pointee_requires_one_generic) ]
493+ #[ diag( builtin_macros_coerce_pointee_requires_one_generic, code = E0802 ) ]
448494struct RequireOneGeneric {
449495 #[ primary_span]
450496 span : Span ,
451497}
452498
453499#[ derive( Diagnostic ) ]
454- #[ diag( builtin_macros_coerce_pointee_requires_one_pointee) ]
500+ #[ diag( builtin_macros_coerce_pointee_requires_one_pointee, code = E0802 ) ]
455501struct RequireOnePointee {
456502 #[ primary_span]
457503 span : Span ,
458504}
459505
460506#[ derive( Diagnostic ) ]
461- #[ diag( builtin_macros_coerce_pointee_too_many_pointees) ]
507+ #[ diag( builtin_macros_coerce_pointee_too_many_pointees, code = E0802 ) ]
462508struct TooManyPointees {
463509 #[ primary_span]
464510 one : Span ,
@@ -467,7 +513,7 @@ struct TooManyPointees {
467513}
468514
469515#[ derive( Diagnostic ) ]
470- #[ diag( builtin_macros_coerce_pointee_requires_maybe_sized) ]
516+ #[ diag( builtin_macros_coerce_pointee_requires_maybe_sized, code = E0802 ) ]
471517struct RequiresMaybeSized {
472518 #[ primary_span]
473519 span : Span ,
0 commit comments