@@ -393,17 +393,22 @@ pub fn render_register_mod(
393393 // * there is a single field that covers the entire register
394394 // * that field can represent all values
395395 // * the write constraints of the register allow full range of values
396- let can_write_safe = ! unsafety (
396+ let safe_ty = if let Safety :: Safe = Safety :: get (
397397 register
398398 . fields
399399 . as_ref ( )
400400 . and_then ( |fields| fields. first ( ) )
401401 . and_then ( |field| field. write_constraint )
402402 . as_ref ( ) ,
403403 rsize,
404- ) || !unsafety ( register. write_constraint . as_ref ( ) , rsize) ;
405- let safe_ty = if can_write_safe { "Safe" } else { "Unsafe" } ;
406- let safe_ty = Ident :: new ( safe_ty, span) ;
404+ ) {
405+ Safety :: Safe
406+ } else if let Safety :: Safe = Safety :: get ( register. write_constraint . as_ref ( ) , rsize) {
407+ Safety :: Safe
408+ } else {
409+ Safety :: Unsafe
410+ } ;
411+ let safe_ty = safe_ty. ident ( span) ;
407412
408413 let doc = format ! ( "`write(|w| ..)` method takes [`{mod_ty}::W`](W) writer structure" , ) ;
409414
@@ -1097,7 +1102,7 @@ pub fn fields(
10971102 // the read value, or else we reuse read value.
10981103 if can_write {
10991104 let mut proxy_items = TokenStream :: new ( ) ;
1100- let mut unsafety = unsafety ( f. write_constraint . as_ref ( ) , width) ;
1105+ let mut safety = Safety :: get ( f. write_constraint . as_ref ( ) , width) ;
11011106
11021107 // if we writes to enumeratedValues, generate its structure if it differs from read structure.
11031108 let value_write_ty = if let Some ( ev) = rwenum. write_enum ( ) {
@@ -1136,12 +1141,12 @@ pub fn fields(
11361141 if variants. len ( ) == 1 << width {
11371142 } else if let Some ( def) = def. take ( ) {
11381143 variants. push ( def) ;
1139- unsafety = false ;
1144+ safety = Safety :: Safe ;
11401145 }
11411146
11421147 // if the write structure is finite, it can be safely written.
11431148 if variants. len ( ) == 1 << width {
1144- unsafety = false ;
1149+ safety = Safety :: Safe ;
11451150 }
11461151
11471152 // generate write value structure and From conversation if we can't reuse read value structure.
@@ -1235,19 +1240,15 @@ pub fn fields(
12351240 quote ! { crate :: #wproxy<' a, REG , #value_write_ty> }
12361241 }
12371242 } else {
1238- let wproxy = Ident :: new (
1239- if unsafety {
1240- "FieldWriter"
1241- } else {
1242- "FieldWriterSafe"
1243- } ,
1244- span,
1245- ) ;
1243+ let wproxy = Ident :: new ( "FieldWriter" , span) ;
12461244 let width = & unsuffixed ( width) ;
1247- if value_write_ty == "u8" {
1245+ if value_write_ty == "u8" && safety != Safety :: Safe {
12481246 quote ! { crate :: #wproxy<' a, REG , #width> }
1249- } else {
1247+ } else if safety != Safety :: Safe {
12501248 quote ! { crate :: #wproxy<' a, REG , #width, #value_write_ty> }
1249+ } else {
1250+ let safe_ty = safety. ident ( span) ;
1251+ quote ! { crate :: #wproxy<' a, REG , #width, #value_write_ty, crate :: #safe_ty> }
12511252 }
12521253 } ;
12531254 mod_items. extend ( quote ! {
@@ -1370,22 +1371,40 @@ pub fn fields(
13701371 ) )
13711372}
13721373
1373- fn unsafety ( write_constraint : Option < & WriteConstraint > , width : u32 ) -> bool {
1374- match & write_constraint {
1375- Some ( & WriteConstraint :: Range ( range) )
1376- if range. min == 0 && range. max == u64:: MAX >> ( 64 - width) =>
1377- {
1378- // the SVD has acknowledged that it's safe to write
1379- // any value that can fit in the field
1380- false
1381- }
1382- None if width == 1 => {
1383- // the field is one bit wide, so we assume it's legal to write
1384- // either value into it or it wouldn't exist; despite that
1385- // if a writeConstraint exists then respect it
1386- false
1374+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
1375+ enum Safety {
1376+ Unsafe ,
1377+ Safe ,
1378+ }
1379+
1380+ impl Safety {
1381+ fn get ( write_constraint : Option < & WriteConstraint > , width : u32 ) -> Self {
1382+ match & write_constraint {
1383+ Some ( & WriteConstraint :: Range ( range) )
1384+ if range. min == 0 && range. max == u64:: MAX >> ( 64 - width) =>
1385+ {
1386+ // the SVD has acknowledged that it's safe to write
1387+ // any value that can fit in the field
1388+ Self :: Safe
1389+ }
1390+ None if width == 1 => {
1391+ // the field is one bit wide, so we assume it's legal to write
1392+ // either value into it or it wouldn't exist; despite that
1393+ // if a writeConstraint exists then respect it
1394+ Self :: Safe
1395+ }
1396+ _ => Self :: Unsafe ,
13871397 }
1388- _ => true ,
1398+ }
1399+ fn ident ( & self , span : Span ) -> Ident {
1400+ Ident :: new (
1401+ if let Self :: Safe = self {
1402+ "Safe"
1403+ } else {
1404+ "Unsafe"
1405+ } ,
1406+ span,
1407+ )
13891408 }
13901409}
13911410
@@ -1425,7 +1444,7 @@ impl Variant {
14251444 span,
14261445 ) ;
14271446 let sc = case. sanitize ( & ev. name ) ;
1428- const INTERNALS : [ & str ; 4 ] = [ "set_bit " , "clear_bit" , "bit " , "bits " ] ;
1447+ const INTERNALS : [ & str ; 6 ] = [ "bit " , "bits" , " clear_bit", "set " , "set_bit" , "variant "] ;
14291448 let sc = Ident :: new (
14301449 & ( if INTERNALS . contains ( & sc. as_ref ( ) ) {
14311450 sc + "_"
@@ -1552,6 +1571,7 @@ fn add_from_variants<'a>(
15521571 impl crate :: FieldSpec for #pc {
15531572 type Ux = #fty;
15541573 }
1574+ impl crate :: IsEnum for #pc { }
15551575 } ) ;
15561576 }
15571577}
0 commit comments