Skip to content

Commit 99f886e

Browse files
committed
Auto merge of rust-lang#135486 - GuillaumeGomez:rollup-oblyjq9, r=GuillaumeGomez
Rollup of 5 pull requests Successful merges: - rust-lang#134216 (Enable "jump to def" feature on patterns) - rust-lang#134353 (Treat safe target_feature functions as unsafe by default [less invasive variant]) - rust-lang#134880 (Made `Path::name` only have item name rather than full name) - rust-lang#135466 (Leak check in `impossible_predicates` to avoid monomorphizing impossible instances) - rust-lang#135476 (Remove remnant of asmjs) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8c39ce5 + f2ec216 commit 99f886e

File tree

49 files changed

+502
-159
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+502
-159
lines changed

Diff for: compiler/rustc_ast_lowering/src/delegation.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
188188
) -> hir::FnSig<'hir> {
189189
let header = if let Some(local_sig_id) = sig_id.as_local() {
190190
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
191-
Some(sig) => self.lower_fn_header(sig.header, hir::Safety::Safe),
191+
Some(sig) => self.lower_fn_header(
192+
sig.header,
193+
// HACK: we override the default safety instead of generating attributes from the ether.
194+
// We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
195+
// and here we need the hir attributes.
196+
if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe },
197+
&[],
198+
),
192199
None => self.generate_header_error(),
193200
}
194201
} else {
@@ -198,7 +205,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
198205
Asyncness::No => hir::IsAsync::NotAsync,
199206
};
200207
hir::FnHeader {
201-
safety: sig.safety,
208+
safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features {
209+
hir::HeaderSafety::SafeTargetFeatures
210+
} else {
211+
hir::HeaderSafety::Normal(sig.safety)
212+
},
202213
constness: self.tcx.constness(sig_id),
203214
asyncness,
204215
abi: sig.abi,
@@ -384,7 +395,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
384395

385396
fn generate_header_error(&self) -> hir::FnHeader {
386397
hir::FnHeader {
387-
safety: hir::Safety::Safe,
398+
safety: hir::Safety::Safe.into(),
388399
constness: hir::Constness::NotConst,
389400
asyncness: hir::IsAsync::NotAsync,
390401
abi: abi::Abi::Rust,

Diff for: compiler/rustc_ast_lowering/src/item.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
231231
});
232232
let sig = hir::FnSig {
233233
decl,
234-
header: this.lower_fn_header(*header, hir::Safety::Safe),
234+
header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
235235
span: this.lower_span(*fn_sig_span),
236236
};
237237
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
@@ -610,7 +610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
610610
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
611611
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
612612
let owner_id = hir_id.expect_owner();
613-
self.lower_attrs(hir_id, &i.attrs);
613+
let attrs = self.lower_attrs(hir_id, &i.attrs);
614614
let item = hir::ForeignItem {
615615
owner_id,
616616
ident: self.lower_ident(i.ident),
@@ -634,7 +634,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
634634
});
635635

636636
// Unmarked safety in unsafe block defaults to unsafe.
637-
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe);
637+
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
638638

639639
hir::ForeignItemKind::Fn(
640640
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
@@ -776,6 +776,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
776776
i.id,
777777
FnDeclKind::Trait,
778778
sig.header.coroutine_kind,
779+
attrs,
779780
);
780781
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
781782
}
@@ -795,6 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
795796
i.id,
796797
FnDeclKind::Trait,
797798
sig.header.coroutine_kind,
799+
attrs,
798800
);
799801
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
800802
}
@@ -911,6 +913,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
911913
i.id,
912914
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
913915
sig.header.coroutine_kind,
916+
attrs,
914917
);
915918

