@@ -393,17 +393,22 @@ pub fn render_register_mod(
393
393
// * there is a single field that covers the entire register
394
394
// * that field can represent all values
395
395
// * 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 (
397
397
register
398
398
. fields
399
399
. as_ref ( )
400
400
. and_then ( |fields| fields. first ( ) )
401
401
. and_then ( |field| field. write_constraint )
402
402
. as_ref ( ) ,
403
403
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) ;
407
412
408
413
let doc = format ! ( "`write(|w| ..)` method takes [`{mod_ty}::W`](W) writer structure" , ) ;
409
414
@@ -1097,7 +1102,7 @@ pub fn fields(
1097
1102
// the read value, or else we reuse read value.
1098
1103
if can_write {
1099
1104
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) ;
1101
1106
1102
1107
// if we writes to enumeratedValues, generate its structure if it differs from read structure.
1103
1108
let value_write_ty = if let Some ( ev) = rwenum. write_enum ( ) {
@@ -1136,12 +1141,12 @@ pub fn fields(
1136
1141
if variants. len ( ) == 1 << width {
1137
1142
} else if let Some ( def) = def. take ( ) {
1138
1143
variants. push ( def) ;
1139
- unsafety = false ;
1144
+ safety = Safety :: Safe ;
1140
1145
}
1141
1146
1142
1147
// if the write structure is finite, it can be safely written.
1143
1148
if variants. len ( ) == 1 << width {
1144
- unsafety = false ;
1149
+ safety = Safety :: Safe ;
1145
1150
}
1146
1151
1147
1152
// generate write value structure and From conversation if we can't reuse read value structure.
@@ -1235,19 +1240,15 @@ pub fn fields(
1235
1240
quote ! { crate :: #wproxy<' a, REG , #value_write_ty> }
1236
1241
}
1237
1242
} 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) ;
1246
1244
let width = & unsuffixed ( width) ;
1247
- if value_write_ty == "u8" {
1245
+ if value_write_ty == "u8" && safety != Safety :: Safe {
1248
1246
quote ! { crate :: #wproxy<' a, REG , #width> }
1249
- } else {
1247
+ } else if safety != Safety :: Safe {
1250
1248
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> }
1251
1252
}
1252
1253
} ;
1253
1254
mod_items. extend ( quote ! {
@@ -1370,22 +1371,40 @@ pub fn fields(
1370
1371
) )
1371
1372
}
1372
1373
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 ,
1387
1397
}
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
+ )
1389
1408
}
1390
1409
}
1391
1410
@@ -1425,7 +1444,7 @@ impl Variant {
1425
1444
span,
1426
1445
) ;
1427
1446
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 "] ;
1429
1448
let sc = Ident :: new (
1430
1449
& ( if INTERNALS . contains ( & sc. as_ref ( ) ) {
1431
1450
sc + "_"
@@ -1552,6 +1571,7 @@ fn add_from_variants<'a>(
1552
1571
impl crate :: FieldSpec for #pc {
1553
1572
type Ux = #fty;
1554
1573
}
1574
+ impl crate :: IsEnum for #pc { }
1555
1575
} ) ;
1556
1576
}
1557
1577
}
0 commit comments