Skip to content

Commit a0ec4f5

Browse files
committed
Fix const-ness progatation through typedefs
Possible after d78b047.
1 parent 2a69b8f commit a0ec4f5

File tree

2 files changed

+30
-37
lines changed

2 files changed

+30
-37
lines changed

crates/header-translator/src/rust_type.rs

+29-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::str::FromStr;
22
use std::sync::LazyLock;
3-
use std::{fmt, iter};
3+
use std::{fmt, iter, mem};
44

55
use clang::{CallingConvention, Entity, EntityKind, Nullability, Type, TypeKind};
66
use proc_macro2::{TokenStream, TokenTree};
@@ -1184,10 +1184,10 @@ impl Ty {
11841184
typedef_name,
11851185
declaration.get_name().expect("typedef declaration name")
11861186
);
1187-
let to = declaration
1187+
let inner = declaration
11881188
.get_typedef_underlying_type()
11891189
.expect("typedef underlying type");
1190-
let _span = debug_span!("typedef", ?typedef_name, ?declaration, ?to).entered();
1190+
let _span = debug_span!("typedef", ?typedef_name, ?declaration, ?inner).entered();
11911191

11921192
let mut parser = AttributeParser::new(&attributed_name, &typedef_name);
11931193
let mut _is_kindof = parser.is_kindof(ParsePosition::Prefix);
@@ -1196,7 +1196,7 @@ impl Ty {
11961196

11971197
let is_const2 = parser.is_const(ParsePosition::Suffix);
11981198
lifetime.update(parser.lifetime(ParsePosition::Suffix));
1199-
let mut nullability = if let Some(nullability) = unexposed_nullability {
1199+
let nullability = if let Some(nullability) = unexposed_nullability {
12001200
nullability
12011201
} else {
12021202
check_nullability(&attributed_ty, parser.nullability(ParsePosition::Suffix))
@@ -1367,7 +1367,7 @@ impl Ty {
13671367
};
13681368
}
13691369

1370-
let to = Self::parse(to, Lifetime::Unspecified, context);
1370+
let mut inner = Self::parse(inner, Lifetime::Unspecified, context);
13711371

13721372
let id = ItemIdentifier::new(&declaration, context);
13731373

@@ -1397,22 +1397,24 @@ impl Ty {
13971397
// parameter.
13981398
if let Self::Pointer {
13991399
nullability: inner_nullability,
1400-
is_const: _,
1400+
is_const: inner_is_const,
14011401
lifetime: inner_lifetime,
14021402
pointee,
1403-
} = &to
1403+
} = &mut inner
14041404
{
14051405
// The outermost attribute, i.e. the one on the typedef,
14061406
// is the one that matters.
1407-
if nullability == Nullability::Unspecified {
1408-
nullability = *inner_nullability;
1407+
//
1408+
// We intentionally mutate the Pointer's data, such that
1409+
// this works regardless of what we do further down below.
1410+
if nullability != Nullability::Unspecified {
1411+
*inner_nullability = nullability;
14091412
}
1410-
// TODO
1411-
// if !is_const {
1412-
// is_const = *inner_is_const;
1413-
// }
1414-
if lifetime == Lifetime::Unspecified {
1415-
lifetime = *inner_lifetime;
1413+
if is_const {
1414+
*inner_is_const = is_const;
1415+
}
1416+
if lifetime != Lifetime::Unspecified {
1417+
*inner_lifetime = lifetime;
14161418
}
14171419

14181420
if pointee.is_direct_cf_type(&id.name, is_bridged(&declaration, context)) {
@@ -1421,25 +1423,16 @@ impl Ty {
14211423
// type is a CF type or not... But that's how it is
14221424
// currently.
14231425
let id = context.replace_typedef_name(id, true);
1424-
return Self::Pointer {
1425-
nullability,
1426-
is_const,
1427-
lifetime,
1428-
pointee: Box::new(Self::Pointee(PointeeTy::CFTypeDef { id })),
1429-
};
1430-
}
1431-
1432-
// Only do this when visiting object-like typedefs.
1433-
if pointee.is_object_like() || pointee.is_cf_type() {
1434-
if let Self::Pointee(pointee_ty) = &**pointee {
1426+
*pointee = Box::new(Self::Pointee(PointeeTy::CFTypeDef { id }));
1427+
return inner;
1428+
} else if pointee.is_object_like() || pointee.is_cf_type() {
1429+
if let Self::Pointee(pointee_ty) = &mut **pointee {
14351430
let id = context.replace_typedef_name(id, pointee_ty.is_cf_type());
1436-
let to = Box::new(pointee_ty.clone());
1437-
return Self::Pointer {
1438-
nullability,
1439-
is_const,
1440-
lifetime,
1441-
pointee: Box::new(Self::Pointee(PointeeTy::TypeDef { id, to })),
1442-
};
1431+
// Replace with a dummy type (will be re-replaced
1432+
// on the line below).
1433+
let to = Box::new(mem::replace(pointee_ty, PointeeTy::Self_));
1434+
*pointee = Box::new(Self::Pointee(PointeeTy::TypeDef { id, to }));
1435+
return inner;
14431436
} else {
14441437
error!(?pointee, "is_object_like/is_cf_type but not Pointee");
14451438
}
@@ -1455,7 +1448,7 @@ impl Ty {
14551448

14561449
Self::TypeDef {
14571450
id,
1458-
to: Box::new(to),
1451+
to: Box::new(inner),
14591452
}
14601453
}
14611454
// Assume that functions without a prototype simply have 0 arguments.
@@ -1945,8 +1938,8 @@ impl Ty {
19451938
Self::Pointer {
19461939
nullability: Nullability::Nullable,
19471940
lifetime: Lifetime::Unspecified,
1948-
is_const: false,
19491941
pointee,
1942+
..
19501943
} if pointee.is_static_object() => {
19511944
// NULL -> error
19521945
write!(
@@ -1959,8 +1952,8 @@ impl Ty {
19591952
Self::Pointer {
19601953
nullability: Nullability::Nullable,
19611954
lifetime: Lifetime::Unspecified,
1962-
is_const: false,
19631955
pointee,
1956+
..
19641957
} if pointee.is_object_like() || pointee.is_cf_type() => {
19651958
// NULL -> error
19661959
write!(

generated

Submodule generated updated 80 files

0 commit comments

Comments
 (0)