916919
(generics, hir::ImplItemKind::Fn(sig, body_id))
@@ -1339,8 +1342,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13391342
id: NodeId,
13401343
kind: FnDeclKind,
13411344
coroutine_kind: Option<CoroutineKind>,
1345+
attrs: &[hir::Attribute],
13421346
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
1343-
let header = self.lower_fn_header(sig.header, hir::Safety::Safe);
1347+
let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
13441348
let itctx = ImplTraitContext::Universal;
13451349
let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
13461350
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
@@ -1352,14 +1356,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
13521356
&mut self,
13531357
h: FnHeader,
13541358
default_safety: hir::Safety,
1359+
attrs: &[hir::Attribute],
13551360
) -> hir::FnHeader {
13561361
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
13571362
hir::IsAsync::Async(span)
13581363
} else {
13591364
hir::IsAsync::NotAsync
13601365
};
1366+
1367+
let safety = self.lower_safety(h.safety, default_safety);
1368+
1369+
// Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
1370+
let safety =
1371+
if attrs.iter().any(|attr| attr.has_name(sym::target_feature)) && safety.is_safe() {
1372+
hir::HeaderSafety::SafeTargetFeatures
1373+
} else {
1374+
safety.into()
1375+
};
1376+
13611377
hir::FnHeader {
1362-
safety: self.lower_safety(h.safety, default_safety),
1378+
safety,
13631379
asyncness,
13641380
constness: self.lower_constness(h.constness),
13651381
abi: self.lower_extern(h.ext),

Diff for: compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
250250
}
251251
}
252252
sym::target_feature => {
253-
if !tcx.is_closure_like(did.to_def_id())
254-
&& let Some(fn_sig) = fn_sig()
255-
&& fn_sig.skip_binder().safety().is_safe()
256-
{
253+
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
254+
tcx.dcx().span_delayed_bug(attr.span, "target_feature applied to non-fn");
255+
continue;
256+
};
257+
let safe_target_features =
258+
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
259+
codegen_fn_attrs.safe_target_features = safe_target_features;
260+
if safe_target_features {
257261
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
258262
// The `#[target_feature]` attribute is allowed on
259263
// WebAssembly targets on all functions, including safe

Diff for: compiler/rustc_hir/src/hir.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -3762,9 +3762,30 @@ impl fmt::Display for Constness {
37623762
}
37633763
}
37643764

3765+
/// The actualy safety specified in syntax. We may treat
3766+
/// its safety different within the type system to create a
3767+
/// "sound by default" system that needs checking this enum
3768+
/// explicitly to allow unsafe operations.
3769+
#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
3770+
pub enum HeaderSafety {
3771+
/// A safe function annotated with `#[target_features]`.
3772+
/// The type system treats this function as an unsafe function,
3773+
/// but safety checking will check this enum to treat it as safe
3774+
/// and allowing calling other safe target feature functions with
3775+
/// the same features without requiring an additional unsafe block.
3776+
SafeTargetFeatures,
3777+
Normal(Safety),
3778+
}
3779+
3780+
impl From<Safety> for HeaderSafety {
3781+
fn from(v: Safety) -> Self {
3782+
Self::Normal(v)
3783+
}
3784+
}
3785+
37653786
#[derive(Copy, Clone, Debug, HashStable_Generic)]
37663787
pub struct FnHeader {
3767-
pub safety: Safety,
3788+
pub safety: HeaderSafety,
37683789
pub constness: Constness,
37693790
pub asyncness: IsAsync,
37703791
pub abi: ExternAbi,
@@ -3780,7 +3801,18 @@ impl FnHeader {
37803801
}
37813802

37823803
pub fn is_unsafe(&self) -> bool {
3783-
self.safety.is_unsafe()
3804+
self.safety().is_unsafe()
3805+
}
3806+
3807+
pub fn is_safe(&self) -> bool {
3808+
self.safety().is_safe()
3809+
}
3810+
3811+
pub fn safety(&self) -> Safety {
3812+
match self.safety {
3813+
HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
3814+
HeaderSafety::Normal(safety) => safety,
3815+
}
37843816
}
37853817
}
37863818

Diff for: compiler/rustc_hir_analysis/src/collect.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
13361336
{
13371337
icx.lowerer().lower_fn_ty(
13381338
hir_id,
1339-
sig.header.safety,
1339+
sig.header.safety(),
13401340
sig.header.abi,
13411341
sig.decl,
13421342
Some(generics),
@@ -1351,13 +1351,18 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
13511351
kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
13521352
generics,
13531353
..
1354-
}) => {
1355-
icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None)
1356-
}
1354+
}) => icx.lowerer().lower_fn_ty(
1355+
hir_id,
1356+
header.safety(),
1357+
header.abi,
1358+
decl,
1359+
Some(generics),
1360+
None,
1361+
),
13571362

13581363
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
13591364
let abi = tcx.hir().get_foreign_abi(hir_id);
1360-
compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety)
1365+
compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
13611366
}
13621367

13631368
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
@@ -1405,7 +1410,7 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
14051410

