Skip to content

Commit aa4f3fd

Browse files
committed
Parse NS_NOESCAPE
1 parent da6484e commit aa4f3fd

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

crates/header-translator/src/id.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ impl ItemIdentifier {
119119
self.library == "Foundation" && self.name == "NSString"
120120
}
121121

122+
pub fn is_nscomparator(&self) -> bool {
123+
self.library == "Foundation" && self.name == "NSComparator"
124+
}
125+
122126
pub fn feature(&self) -> Option<impl fmt::Display + '_> {
123127
struct ItemIdentifierFeature<'a>(&'a ItemIdentifier);
124128

crates/header-translator/src/method.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ impl<'tu> PartialMethod<'tu> {
401401
.get_objc_qualifiers()
402402
.map(MethodArgumentQualifier::parse);
403403
let mut sendable = None;
404+
let mut no_escape = false;
404405

405406
immediate_children(&entity, |entity, _span| match entity.get_kind() {
406407
EntityKind::ObjCClassRef
@@ -417,6 +418,7 @@ impl<'tu> PartialMethod<'tu> {
417418
match attr {
418419
UnexposedAttr::Sendable => sendable = Some(true),
419420
UnexposedAttr::NonSendable => sendable = Some(false),
421+
UnexposedAttr::NoEscape => no_escape = true,
420422
attr => error!(?attr, "unknown attribute"),
421423
}
422424
}
@@ -427,7 +429,7 @@ impl<'tu> PartialMethod<'tu> {
427429
});
428430

429431
let ty = entity.get_type().expect("argument type");
430-
let ty = Ty::parse_method_argument(ty, qualifier, sendable, context);
432+
let ty = Ty::parse_method_argument(ty, qualifier, sendable, no_escape, context);
431433

432434
(name, ty)
433435
})

crates/header-translator/src/rust_type.rs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,13 @@ enum Inner {
501501
},
502502
Fn {
503503
is_variadic: bool,
504+
no_escape: bool,
504505
arguments: Vec<Inner>,
505506
result_type: Box<Inner>,
506507
},
507508
Block {
509+
sendable: Option<bool>,
510+
no_escape: bool,
508511
arguments: Vec<Inner>,
509512
result_type: Box<Inner>,
510513
},
@@ -546,7 +549,7 @@ impl Inner {
546549

547550
match attr {
548551
Some(UnexposedAttr::NonIsolated | UnexposedAttr::UIActor) => {
549-
// Ignored for now; these are almost always also emitted on the method/property,
552+
// Ignored for now; these are usually also emitted on the method/property,
550553
// which is where they will be useful in any case.
551554
}
552555
Some(attr) => error!(?attr, "unknown attribute"),
@@ -681,12 +684,15 @@ impl Inner {
681684
match Self::parse(ty, Lifetime::Unspecified, context) {
682685
Self::Fn {
683686
is_variadic: false,
687+
no_escape,
684688
arguments,
685689
result_type,
686690
} => Self::Pointer {
687691
nullability,
688692
is_const,
689693
pointee: Box::new(Self::Block {
694+
sendable: None,
695+
no_escape,
690696
arguments,
691697
result_type,
692698
}),
@@ -924,6 +930,7 @@ impl Inner {
924930

925931
Self::Fn {
926932
is_variadic: ty.is_variadic(),
933+
no_escape: false,
927934
arguments,
928935
result_type: Box::new(result_type),
929936
}
@@ -1008,11 +1015,14 @@ impl Inner {
10081015
//
10091016
// }
10101017
Self::Fn {
1018+
is_variadic: _,
1019+
no_escape: _,
10111020
arguments,
10121021
result_type,
1013-
..
10141022
}
10151023
| Self::Block {
1024+
sendable: _,
1025+
no_escape: _,
10161026
arguments,
10171027
result_type,
10181028
} => {
@@ -1106,6 +1116,7 @@ impl fmt::Display for Inner {
11061116
} => match &**pointee {
11071117
Self::Fn {
11081118
is_variadic,
1119+
no_escape: _,
11091120
arguments,
11101121
result_type,
11111122
} => {
@@ -1161,6 +1172,8 @@ impl fmt::Display for Inner {
11611172
Enum { id } | Struct { id } | TypeDef { id } => write!(f, "{}", id.path()),
11621173
Self::Fn { .. } => write!(f, "TodoFunction"),
11631174
Self::Block {
1175+
sendable: _,
1176+
no_escape: _,
11641177
arguments,
11651178
result_type,
11661179
} => {
@@ -1213,10 +1226,44 @@ impl Ty {
12131226
pub fn parse_method_argument(
12141227
ty: Type<'_>,
12151228
_qualifier: Option<MethodArgumentQualifier>,
1216-
_sendable: Option<bool>,
1229+
mut arg_sendable: Option<bool>,
1230+
mut arg_no_escape: bool,
12171231
context: &Context<'_>,
12181232
) -> Self {
1219-
let ty = Inner::parse(ty, Lifetime::Unspecified, context);
1233+
let mut ty = Inner::parse(ty, Lifetime::Unspecified, context);
1234+
1235+
match &mut ty {
1236+
Inner::Pointer { pointee, .. } => match &mut **pointee {
1237+
Inner::Block {
1238+
sendable,
1239+
no_escape,
1240+
..
1241+
} => {
1242+
*sendable = arg_sendable;
1243+
*no_escape = arg_no_escape;
1244+
arg_sendable = None;
1245+
arg_no_escape = false;
1246+
}
1247+
Inner::Fn { no_escape, .. } => {
1248+
*no_escape = arg_no_escape;
1249+
arg_no_escape = false;
1250+
}
1251+
_ => {}
1252+
},
1253+
// Ignore NSComparator for now
1254+
Inner::TypeDef { id } if id.is_nscomparator() => {
1255+
arg_no_escape = false;
1256+
}
1257+
_ => {}
1258+
}
1259+
1260+
if arg_sendable.is_some() {
1261+
warn!(?ty, "did not consume sendable in argument");
1262+
}
1263+
1264+
if arg_no_escape {
1265+
warn!(?ty, "did not consume no_escape in argument");
1266+
}
12201267

12211268
match &ty {
12221269
Inner::Pointer { pointee, .. } => pointee.visit_lifetime(|lifetime| {
@@ -1274,7 +1321,7 @@ impl Ty {
12741321
}
12751322

12761323
pub fn parse_function_argument(ty: Type<'_>, context: &Context<'_>) -> Self {
1277-
let mut this = Self::parse_method_argument(ty, None, None, context);
1324+
let mut this = Self::parse_method_argument(ty, None, None, false, context);
12781325
this.kind = TyKind::FnArgument;
12791326
this
12801327
}

crates/header-translator/src/unexposed_attr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum UnexposedAttr {
2525
NonSendable,
2626
UIActor,
2727
NonIsolated,
28+
29+
NoEscape,
2830
}
2931

3032
impl UnexposedAttr {
@@ -77,8 +79,7 @@ impl UnexposedAttr {
7779
let _ = get_arguments();
7880
None
7981
}
80-
// TODO
81-
"NS_NOESCAPE" => None,
82+
"NS_NOESCAPE" => Some(Self::NoEscape),
8283
// TODO: We could potentially automatically elide this argument
8384
// from the method call, though it's rare enough that it's
8485
// probably not really worth the effort.

0 commit comments

Comments
 (0)