1
Fork 0

Rollup merge of #138399 - Bryanskiy:delegation-extern-fn, r=petrochenkov

Delegation: allow foreign fns `reuse`

In example:
```rust
unsafe extern "C" {
    fn foo();
}

reuse foo as bar;
```

Desugaring before:

```rust
fn bar() {
    foo()
    //~^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block
}
```

after:

```rust
unsafe extern "C" fn bar() {
    foo()
}
```

Fixes https://github.com/rust-lang/rust/issues/127412

r? `@petrochenkov`
This commit is contained in:
Matthias Krüger 2025-03-13 17:44:07 +01:00 committed by GitHub
commit 41d6e6e8da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 87 additions and 13 deletions

View file

@ -190,14 +190,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::FnSig<'hir> {
let header = if let Some(local_sig_id) = sig_id.as_local() {
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
Some(sig) => self.lower_fn_header(
sig.header,
Some(sig) => {
let parent = self.tcx.parent(sig_id);
// HACK: we override the default safety instead of generating attributes from the ether.
// We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
// and here we need the hir attributes.
if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe },
&[],
),
let default_safety =
if sig.target_feature || self.tcx.def_kind(parent) == DefKind::ForeignMod {
hir::Safety::Unsafe
} else {
hir::Safety::Safe
};
self.lower_fn_header(sig.header, default_safety, &[])
}
None => self.generate_header_error(),
}
} else {