14061411
icx.lowerer().lower_fn_ty(
14071412
icx.tcx().local_def_id_to_hir_id(def_id),
1408-
sig.header.safety,
1413+
sig.header.safety(),
14091414
sig.header.abi,
14101415
sig.decl,
14111416
Some(generics),

Diff for: compiler/rustc_hir_pretty/src/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2407,7 +2407,7 @@ impl<'a> State<'a> {
24072407
self.print_fn(
24082408
decl,
24092409
hir::FnHeader {
2410-
safety,
2410+
safety: safety.into(),
24112411
abi,
24122412
constness: hir::Constness::NotConst,
24132413
asyncness: hir::IsAsync::NotAsync,
@@ -2423,12 +2423,20 @@ impl<'a> State<'a> {
24232423
fn print_fn_header_info(&mut self, header: hir::FnHeader) {
24242424
self.print_constness(header.constness);
24252425

2426+
let safety = match header.safety {
2427+
hir::HeaderSafety::SafeTargetFeatures => {
2428+
self.word_nbsp("#[target_feature]");
2429+
hir::Safety::Safe
2430+
}
2431+
hir::HeaderSafety::Normal(safety) => safety,
2432+
};
2433+
24262434
match header.asyncness {
24272435
hir::IsAsync::NotAsync => {}
24282436
hir::IsAsync::Async(_) => self.word_nbsp("async"),
24292437
}
24302438

2431-
self.print_safety(header.safety);
2439+
self.print_safety(safety);
24322440

24332441
if header.abi != ExternAbi::Rust {
24342442
self.word_nbsp("extern");

Diff for: compiler/rustc_hir_typeck/src/coercion.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -932,10 +932,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
932932
return Err(TypeError::ForceInlineCast);
933933
}
934934

935-
// Safe `#[target_feature]` functions are not assignable to safe fn pointers
936-
// (RFC 2396).
935+
let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
936+
if matches!(fn_attrs.inline, InlineAttr::Force { .. }) {
937+
return Err(TypeError::ForceInlineCast);
938+
}
939+
940+
// FIXME(target_feature): Safe `#[target_feature]` functions could be cast to safe fn pointers (RFC 2396),
941+
// as you can already write that "cast" in user code by wrapping a target_feature fn call in a closure,
942+
// which is safe. This is sound because you already need to be executing code that is satisfying the target
943+
// feature constraints..
937944
if b_hdr.safety.is_safe()
938-
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
945+
&& self.tcx.codegen_fn_attrs(def_id).safe_target_features
939946
{
940947
return Err(TypeError::TargetFeatureCast(def_id));
941948
}

Diff for: compiler/rustc_hir_typeck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ fn typeck_with_fallback<'tcx>(
139139
// type that has an infer in it, lower the type directly so that it'll
140140
// be correctly filled with infer. We'll use this inference to provide
141141
// a suggestion later on.
142-
fcx.lowerer().lower_fn_ty(id, header.safety, header.abi, decl, None, None)
142+
fcx.lowerer().lower_fn_ty(id, header.safety(), header.abi, decl, None, None)
143143
} else {
144144
tcx.fn_sig(def_id).instantiate_identity()
145145
};

Diff for: compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub struct CodegenFnAttrs {
3030
/// features (only enabled features are supported right now).
3131
/// Implied target features have already been applied.
3232
pub target_features: Vec<TargetFeature>,
33+
/// Whether the function was declared safe, but has target features
34+
pub safe_target_features: bool,
3335
/// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
3436
pub linkage: Option<Linkage>,
3537
/// The `#[linkage = "..."]` attribute on foreign items and the value we found.
@@ -150,6 +152,7 @@ impl CodegenFnAttrs {
150152
link_name: None,
151153
link_ordinal: None,
152154
target_features: vec![],
155+
safe_target_features: false,
153156
linkage: None,
154157
import_linkage: None,
155158
link_section: None,

Diff for: compiler/rustc_middle/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ pub struct DelegationFnSig {
222222
pub param_count: usize,
223223
pub has_self: bool,
224224
pub c_variadic: bool,
225+
pub target_feature: bool,
225226
}
226227

227228
#[derive(Clone, Copy, Debug)]

Diff for: compiler/rustc_middle/src/ty/print/pretty.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
690690
if with_reduced_queries() {
691691
p!(print_def_path(def_id, args));
692692
} else {
693-
let sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
693+
let mut sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
694+
if self.tcx().codegen_fn_attrs(def_id).safe_target_features {
695+
p!("#[target_features] ");
696+
sig = sig.map_bound(|mut sig| {
697+
sig.safety = hir::Safety::Safe;
698+
sig
699+
});
700+
}
694701
p!(print(sig), " {{", print_value_path(def_id, args), "}}");
695702
}
696703
}

0 commit comments

Comments
 (0)