authorbors <bors@rust-lang.org> 2024-07-16 16:14:47 UTC
committerbors <bors@rust-lang.org> 2024-07-16 16:14:47 UTC
log16b569057e4d1591b4bee05f10df34000308dedc
tree91e0788419dd4b30c1b21dfce0c11503c0d88ac4
parenta91f7d72f12efcc00ecf71591f066c534d45ddf7
parentab4cc440dd4711fbdba04417aa43910d95576c13

Auto merge of #127819 - matthiaskrgr:rollup-djdffkl, r=matthiaskrgr

Rollup of 8 pull requests Successful merges: - #127669 (Fix the issue of invalid suggestion for a reference of iterator) - #127707 (match lowering: Use an iterator to find `expand_until`) - #127730 (Fix and enforce `unsafe_op_in_unsafe_fn` in compiler) - #127789 (delete #![allow(unsafe_op_in_unsafe_fn)] in teeos) - #127805 (run-make-support: update gimli to 0.31.0) - #127808 (Make ErrorGuaranteed discoverable outside types, consts, and lifetimes) - #127817 (Fix a bunch of sites that were walking instead of visiting, making it impossible for visitor impls to look at these values) - #127818 (Various ast validation simplifications) r? `@ghost` `@rustbot` modify labels: rollup

30 files changed, 643 insertions(+), 500 deletions(-)

Cargo.lock+12-1
......@@ -1618,6 +1618,17 @@ dependencies = [
16181618 "rustc-std-workspace-core",
16191619]
16201620
1621[[package]]
1622name = "gimli"
1623version = "0.31.0"
1624source = "registry+https://github.com/rust-lang/crates.io-index"
1625checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
1626dependencies = [
1627 "fallible-iterator",
1628 "indexmap",
1629 "stable_deref_trait",
1630]
1631
16211632[[package]]
16221633name = "glob"
16231634version = "0.3.1"
......@@ -3421,7 +3432,7 @@ dependencies = [
34213432 "ar",
34223433 "bstr",
34233434 "build_helper",
3424 "gimli 0.28.1",
3435 "gimli 0.31.0",
34253436 "object 0.34.0",
34263437 "regex",
34273438 "similar",
compiler/rustc_abi/src/lib.rs+2-2
......@@ -627,7 +627,7 @@ impl Step for Size {
627627
628628 #[inline]
629629 unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
630 Self::from_bytes(u64::forward_unchecked(start.bytes(), count))
630 Self::from_bytes(unsafe { u64::forward_unchecked(start.bytes(), count) })
631631 }
632632
633633 #[inline]
......@@ -642,7 +642,7 @@ impl Step for Size {
642642
643643 #[inline]
644644 unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
645 Self::from_bytes(u64::backward_unchecked(start.bytes(), count))
645 Self::from_bytes(unsafe { u64::backward_unchecked(start.bytes(), count) })
646646 }
647647}
648648
compiler/rustc_ast/src/mut_visit.rs+3-3
......@@ -482,7 +482,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
482482 TyKind::Slice(ty) => vis.visit_ty(ty),
483483 TyKind::Ptr(mt) => vis.visit_mt(mt),
484484 TyKind::Ref(lt, mt) => {
485 visit_opt(lt, |lt| noop_visit_lifetime(lt, vis));
485 visit_opt(lt, |lt| vis.visit_lifetime(lt));
486486 vis.visit_mt(mt);
487487 }
488488 TyKind::BareFn(bft) => {
......@@ -925,7 +925,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
925925 vis.visit_id(id);
926926 visit_attrs(attrs, vis);
927927 vis.visit_ident(ident);
928 visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
928 visit_vec(bounds, |bound| vis.visit_param_bound(bound));
929929 match kind {
930930 GenericParamKind::Lifetime => {}
931931 GenericParamKind::Type { default } => {
......@@ -983,7 +983,7 @@ fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mu
983983 }
984984 WherePredicate::RegionPredicate(rp) => {
985985 let WhereRegionPredicate { span, lifetime, bounds } = rp;
986 noop_visit_lifetime(lifetime, vis);
986 vis.visit_lifetime(lifetime);
987987 visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
988988 vis.visit_span(span);
989989 }
compiler/rustc_ast_passes/src/ast_validation.rs+26-70
......@@ -38,7 +38,7 @@ use std::mem;
3838use std::ops::{Deref, DerefMut};
3939use thin_vec::thin_vec;
4040
41use crate::errors;
41use crate::errors::{self, TildeConstReason};
4242
4343/// Is `self` allowed semantically as the first parameter in an `FnDecl`?
4444enum SelfSemantic {
......@@ -46,27 +46,12 @@ enum SelfSemantic {
4646 No,
4747}
4848
49/// What is the context that prevents using `~const`?
50// FIXME(effects): Consider getting rid of this in favor of `errors::TildeConstReason`, they're
51// almost identical. This gets rid of an abstraction layer which might be considered bad.
52enum DisallowTildeConstContext<'a> {
53 TraitObject,
54 Fn(FnKind<'a>),
55 Trait(Span),
56 TraitImpl(Span),
57 Impl(Span),
58 TraitAssocTy(Span),
59 TraitImplAssocTy(Span),
60 InherentAssocTy(Span),
61 Item,
62}
63
64enum TraitOrTraitImpl<'a> {
49enum TraitOrTraitImpl {
6550 Trait { span: Span, constness: Option<Span> },
66 TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: &'a TraitRef },
51 TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: Span },
6752}
6853
69impl<'a> TraitOrTraitImpl<'a> {
54impl TraitOrTraitImpl {
7055 fn constness(&self) -> Option<Span> {
7156 match self {
7257 Self::Trait { constness: Some(span), .. }
......@@ -81,9 +66,9 @@ struct AstValidator<'a> {
8166 features: &'a Features,
8267
8368 /// The span of the `extern` in an `extern { ... }` block, if any.
84 extern_mod: Option<&'a Item>,
69 extern_mod: Option<Span>,
8570
86 outer_trait_or_trait_impl: Option<TraitOrTraitImpl<'a>>,
71 outer_trait_or_trait_impl: Option<TraitOrTraitImpl>,
8772
8873 has_proc_macro_decls: bool,
8974
......@@ -92,7 +77,7 @@ struct AstValidator<'a> {
9277 /// e.g., `impl Iterator<Item = impl Debug>`.
9378 outer_impl_trait: Option<Span>,
9479
95 disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
80 disallow_tilde_const: Option<TildeConstReason>,
9681
9782 /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
9883 /// or `Foo::Bar<impl Trait>`
......@@ -115,7 +100,7 @@ impl<'a> AstValidator<'a> {
115100 trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl {
116101 constness,
117102 polarity,
118 trait_ref,
103 trait_ref: trait_ref.path.span,
119104 }),
120105 );
121106 f(self);
......@@ -145,7 +130,7 @@ impl<'a> AstValidator<'a> {
145130
146131 fn with_tilde_const(
147132 &mut self,
148 disallowed: Option<DisallowTildeConstContext<'a>>,
133 disallowed: Option<TildeConstReason>,
149134 f: impl FnOnce(&mut Self),
150135 ) {
151136 let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
......@@ -224,7 +209,7 @@ impl<'a> AstValidator<'a> {
224209 }
225210 }
226211 TyKind::TraitObject(..) => self
227 .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
212 .with_tilde_const(Some(TildeConstReason::TraitObject), |this| {
228213 visit::walk_ty(this, t)
229214 }),
230215 TyKind::Path(qself, path) => {
......@@ -354,7 +339,7 @@ impl<'a> AstValidator<'a> {
354339 }
355340 }
356341
357 fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'a>) {
342 fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
358343 let Const::Yes(span) = constness else {
359344 return;
360345 };
......@@ -367,7 +352,7 @@ impl<'a> AstValidator<'a> {
367352 ..
368353 } = parent
369354 {
370 Some(trait_ref.path.span.shrink_to_lo())
355 Some(trait_ref.shrink_to_lo())
371356 } else {
372357 None
373358 };
......@@ -579,7 +564,7 @@ impl<'a> AstValidator<'a> {
579564 }
580565
581566 fn current_extern_span(&self) -> Span {
582 self.session.source_map().guess_head_span(self.extern_mod.unwrap().span)
567 self.session.source_map().guess_head_span(self.extern_mod.unwrap())
583568 }
584569
585570 /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
......@@ -980,7 +965,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
980965 this.visit_vis(&item.vis);
981966 this.visit_ident(item.ident);
982967 let disallowed = matches!(constness, Const::No)
983 .then(|| DisallowTildeConstContext::TraitImpl(item.span));
968 .then(|| TildeConstReason::TraitImpl { span: item.span });
984969 this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
985970 this.visit_trait_ref(t);
986971 this.visit_ty(self_ty);
......@@ -1035,7 +1020,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10351020 this.visit_vis(&item.vis);
10361021 this.visit_ident(item.ident);
10371022 this.with_tilde_const(
1038 Some(DisallowTildeConstContext::Impl(item.span)),
1023 Some(TildeConstReason::Impl { span: item.span }),
10391024 |this| this.visit_generics(generics),
10401025 );
10411026 this.visit_ty(self_ty);
......@@ -1080,7 +1065,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10801065 }
10811066 ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
10821067 self.with_in_extern_mod(*safety, |this| {
1083 let old_item = mem::replace(&mut this.extern_mod, Some(item));
1068 let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
10841069 this.visibility_not_permitted(
10851070 &item.vis,
10861071 errors::VisibilityNotPermittedNote::IndividualForeignItems,
......@@ -1154,7 +1139,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11541139 this.visit_ident(item.ident);
11551140 let disallowed = is_const_trait
11561141 .is_none()
1157 .then(|| DisallowTildeConstContext::Trait(item.span));
1142 .then(|| TildeConstReason::Trait { span: item.span });
11581143 this.with_tilde_const(disallowed, |this| {
11591144 this.visit_generics(generics);
11601145 walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
......@@ -1399,40 +1384,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13991384 self.dcx().emit_err(errors::ConstBoundTraitObject { span: trait_ref.span });
14001385 }
14011386 (_, BoundConstness::Maybe(span), BoundPolarity::Positive)
1402 if let Some(reason) = &self.disallow_tilde_const =>
1387 if let Some(reason) = self.disallow_tilde_const =>
14031388 {
1404 let reason = match reason {
1405 DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
1406 errors::TildeConstReason::Closure
1407 }
1408 DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
1409 errors::TildeConstReason::Function { ident: ident.span }
1410 }
1411 &DisallowTildeConstContext::Trait(span) => {
1412 errors::TildeConstReason::Trait { span }
1413 }
1414 &DisallowTildeConstContext::TraitImpl(span) => {
1415 errors::TildeConstReason::TraitImpl { span }
1416 }
1417 &DisallowTildeConstContext::Impl(span) => {
1418 // FIXME(effects): Consider providing a help message or even a structured
1419 // suggestion for moving such bounds to the assoc const fns if available.
1420 errors::TildeConstReason::Impl { span }
1421 }
1422 &DisallowTildeConstContext::TraitAssocTy(span) => {
1423 errors::TildeConstReason::TraitAssocTy { span }
1424 }
1425 &DisallowTildeConstContext::TraitImplAssocTy(span) => {
1426 errors::TildeConstReason::TraitImplAssocTy { span }
1427 }
1428 &DisallowTildeConstContext::InherentAssocTy(span) => {
1429 errors::TildeConstReason::InherentAssocTy { span }
1430 }
1431 DisallowTildeConstContext::TraitObject => {
1432 errors::TildeConstReason::TraitObject
1433 }
1434 DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
1435 };
14361389 self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
14371390 }
14381391 (
......@@ -1569,7 +1522,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15691522 .and_then(TraitOrTraitImpl::constness)
15701523 .is_some();
15711524
1572 let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
1525 let disallowed = (!tilde_const_allowed).then(|| match fk {
1526 FnKind::Fn(_, ident, _, _, _, _) => TildeConstReason::Function { ident: ident.span },
1527 FnKind::Closure(_, _, _) => TildeConstReason::Closure,
1528 });
15731529 self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
15741530 }
15751531
......@@ -1664,12 +1620,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
16641620 AssocItemKind::Type(_) => {
16651621 let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl {
16661622 Some(TraitOrTraitImpl::Trait { .. }) => {
1667 DisallowTildeConstContext::TraitAssocTy(item.span)
1623 TildeConstReason::TraitAssocTy { span: item.span }
16681624 }
16691625 Some(TraitOrTraitImpl::TraitImpl { .. }) => {
1670 DisallowTildeConstContext::TraitImplAssocTy(item.span)
1626 TildeConstReason::TraitImplAssocTy { span: item.span }
16711627 }
1672 None => DisallowTildeConstContext::InherentAssocTy(item.span),
1628 None => TildeConstReason::InherentAssocTy { span: item.span },
16731629 });
16741630 self.with_tilde_const(disallowed, |this| {
16751631 this.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt))
......@@ -1852,7 +1808,7 @@ pub fn check_crate(
18521808 outer_trait_or_trait_impl: None,
18531809 has_proc_macro_decls: false,
18541810 outer_impl_trait: None,
1855 disallow_tilde_const: Some(DisallowTildeConstContext::Item),
1811 disallow_tilde_const: Some(TildeConstReason::Item),
18561812 is_impl_trait_banned: false,
18571813 extern_mod_safety: None,
18581814 lint_buffer: lints,
compiler/rustc_ast_passes/src/errors.rs+1-1
......@@ -612,7 +612,7 @@ pub struct TildeConstDisallowed {
612612 pub reason: TildeConstReason,
613613}
614614
615#[derive(Subdiagnostic)]
615#[derive(Subdiagnostic, Copy, Clone)]
616616pub enum TildeConstReason {
617617 #[note(ast_passes_closure)]
618618 Closure,
compiler/rustc_codegen_llvm/src/allocator.rs+27-23
......@@ -21,14 +21,16 @@ pub(crate) unsafe fn codegen(
2121) {
2222 let llcx = &*module_llvm.llcx;
2323 let llmod = module_llvm.llmod();
24 let usize = match tcx.sess.target.pointer_width {
25 16 => llvm::LLVMInt16TypeInContext(llcx),
26 32 => llvm::LLVMInt32TypeInContext(llcx),
27 64 => llvm::LLVMInt64TypeInContext(llcx),
28 tws => bug!("Unsupported target word size for int: {}", tws),
24 let usize = unsafe {
25 match tcx.sess.target.pointer_width {
26 16 => llvm::LLVMInt16TypeInContext(llcx),
27 32 => llvm::LLVMInt32TypeInContext(llcx),
28 64 => llvm::LLVMInt64TypeInContext(llcx),
29 tws => bug!("Unsupported target word size for int: {}", tws),
30 }
2931 };
30 let i8 = llvm::LLVMInt8TypeInContext(llcx);
31 let i8p = llvm::LLVMPointerTypeInContext(llcx, 0);
32 let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) };
33 let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) };
3234
3335 if kind == AllocatorKind::Default {
3436 for method in ALLOCATOR_METHODS {
......@@ -73,23 +75,25 @@ pub(crate) unsafe fn codegen(
7375 true,
7476 );
7577
76 // __rust_alloc_error_handler_should_panic
77 let name = OomStrategy::SYMBOL;
78 let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
79 if tcx.sess.default_hidden_visibility() {
80 llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
81 }
82 let val = tcx.sess.opts.unstable_opts.oom.should_panic();
83 let llval = llvm::LLVMConstInt(i8, val as u64, False);
84 llvm::LLVMSetInitializer(ll_g, llval);
85
86 let name = NO_ALLOC_SHIM_IS_UNSTABLE;
87 let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
88 if tcx.sess.default_hidden_visibility() {
89 llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
78 unsafe {
79 // __rust_alloc_error_handler_should_panic
80 let name = OomStrategy::SYMBOL;
81 let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
82 if tcx.sess.default_hidden_visibility() {
83 llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
84 }
85 let val = tcx.sess.opts.unstable_opts.oom.should_panic();
86 let llval = llvm::LLVMConstInt(i8, val as u64, False);
87 llvm::LLVMSetInitializer(ll_g, llval);
88
89 let name = NO_ALLOC_SHIM_IS_UNSTABLE;
90 let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
91 if tcx.sess.default_hidden_visibility() {
92 llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
93 }
94 let llval = llvm::LLVMConstInt(i8, 0, False);
95 llvm::LLVMSetInitializer(ll_g, llval);
9096 }
91 let llval = llvm::LLVMConstInt(i8, 0, False);
92 llvm::LLVMSetInitializer(ll_g, llval);
9397
9498 if tcx.sess.opts.debuginfo != DebugInfo::None {
9599 let dbg_cx = debuginfo::CodegenUnitDebugContext::new(llmod);
compiler/rustc_codegen_llvm/src/back/lto.rs+11-5
......@@ -727,7 +727,7 @@ pub unsafe fn optimize_thin_module(
727727 // into that context. One day, however, we may do this for upstream
728728 // crates but for locally codegened modules we may be able to reuse
729729 // that LLVM Context and Module.
730 let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
730 let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) };
731731 let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _;
732732 let mut module = ModuleCodegen {
733733 module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
......@@ -750,7 +750,9 @@ pub unsafe fn optimize_thin_module(
750750 {
751751 let _timer =
752752 cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
753 if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) {
753 if unsafe {
754 !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target)
755 } {
754756 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
755757 }
756758 save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
......@@ -760,7 +762,8 @@ pub unsafe fn optimize_thin_module(
760762 let _timer = cgcx
761763 .prof
762764 .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name());
763 if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
765 if unsafe { !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) }
766 {
764767 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
765768 }
766769 save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve");
......@@ -770,7 +773,8 @@ pub unsafe fn optimize_thin_module(
770773 let _timer = cgcx
771774 .prof
772775 .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name());
773 if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
776 if unsafe { !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) }
777 {
774778 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
775779 }
776780 save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize");
......@@ -779,7 +783,9 @@ pub unsafe fn optimize_thin_module(
779783 {
780784 let _timer =
781785 cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
782 if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) {
786 if unsafe {
787 !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
788 } {
783789 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
784790 }
785791 save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
compiler/rustc_codegen_llvm/src/back/profiling.rs+7-5
......@@ -46,13 +46,15 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback(
4646 pass_name: *const c_char,
4747 ir_name: *const c_char,
4848) {
49 let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
50 let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
51 let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
52 llvm_self_profiler.before_pass_callback(pass_name, ir_name);
49 unsafe {
50 let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
51 let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
52 let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
53 llvm_self_profiler.before_pass_callback(pass_name, ir_name);
54 }
5355}
5456
5557pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
56 let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
58 let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
5759 llvm_self_profiler.after_pass_callback();
5860}
compiler/rustc_codegen_llvm/src/back/write.rs+119-105
......@@ -428,9 +428,10 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
428428 if user.is_null() {
429429 return;
430430 }
431 let (cgcx, dcx) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'_>));
431 let (cgcx, dcx) =
432 unsafe { *(user as *const (&CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'_>)) };
432433
433 match llvm::diagnostic::Diagnostic::unpack(info) {
434 match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } {
434435 llvm::diagnostic::InlineAsm(inline) => {
435436 report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source);
436437 }
......@@ -454,14 +455,14 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
454455 });
455456 }
456457 llvm::diagnostic::PGO(diagnostic_ref) | llvm::diagnostic::Linker(diagnostic_ref) => {
457 let message = llvm::build_string(|s| {
458 let message = llvm::build_string(|s| unsafe {
458459 llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
459460 })
460461 .expect("non-UTF8 diagnostic");
461462 dcx.emit_warn(FromLlvmDiag { message });
462463 }
463464 llvm::diagnostic::Unsupported(diagnostic_ref) => {
464 let message = llvm::build_string(|s| {
465 let message = llvm::build_string(|s| unsafe {
465466 llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
466467 })
467468 .expect("non-UTF8 diagnostic");
......@@ -564,37 +565,39 @@ pub(crate) unsafe fn llvm_optimize(
564565
565566 let llvm_plugins = config.llvm_plugins.join(",");
566567
567 let result = llvm::LLVMRustOptimize(
568 module.module_llvm.llmod(),
569 &*module.module_llvm.tm,
570 to_pass_builder_opt_level(opt_level),
571 opt_stage,
572 cgcx.opts.cg.linker_plugin_lto.enabled(),
573 config.no_prepopulate_passes,
574 config.verify_llvm_ir,
575 using_thin_buffers,
576 config.merge_functions,
577 unroll_loops,
578 config.vectorize_slp,
579 config.vectorize_loop,
580 config.no_builtins,
581 config.emit_lifetime_markers,
582 sanitizer_options.as_ref(),
583 pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
584 pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
585 config.instrument_coverage,
586 instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
587 config.instrument_gcov,
588 pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
589 config.debug_info_for_profiling,
590 llvm_selfprofiler,
591 selfprofile_before_pass_callback,
592 selfprofile_after_pass_callback,
593 extra_passes.as_ptr().cast(),
594 extra_passes.len(),
595 llvm_plugins.as_ptr().cast(),
596 llvm_plugins.len(),
597 );
568 let result = unsafe {
569 llvm::LLVMRustOptimize(
570 module.module_llvm.llmod(),
571 &*module.module_llvm.tm,
572 to_pass_builder_opt_level(opt_level),
573 opt_stage,
574 cgcx.opts.cg.linker_plugin_lto.enabled(),
575 config.no_prepopulate_passes,
576 config.verify_llvm_ir,
577 using_thin_buffers,
578 config.merge_functions,
579 unroll_loops,
580 config.vectorize_slp,
581 config.vectorize_loop,
582 config.no_builtins,
583 config.emit_lifetime_markers,
584 sanitizer_options.as_ref(),
585 pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
586 pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
587 config.instrument_coverage,
588 instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
589 config.instrument_gcov,
590 pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
591 config.debug_info_for_profiling,
592 llvm_selfprofiler,
593 selfprofile_before_pass_callback,
594 selfprofile_after_pass_callback,
595 extra_passes.as_ptr().cast(),
596 extra_passes.len(),
597 llvm_plugins.as_ptr().cast(),
598 llvm_plugins.len(),
599 )
600 };
598601 result.into_result().map_err(|()| llvm_err(dcx, LlvmError::RunLlvmPasses))
599602}
600603
......@@ -617,7 +620,7 @@ pub(crate) unsafe fn optimize(
617620 if config.emit_no_opt_bc {
618621 let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
619622 let out = path_to_c_string(&out);
620 llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
623 unsafe { llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()) };
621624 }
622625
623626 if let Some(opt_level) = config.opt_level {
......@@ -627,7 +630,7 @@ pub(crate) unsafe fn optimize(
627630 _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
628631 _ => llvm::OptStage::PreLinkNoLTO,
629632 };
630 return llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage);
633 return unsafe { llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage) };
631634 }
632635 Ok(())
633636}
......@@ -692,10 +695,12 @@ pub(crate) unsafe fn codegen(
692695 where
693696 F: FnOnce(&'ll mut PassManager<'ll>) -> R,
694697 {
695 let cpm = llvm::LLVMCreatePassManager();
696 llvm::LLVMAddAnalysisPasses(tm, cpm);
697 llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
698 f(cpm)
698 unsafe {
699 let cpm = llvm::LLVMCreatePassManager();
700 llvm::LLVMAddAnalysisPasses(tm, cpm);
701 llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
702 f(cpm)
703 }
699704 }
700705
701706 // Two things to note:
......@@ -757,7 +762,9 @@ pub(crate) unsafe fn codegen(
757762 let _timer = cgcx
758763 .prof
759764 .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name);
760 embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
765 unsafe {
766 embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
767 }
761768 }
762769 }
763770
......@@ -793,7 +800,8 @@ pub(crate) unsafe fn codegen(
793800 cursor.position() as size_t
794801 }
795802
796 let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
803 let result =
804 unsafe { llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback) };
797805
798806 if result == llvm::LLVMRustResult::Success {
799807 record_artifact_size(&cgcx.prof, "llvm_ir", &out);
......@@ -812,22 +820,24 @@ pub(crate) unsafe fn codegen(
812820 // binaries. So we must clone the module to produce the asm output
813821 // if we are also producing object code.
814822 let llmod = if let EmitObj::ObjectCode(_) = config.emit_obj {
815 llvm::LLVMCloneModule(llmod)
823 unsafe { llvm::LLVMCloneModule(llmod) }
816824 } else {
817825 llmod
818826 };
819 with_codegen(tm, llmod, config.no_builtins, |cpm| {
820 write_output_file(
821 dcx,
822 tm,
823 cpm,
824 llmod,
825 &path,
826 None,
827 llvm::FileType::AssemblyFile,
828 &cgcx.prof,
829 )
830 })?;
827 unsafe {
828 with_codegen(tm, llmod, config.no_builtins, |cpm| {
829 write_output_file(
830 dcx,
831 tm,
832 cpm,
833 llmod,
834 &path,
835 None,
836 llvm::FileType::AssemblyFile,
837 &cgcx.prof,
838 )
839 })?;
840 }
831841 }
832842
833843 match config.emit_obj {
......@@ -851,18 +861,20 @@ pub(crate) unsafe fn codegen(
851861 (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
852862 };
853863
854 with_codegen(tm, llmod, config.no_builtins, |cpm| {
855 write_output_file(
856 dcx,
857 tm,
858 cpm,
859 llmod,
860 &obj_out,
861 dwo_out,
862 llvm::FileType::ObjectFile,
863 &cgcx.prof,
864 )
865 })?;
864 unsafe {
865 with_codegen(tm, llmod, config.no_builtins, |cpm| {
866 write_output_file(
867 dcx,
868 tm,
869 cpm,
870 llmod,
871 &obj_out,
872 dwo_out,
873 llvm::FileType::ObjectFile,
874 &cgcx.prof,
875 )
876 })?;
877 }
866878 }
867879
868880 EmitObj::Bitcode => {
......@@ -1013,44 +1025,46 @@ unsafe fn embed_bitcode(
10131025 // reason (see issue #90326 for historical background).
10141026 let is_aix = target_is_aix(cgcx);
10151027 let is_apple = target_is_apple(cgcx);
1016 if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
1017 // We don't need custom section flags, create LLVM globals.
1018 let llconst = common::bytes_in_context(llcx, bitcode);
1019 let llglobal = llvm::LLVMAddGlobal(
1020 llmod,
1021 common::val_ty(llconst),
1022 c"rustc.embedded.module".as_ptr().cast(),
1023 );
1024 llvm::LLVMSetInitializer(llglobal, llconst);
1025
1026 let section = bitcode_section_name(cgcx);
1027 llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
1028 llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
1029 llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
1030
1031 let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
1032 let llglobal = llvm::LLVMAddGlobal(
1033 llmod,
1034 common::val_ty(llconst),
1035 c"rustc.embedded.cmdline".as_ptr().cast(),
1036 );
1037 llvm::LLVMSetInitializer(llglobal, llconst);
1038 let section = if is_apple {
1039 c"__LLVM,__cmdline"
1040 } else if is_aix {
1041 c".info"
1028 unsafe {
1029 if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
1030 // We don't need custom section flags, create LLVM globals.
1031 let llconst = common::bytes_in_context(llcx, bitcode);
1032 let llglobal = llvm::LLVMAddGlobal(
1033 llmod,
1034 common::val_ty(llconst),
1035 c"rustc.embedded.module".as_ptr().cast(),
1036 );
1037 llvm::LLVMSetInitializer(llglobal, llconst);
1038
1039 let section = bitcode_section_name(cgcx);
1040 llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
1041 llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
1042 llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
1043
1044 let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
1045 let llglobal = llvm::LLVMAddGlobal(
1046 llmod,
1047 common::val_ty(llconst),
1048 c"rustc.embedded.cmdline".as_ptr().cast(),
1049 );
1050 llvm::LLVMSetInitializer(llglobal, llconst);
1051 let section = if is_apple {
1052 c"__LLVM,__cmdline"
1053 } else if is_aix {
1054 c".info"
1055 } else {
1056 c".llvmcmd"
1057 };
1058 llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
1059 llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
10421060 } else {
1043 c".llvmcmd"
1044 };
1045 llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
1046 llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
1047 } else {
1048 // We need custom section flags, so emit module-level inline assembly.
1049 let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
1050 let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
1051 llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1052 let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
1053 llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1061 // We need custom section flags, so emit module-level inline assembly.
1062 let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
1063 let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
1064 llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1065 let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
1066 llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
1067 }
10541068 }
10551069}
10561070
compiler/rustc_codegen_llvm/src/context.rs+149-110
......@@ -120,7 +120,7 @@ pub unsafe fn create_module<'ll>(
120120) -> &'ll llvm::Module {
121121 let sess = tcx.sess;
122122 let mod_name = SmallCStr::new(mod_name);
123 let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
123 let llmod = unsafe { llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx) };
124124
125125 let mut target_data_layout = sess.target.data_layout.to_string();
126126 let llvm_version = llvm_util::get_version();
......@@ -153,11 +153,14 @@ pub unsafe fn create_module<'ll>(
153153 // Ensure the data-layout values hardcoded remain the defaults.
154154 {
155155 let tm = crate::back::write::create_informational_target_machine(tcx.sess);
156 llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
156 unsafe {
157 llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
158 }
157159
158 let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
159 let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
160 .expect("got a non-UTF8 data-layout from LLVM");
160 let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
161 let llvm_data_layout =
162 str::from_utf8(unsafe { CStr::from_ptr(llvm_data_layout) }.to_bytes())
163 .expect("got a non-UTF8 data-layout from LLVM");
161164
162165 if target_data_layout != llvm_data_layout {
163166 tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
......@@ -170,20 +173,28 @@ pub unsafe fn create_module<'ll>(
170173 }
171174
172175 let data_layout = SmallCStr::new(&target_data_layout);
173 llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
176 unsafe {
177 llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
178 }
174179
175180 let llvm_target = SmallCStr::new(&sess.target.llvm_target);
176 llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
181 unsafe {
182 llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
183 }
177184
178185 let reloc_model = sess.relocation_model();
179186 if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) {
180 llvm::LLVMRustSetModulePICLevel(llmod);
187 unsafe {
188 llvm::LLVMRustSetModulePICLevel(llmod);
189 }
181190 // PIE is potentially more effective than PIC, but can only be used in executables.
182191 // If all our outputs are executables, then we can relax PIC to PIE.
183192 if reloc_model == RelocModel::Pie
184193 || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
185194 {
186 llvm::LLVMRustSetModulePIELevel(llmod);
195 unsafe {
196 llvm::LLVMRustSetModulePIELevel(llmod);
197 }
187198 }
188199 }
189200
......@@ -192,95 +203,109 @@ pub unsafe fn create_module<'ll>(
192203 // longer jumps) if a larger code model is used with a smaller one.
193204 //
194205 // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
195 llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
206 unsafe {
207 llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
208 }
196209
197210 // If skipping the PLT is enabled, we need to add some module metadata
198211 // to ensure intrinsic calls don't use it.
199212 if !sess.needs_plt() {
200213 let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
201 llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
214 unsafe {
215 llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
216 }
202217 }
203218
204219 // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
205220 if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
206221 let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
207 llvm::LLVMRustAddModuleFlagU32(
208 llmod,
209 llvm::LLVMModFlagBehavior::Override,
210 canonical_jump_tables,
211 1,
212 );
222 unsafe {
223 llvm::LLVMRustAddModuleFlagU32(
224 llmod,
225 llvm::LLVMModFlagBehavior::Override,
226 canonical_jump_tables,
227 1,
228 );
229 }
213230 }
214231
215232 // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
216233 if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
217234 let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
218 llvm::LLVMRustAddModuleFlagU32(
219 llmod,
220 llvm::LLVMModFlagBehavior::Override,
221 enable_split_lto_unit,
222 1,
223 );
235 unsafe {
236 llvm::LLVMRustAddModuleFlagU32(
237 llmod,
238 llvm::LLVMModFlagBehavior::Override,
239 enable_split_lto_unit,
240 1,
241 );
242 }
224243 }
225244
226245 // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
227246 if sess.is_sanitizer_kcfi_enabled() {
228247 let kcfi = c"kcfi".as_ptr().cast();
229 llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
248 unsafe {
249 llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
250 }
230251 }
231252
232253 // Control Flow Guard is currently only supported by the MSVC linker on Windows.
233254 if sess.target.is_like_msvc {
234 match sess.opts.cg.control_flow_guard {
235 CFGuard::Disabled => {}
236 CFGuard::NoChecks => {
237 // Set `cfguard=1` module flag to emit metadata only.
238 llvm::LLVMRustAddModuleFlagU32(
239 llmod,
240 llvm::LLVMModFlagBehavior::Warning,
241 c"cfguard".as_ptr() as *const _,
242 1,
243 )
244 }
245 CFGuard::Checks => {
246 // Set `cfguard=2` module flag to emit metadata and checks.
247 llvm::LLVMRustAddModuleFlagU32(
248 llmod,
249 llvm::LLVMModFlagBehavior::Warning,
250 c"cfguard".as_ptr() as *const _,
251 2,
252 )
255 unsafe {
256 match sess.opts.cg.control_flow_guard {
257 CFGuard::Disabled => {}
258 CFGuard::NoChecks => {
259 // Set `cfguard=1` module flag to emit metadata only.
260 llvm::LLVMRustAddModuleFlagU32(
261 llmod,
262 llvm::LLVMModFlagBehavior::Warning,
263 c"cfguard".as_ptr() as *const _,
264 1,
265 )
266 }
267 CFGuard::Checks => {
268 // Set `cfguard=2` module flag to emit metadata and checks.
269 llvm::LLVMRustAddModuleFlagU32(
270 llmod,
271 llvm::LLVMModFlagBehavior::Warning,
272 c"cfguard".as_ptr() as *const _,
273 2,
274 )
275 }
253276 }
254277 }
255278 }
256279
257280 if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
258281 if sess.target.arch == "aarch64" {
259 llvm::LLVMRustAddModuleFlagU32(
260 llmod,
261 llvm::LLVMModFlagBehavior::Min,
262 c"branch-target-enforcement".as_ptr().cast(),
263 bti.into(),
264 );
265 llvm::LLVMRustAddModuleFlagU32(
266 llmod,
267 llvm::LLVMModFlagBehavior::Min,
268 c"sign-return-address".as_ptr().cast(),
269 pac_ret.is_some().into(),
270 );
271 let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
272 llvm::LLVMRustAddModuleFlagU32(
273 llmod,
274 llvm::LLVMModFlagBehavior::Min,
275 c"sign-return-address-all".as_ptr().cast(),
276 pac_opts.leaf.into(),
277 );
278 llvm::LLVMRustAddModuleFlagU32(
279 llmod,
280 llvm::LLVMModFlagBehavior::Min,
281 c"sign-return-address-with-bkey".as_ptr().cast(),
282 u32::from(pac_opts.key == PAuthKey::B),
283 );
282 unsafe {
283 llvm::LLVMRustAddModuleFlagU32(
284 llmod,
285 llvm::LLVMModFlagBehavior::Min,
286 c"branch-target-enforcement".as_ptr().cast(),
287 bti.into(),
288 );
289 llvm::LLVMRustAddModuleFlagU32(
290 llmod,
291 llvm::LLVMModFlagBehavior::Min,
292 c"sign-return-address".as_ptr().cast(),
293 pac_ret.is_some().into(),
294 );
295 let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
296 llvm::LLVMRustAddModuleFlagU32(
297 llmod,
298 llvm::LLVMModFlagBehavior::Min,
299 c"sign-return-address-all".as_ptr().cast(),
300 pac_opts.leaf.into(),
301 );
302 llvm::LLVMRustAddModuleFlagU32(
303 llmod,
304 llvm::LLVMModFlagBehavior::Min,
305 c"sign-return-address-with-bkey".as_ptr().cast(),
306 u32::from(pac_opts.key == PAuthKey::B),
307 );
308 }
284309 } else {
285310 bug!(
286311 "branch-protection used on non-AArch64 target; \
......@@ -291,39 +316,47 @@ pub unsafe fn create_module<'ll>(
291316
292317 // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
293318 if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
294 llvm::LLVMRustAddModuleFlagU32(
295 llmod,
296 llvm::LLVMModFlagBehavior::Override,
297 c"cf-protection-branch".as_ptr().cast(),
298 1,
299 )
319 unsafe {
320 llvm::LLVMRustAddModuleFlagU32(
321 llmod,
322 llvm::LLVMModFlagBehavior::Override,
323 c"cf-protection-branch".as_ptr().cast(),
324 1,
325 );
326 }
300327 }
301328 if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
302 llvm::LLVMRustAddModuleFlagU32(
303 llmod,
304 llvm::LLVMModFlagBehavior::Override,
305 c"cf-protection-return".as_ptr().cast(),
306 1,
307 )
329 unsafe {
330 llvm::LLVMRustAddModuleFlagU32(
331 llmod,
332 llvm::LLVMModFlagBehavior::Override,
333 c"cf-protection-return".as_ptr().cast(),
334 1,
335 );
336 }
308337 }
309338
310339 if sess.opts.unstable_opts.virtual_function_elimination {
311 llvm::LLVMRustAddModuleFlagU32(
312 llmod,
313 llvm::LLVMModFlagBehavior::Error,
314 c"Virtual Function Elim".as_ptr().cast(),
315 1,
316 );
340 unsafe {
341 llvm::LLVMRustAddModuleFlagU32(
342 llmod,
343 llvm::LLVMModFlagBehavior::Error,
344 c"Virtual Function Elim".as_ptr().cast(),
345 1,
346 );
347 }
317348 }
318349
319350 // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
320351 if sess.opts.unstable_opts.ehcont_guard {
321 llvm::LLVMRustAddModuleFlagU32(
322 llmod,
323 llvm::LLVMModFlagBehavior::Warning,
324 c"ehcontguard".as_ptr() as *const _,
325 1,
326 )
352 unsafe {
353 llvm::LLVMRustAddModuleFlagU32(
354 llmod,
355 llvm::LLVMModFlagBehavior::Warning,
356 c"ehcontguard".as_ptr() as *const _,
357 1,
358 )
359 }
327360 }
328361
329362 // Insert `llvm.ident` metadata.
......@@ -333,16 +366,20 @@ pub unsafe fn create_module<'ll>(
333366 #[allow(clippy::option_env_unwrap)]
334367 let rustc_producer =
335368 format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"));
336 let name_metadata = llvm::LLVMMDStringInContext(
337 llcx,
338 rustc_producer.as_ptr().cast(),
339 rustc_producer.as_bytes().len() as c_uint,
340 );
341 llvm::LLVMAddNamedMetadataOperand(
342 llmod,
343 c"llvm.ident".as_ptr(),
344 llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
345 );
369 let name_metadata = unsafe {
370 llvm::LLVMMDStringInContext(
371 llcx,
372 rustc_producer.as_ptr().cast(),
373 rustc_producer.as_bytes().len() as c_uint,
374 )
375 };
376 unsafe {
377 llvm::LLVMAddNamedMetadataOperand(
378 llmod,
379 c"llvm.ident".as_ptr(),
380 llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
381 );
382 }
346383
347384 // Emit RISC-V specific target-abi metadata
348385 // to workaround lld as the LTO plugin not
......@@ -351,13 +388,15 @@ pub unsafe fn create_module<'ll>(
351388 // If llvm_abiname is empty, emit nothing.
352389 let llvm_abiname = &sess.target.options.llvm_abiname;
353390 if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() {
354 llvm::LLVMRustAddModuleFlagString(
355 llmod,
356 llvm::LLVMModFlagBehavior::Error,
357 c"target-abi".as_ptr(),
358 llvm_abiname.as_ptr().cast(),
359 llvm_abiname.len(),
360 );
391 unsafe {
392 llvm::LLVMRustAddModuleFlagString(
393 llmod,
394 llvm::LLVMModFlagBehavior::Error,
395 c"target-abi".as_ptr(),
396 llvm_abiname.as_ptr().cast(),
397 llvm_abiname.len(),
398 );
399 }
361400 }
362401
363402 // Add module flags specified via -Z llvm_module_flag
......@@ -375,7 +414,7 @@ pub unsafe fn create_module<'ll>(
375414 // We already checked this during option parsing
376415 _ => unreachable!(),
377416 };
378 llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value)
417 unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) }
379418 }
380419
381420 llmod
compiler/rustc_codegen_llvm/src/lib.rs+3-3
......@@ -216,7 +216,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
216216 module: &ModuleCodegen<Self::Module>,
217217 config: &ModuleConfig,
218218 ) -> Result<(), FatalError> {
219 back::write::optimize(cgcx, dcx, module, config)
219 unsafe { back::write::optimize(cgcx, dcx, module, config) }
220220 }
221221 fn optimize_fat(
222222 cgcx: &CodegenContext<Self>,
......@@ -230,7 +230,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
230230 cgcx: &CodegenContext<Self>,
231231 thin: ThinModule<Self>,
232232 ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
233 back::lto::optimize_thin_module(thin, cgcx)
233 unsafe { back::lto::optimize_thin_module(thin, cgcx) }
234234 }
235235 unsafe fn codegen(
236236 cgcx: &CodegenContext<Self>,
......@@ -238,7 +238,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
238238 module: ModuleCodegen<Self::Module>,
239239 config: &ModuleConfig,
240240 ) -> Result<CompiledModule, FatalError> {
241 back::write::codegen(cgcx, dcx, module, config)
241 unsafe { back::write::codegen(cgcx, dcx, module, config) }
242242 }
243243 fn prepare_thin(
244244 module: ModuleCodegen<Self::Module>,
compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs+38-33
......@@ -40,7 +40,7 @@ impl<'ll> OptimizationDiagnostic<'ll> {
4040 let mut filename = None;
4141 let pass_name = super::build_string(|pass_name| {
4242 message = super::build_string(|message| {
43 filename = super::build_string(|filename| {
43 filename = super::build_string(|filename| unsafe {
4444 super::LLVMRustUnpackOptimizationDiagnostic(
4545 di,
4646 pass_name,
......@@ -91,7 +91,7 @@ impl SrcMgrDiagnostic {
9191 let mut ranges = [0; 8];
9292 let mut num_ranges = ranges.len() / 2;
9393 let message = super::build_string(|message| {
94 buffer = super::build_string(|buffer| {
94 buffer = super::build_string(|buffer| unsafe {
9595 have_source = super::LLVMRustUnpackSMDiagnostic(
9696 diag,
9797 message,
......@@ -134,7 +134,9 @@ impl InlineAsmDiagnostic {
134134 let mut message = None;
135135 let mut level = super::DiagnosticLevel::Error;
136136
137 super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
137 unsafe {
138 super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
139 }
138140
139141 InlineAsmDiagnostic {
140142 level,
......@@ -146,7 +148,8 @@ impl InlineAsmDiagnostic {
146148
147149 unsafe fn unpackSrcMgr(di: &DiagnosticInfo) -> Self {
148150 let mut cookie = 0;
149 let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
151 let smdiag =
152 unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
150153 InlineAsmDiagnostic {
151154 level: smdiag.level,
152155 cookie: cookie.into(),
......@@ -170,44 +173,46 @@ pub enum Diagnostic<'ll> {
170173impl<'ll> Diagnostic<'ll> {
171174 pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
172175 use super::DiagnosticKind as Dk;
173 let kind = super::LLVMRustGetDiagInfoKind(di);
174176
175 match kind {
176 Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
177 unsafe {
178 let kind = super::LLVMRustGetDiagInfoKind(di);
179 match kind {
180 Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
177181
178 Dk::OptimizationRemark => {
179 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
180 }
181 Dk::OptimizationRemarkOther => {
182 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
183 }
184 Dk::OptimizationRemarkMissed => {
185 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
186 }
182 Dk::OptimizationRemark => {
183 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
184 }
185 Dk::OptimizationRemarkOther => {
186 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
187 }
188 Dk::OptimizationRemarkMissed => {
189 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
190 }
187191
188 Dk::OptimizationRemarkAnalysis => {
189 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
190 }
192 Dk::OptimizationRemarkAnalysis => {
193 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
194 }
191195
192 Dk::OptimizationRemarkAnalysisFPCommute => {
193 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
194 }
196 Dk::OptimizationRemarkAnalysisFPCommute => {
197 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
198 }
195199
196 Dk::OptimizationRemarkAnalysisAliasing => {
197 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
198 }
200 Dk::OptimizationRemarkAnalysisAliasing => {
201 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
202 }
199203
200 Dk::OptimizationFailure => {
201 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
202 }
204 Dk::OptimizationFailure => {
205 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
206 }
203207
204 Dk::PGOProfile => PGO(di),
205 Dk::Linker => Linker(di),
206 Dk::Unsupported => Unsupported(di),
208 Dk::PGOProfile => PGO(di),
209 Dk::Linker => Linker(di),
210 Dk::Unsupported => Unsupported(di),
207211
208 Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
212 Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
209213
210 _ => UnknownDiagnostic(di),
214 _ => UnknownDiagnostic(di),
215 }
211216 }
212217 }
213218}
compiler/rustc_codegen_llvm/src/llvm_util.rs+10-6
......@@ -49,12 +49,16 @@ unsafe fn configure_llvm(sess: &Session) {
4949 let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
5050 let mut llvm_args = Vec::with_capacity(n_args + 1);
5151
52 llvm::LLVMRustInstallErrorHandlers();
52 unsafe {
53 llvm::LLVMRustInstallErrorHandlers();
54 }
5355 // On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
5456 // box for the purpose of launching a debugger. However, on CI this will
5557 // cause it to hang until it times out, which can take several hours.
5658 if std::env::var_os("CI").is_some() {
57 llvm::LLVMRustDisableSystemDialogsOnCrash();
59 unsafe {
60 llvm::LLVMRustDisableSystemDialogsOnCrash();
61 }
5862 }
5963
6064 fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
......@@ -124,12 +128,12 @@ unsafe fn configure_llvm(sess: &Session) {
124128 }
125129
126130 if sess.opts.unstable_opts.llvm_time_trace {
127 llvm::LLVMRustTimeTraceProfilerInitialize();
131 unsafe { llvm::LLVMRustTimeTraceProfilerInitialize() };
128132 }
129133
130134 rustc_llvm::initialize_available_targets();
131135
132 llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
136 unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) };
133137}
134138
135139pub fn time_trace_profiler_finish(file_name: &Path) {
......@@ -442,8 +446,8 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
442446 let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
443447 .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
444448 unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
445 let out = &mut *(out as *mut &mut String);
446 let bytes = slice::from_raw_parts(string as *const u8, len);
449 let out = unsafe { &mut *(out as *mut &mut String) };
450 let bytes = unsafe { slice::from_raw_parts(string as *const u8, len) };
447451 write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap();
448452 }
449453 unsafe {
compiler/rustc_codegen_llvm/src/mono_item.rs+4-4
......@@ -108,8 +108,8 @@ impl CodegenCx<'_, '_> {
108108 llval: &llvm::Value,
109109 is_declaration: bool,
110110 ) -> bool {
111 let linkage = llvm::LLVMRustGetLinkage(llval);
112 let visibility = llvm::LLVMRustGetVisibility(llval);
111 let linkage = unsafe { llvm::LLVMRustGetLinkage(llval) };
112 let visibility = unsafe { llvm::LLVMRustGetVisibility(llval) };
113113
114114 if matches!(linkage, llvm::Linkage::InternalLinkage | llvm::Linkage::PrivateLinkage) {
115115 return true;
......@@ -145,8 +145,8 @@ impl CodegenCx<'_, '_> {
145145 }
146146
147147 // Thread-local variables generally don't support copy relocations.
148 let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
149 .is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
148 let is_thread_local_var = unsafe { llvm::LLVMIsAGlobalVariable(llval) }
149 .is_some_and(|v| unsafe { llvm::LLVMIsThreadLocal(v) } == llvm::True);
150150 if is_thread_local_var {
151151 return false;
152152 }
compiler/rustc_codegen_ssa/src/back/lto.rs+1-1
......@@ -72,7 +72,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
7272 B::optimize_fat(cgcx, &mut module)?;
7373 Ok(module)
7474 }
75 LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin),
75 LtoModuleCodegen::Thin(thin) => unsafe { B::optimize_thin(cgcx, thin) },
7676 }
7777 }
7878
compiler/rustc_llvm/src/lib.rs+1-1
......@@ -33,7 +33,7 @@ pub unsafe extern "C" fn LLVMRustStringWriteImpl(
3333 ptr: *const c_char,
3434 size: size_t,
3535) {
36 let slice = slice::from_raw_parts(ptr as *const u8, size);
36 let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) };
3737
3838 sr.bytes.borrow_mut().extend_from_slice(slice);
3939}
compiler/rustc_middle/src/ty/context/tls.rs+1-1
......@@ -67,7 +67,7 @@ fn erase(context: &ImplicitCtxt<'_, '_>) -> *const () {
6767
6868#[inline]
6969unsafe fn downcast<'a, 'tcx>(context: *const ()) -> &'a ImplicitCtxt<'a, 'tcx> {
70 &*(context as *const ImplicitCtxt<'a, 'tcx>)
70 unsafe { &*(context as *const ImplicitCtxt<'a, 'tcx>) }
7171}
7272
7373/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
compiler/rustc_middle/src/ty/structural_impls.rs+17-8
......@@ -257,7 +257,6 @@ TrivialTypeTraversalImpls! {
257257 crate::ty::adjustment::PointerCoercion,
258258 ::rustc_span::Span,
259259 ::rustc_span::symbol::Ident,
260 ::rustc_errors::ErrorGuaranteed,
261260 ty::BoundVar,
262261 ty::ValTree<'tcx>,
263262}
......@@ -443,13 +442,14 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
443442 pat.visit_with(visitor)
444443 }
445444
445 ty::Error(guar) => guar.visit_with(visitor),
446
446447 ty::Bool
447448 | ty::Char
448449 | ty::Str
449450 | ty::Int(_)
450451 | ty::Uint(_)
451452 | ty::Float(_)
452 | ty::Error(_)
453453 | ty::Infer(_)
454454 | ty::Bound(..)
455455 | ty::Placeholder(..)
......@@ -602,6 +602,21 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
602602 }
603603}
604604
605impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
606 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
607 visitor.visit_error(*self)
608 }
609}
610
611impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
612 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
613 self,
614 _folder: &mut F,
615 ) -> Result<Self, F::Error> {
616 Ok(self)
617 }
618}
619
605620impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
606621 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
607622 self,
......@@ -617,12 +632,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
617632 }
618633}
619634
620impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
621 fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
622 self.args.visit_with(visitor)
623 }
624}
625
626635impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
627636 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
628637 visitor.visit_ty(self.ty)
compiler/rustc_mir_build/src/build/matches/mod.rs+19-14
......@@ -1547,10 +1547,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15471547 start_block: BasicBlock,
15481548 candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
15491549 ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
1550 // We can't expand or-patterns freely. The rule is: if the candidate has an
1551 // or-pattern as its only remaining match pair, we can expand it freely. If it has
1552 // other match pairs, we can expand it but we can't process more candidates after
1553 // it.
1550 // We can't expand or-patterns freely. The rule is:
1551 // - If a candidate doesn't start with an or-pattern, we include it in
1552 // the expansion list as-is (i.e. it "expands" to itself).
1553 // - If a candidate has an or-pattern as its only remaining match pair,
1554 // we can expand it.
1555 // - If it starts with an or-pattern but also has other match pairs,
1556 // we can expand it, but we can't process more candidates after it.
15541557 //
15551558 // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
15561559 // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
......@@ -1567,17 +1570,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15671570 // }
15681571 // ```
15691572 //
1570 // We therefore split the `candidates` slice in two, expand or-patterns in the first half,
1573 // We therefore split the `candidates` slice in two, expand or-patterns in the first part,
15711574 // and process the rest separately.
1572 let mut expand_until = 0;
1573 for (i, candidate) in candidates.iter().enumerate() {
1574 expand_until = i + 1;
1575 if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
1576 // The candidate has an or-pattern as well as more match pairs: we must
1577 // split the candidates list here.
1578 break;
1579 }
1580 }
1575 let expand_until = candidates
1576 .iter()
1577 .position(|candidate| {
1578 // If a candidate starts with an or-pattern and has more match pairs,
1579 // we can expand it, but we must stop expanding _after_ it.
1580 candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern()
1581 })
1582 .map(|pos| pos + 1) // Stop _after_ the found candidate
1583 .unwrap_or(candidates.len()); // Otherwise, include all candidates
15811584 let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
15821585
15831586 // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
......@@ -1592,6 +1595,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15921595 expanded_candidates.push(subcandidate);
15931596 }
15941597 } else {
1598 // A candidate that doesn't start with an or-pattern has nothing to
1599 // expand, so it is included in the post-expansion list as-is.
15951600 expanded_candidates.push(candidate);
15961601 }
15971602 }
compiler/rustc_span/src/analyze_source_file.rs+58-51
......@@ -35,25 +35,25 @@ pub fn analyze_source_file(
3535
3636cfg_match! {
3737 cfg(any(target_arch = "x86", target_arch = "x86_64")) => {
38 fn analyze_source_file_dispatch(src: &str,
39 lines: &mut Vec<RelativeBytePos>,
40 multi_byte_chars: &mut Vec<MultiByteChar>,
41 non_narrow_chars: &mut Vec<NonNarrowChar>) {
38 fn analyze_source_file_dispatch(
39 src: &str,
40 lines: &mut Vec<RelativeBytePos>,
41 multi_byte_chars: &mut Vec<MultiByteChar>,
42 non_narrow_chars: &mut Vec<NonNarrowChar>,
43 ) {
4244 if is_x86_feature_detected!("sse2") {
4345 unsafe {
44 analyze_source_file_sse2(src,
45 lines,
46 multi_byte_chars,
47 non_narrow_chars);
46 analyze_source_file_sse2(src, lines, multi_byte_chars, non_narrow_chars);
4847 }
4948 } else {
50 analyze_source_file_generic(src,
51 src.len(),
52 RelativeBytePos::from_u32(0),
53 lines,
54 multi_byte_chars,
55 non_narrow_chars);
56
49 analyze_source_file_generic(
50 src,
51 src.len(),
52 RelativeBytePos::from_u32(0),
53 lines,
54 multi_byte_chars,
55 non_narrow_chars,
56 );
5757 }
5858 }
5959
......@@ -62,10 +62,12 @@ cfg_match! {
6262 /// function falls back to the generic implementation. Otherwise it uses
6363 /// SSE2 intrinsics to quickly find all newlines.
6464 #[target_feature(enable = "sse2")]
65 unsafe fn analyze_source_file_sse2(src: &str,
66 lines: &mut Vec<RelativeBytePos>,
67 multi_byte_chars: &mut Vec<MultiByteChar>,
68 non_narrow_chars: &mut Vec<NonNarrowChar>) {
65 unsafe fn analyze_source_file_sse2(
66 src: &str,
67 lines: &mut Vec<RelativeBytePos>,
68 multi_byte_chars: &mut Vec<MultiByteChar>,
69 non_narrow_chars: &mut Vec<NonNarrowChar>,
70 ) {
6971 #[cfg(target_arch = "x86")]
7072 use std::arch::x86::*;
7173 #[cfg(target_arch = "x86_64")]
......@@ -83,17 +85,17 @@ cfg_match! {
8385 // handled it.
8486 let mut intra_chunk_offset = 0;
8587
86 for chunk_index in 0 .. chunk_count {
88 for chunk_index in 0..chunk_count {
8789 let ptr = src_bytes.as_ptr() as *const __m128i;
8890 // We don't know if the pointer is aligned to 16 bytes, so we
8991 // use `loadu`, which supports unaligned loading.
90 let chunk = _mm_loadu_si128(ptr.add(chunk_index));
92 let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) };
9193
9294 // For character in the chunk, see if its byte value is < 0, which
9395 // indicates that it's part of a UTF-8 char.
94 let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
96 let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
9597 // Create a bit mask from the comparison results.
96 let multibyte_mask = _mm_movemask_epi8(multibyte_test);
98 let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
9799
98100 // If the bit mask is all zero, we only have ASCII chars here:
99101 if multibyte_mask == 0 {
......@@ -102,19 +104,19 @@ cfg_match! {
102104 // Check if there are any control characters in the chunk. All
103105 // control characters that we can encounter at this point have a
104106 // byte value less than 32 or ...
105 let control_char_test0 = _mm_cmplt_epi8(chunk, _mm_set1_epi8(32));
106 let control_char_mask0 = _mm_movemask_epi8(control_char_test0);
107 let control_char_test0 = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)) };
108 let control_char_mask0 = unsafe { _mm_movemask_epi8(control_char_test0) };
107109
108110 // ... it's the ASCII 'DEL' character with a value of 127.
109 let control_char_test1 = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127));
110 let control_char_mask1 = _mm_movemask_epi8(control_char_test1);
111 let control_char_test1 = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)) };
112 let control_char_mask1 = unsafe { _mm_movemask_epi8(control_char_test1) };
111113
112114 let control_char_mask = control_char_mask0 | control_char_mask1;
113115
114116 if control_char_mask != 0 {
115117 // Check for newlines in the chunk
116 let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
117 let newlines_mask = _mm_movemask_epi8(newlines_test);
118 let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
119 let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
118120
119121 if control_char_mask == newlines_mask {
120122 // All control characters are newlines, record them
......@@ -126,7 +128,7 @@ cfg_match! {
126128
127129 if index >= CHUNK_SIZE as u32 {
128130 // We have arrived at the end of the chunk.
129 break
131 break;
130132 }
131133
132134 lines.push(RelativeBytePos(index) + output_offset);
......@@ -137,14 +139,14 @@ cfg_match! {
137139
138140 // We are done for this chunk. All control characters were
139141 // newlines and we took care of those.
140 continue
142 continue;
141143 } else {
142144 // Some of the control characters are not newlines,
143145 // fall through to the slow path below.
144146 }
145147 } else {
146148 // No control characters, nothing to record for this chunk
147 continue
149 continue;
148150 }
149151 }
150152
......@@ -152,43 +154,48 @@ cfg_match! {
152154 // There are control chars in here, fallback to generic decoding.
153155 let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset;
154156 intra_chunk_offset = analyze_source_file_generic(
155 &src[scan_start .. ],
157 &src[scan_start..],
156158 CHUNK_SIZE - intra_chunk_offset,
157159 RelativeBytePos::from_usize(scan_start),
158160 lines,
159161 multi_byte_chars,
160 non_narrow_chars
162 non_narrow_chars,
161163 );
162164 }
163165
164166 // There might still be a tail left to analyze
165167 let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset;
166168 if tail_start < src.len() {
167 analyze_source_file_generic(&src[tail_start ..],
168 src.len() - tail_start,
169 RelativeBytePos::from_usize(tail_start),
170 lines,
171 multi_byte_chars,
172 non_narrow_chars);
169 analyze_source_file_generic(
170 &src[tail_start..],
171 src.len() - tail_start,
172 RelativeBytePos::from_usize(tail_start),
173 lines,
174 multi_byte_chars,
175 non_narrow_chars,
176 );
173177 }
174178 }
175179 }
176180 _ => {
177181 // The target (or compiler version) does not support SSE2 ...
178 fn analyze_source_file_dispatch(src: &str,
179 lines: &mut Vec<RelativeBytePos>,
180 multi_byte_chars: &mut Vec<MultiByteChar>,
181 non_narrow_chars: &mut Vec<NonNarrowChar>) {
182 analyze_source_file_generic(src,
183 src.len(),
184 RelativeBytePos::from_u32(0),
185 lines,
186 multi_byte_chars,
187 non_narrow_chars);
182 fn analyze_source_file_dispatch(
183 src: &str,
184 lines: &mut Vec<RelativeBytePos>,
185 multi_byte_chars: &mut Vec<MultiByteChar>,
186 non_narrow_chars: &mut Vec<NonNarrowChar>,
187 ) {
188 analyze_source_file_generic(
189 src,
190 src.len(),
191 RelativeBytePos::from_u32(0),
192 lines,
193 multi_byte_chars,
194 non_narrow_chars,
195 );
188196 }
189197 }
190198}
191
192199// `scan_len` determines the number of bytes in `src` to scan. Note that the
193200// function can read past `scan_len` if a multi-byte character start within the
194201// range but extends past it. The overflow is returned by the function.
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+3-1
......@@ -466,7 +466,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
466466 && let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
467467 {
468468 // Suggest dereferencing the argument to a function/method call if possible
469
470469 let mut real_trait_pred = trait_pred;
471470 while let Some((parent_code, parent_trait_pred)) = code.parent() {
472471 code = parent_code;
......@@ -553,6 +552,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
553552 );
554553 if self.predicate_may_hold(&obligation)
555554 && self.predicate_must_hold_modulo_regions(&sized_obligation)
555 // Do not suggest * if it is already a reference,
556 // will suggest removing the borrow instead in that case.
557 && !matches!(expr.kind, hir::ExprKind::AddrOf(..))
556558 {
557559 let call_node = self.tcx.hir_node(*call_hir_id);
558560 let msg = "consider dereferencing here";
compiler/rustc_type_ir/src/visit.rs+21-24
......@@ -101,8 +101,12 @@ pub trait TypeVisitor<I: Interner>: Sized {
101101
102102 // The default region visitor is a no-op because `Region` is non-recursive
103103 // and has no `super_visit_with` method to call.
104 fn visit_region(&mut self, _r: I::Region) -> Self::Result {
105 Self::Result::output()
104 fn visit_region(&mut self, r: I::Region) -> Self::Result {
105 if let ty::ReError(guar) = r.kind() {
106 self.visit_error(guar)
107 } else {
108 Self::Result::output()
109 }
106110 }
107111
108112 fn visit_const(&mut self, c: I::Const) -> Self::Result {
......@@ -116,6 +120,10 @@ pub trait TypeVisitor<I: Interner>: Sized {
116120 fn visit_clauses(&mut self, p: I::Clauses) -> Self::Result {
117121 p.super_visit_with(self)
118122 }
123
124 fn visit_error(&mut self, _guar: I::ErrorGuaranteed) -> Self::Result {
125 Self::Result::output()
126 }
119127}
120128
121129///////////////////////////////////////////////////////////////////////////
......@@ -439,6 +447,15 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
439447 ControlFlow::Continue(())
440448 }
441449 }
450
451 #[inline]
452 fn visit_error(&mut self, _guar: <I as Interner>::ErrorGuaranteed) -> Self::Result {
453 if self.flags.intersects(TypeFlags::HAS_ERROR) {
454 ControlFlow::Break(FoundFlags)
455 } else {
456 ControlFlow::Continue(())
457 }
458 }
442459}
443460
444461#[derive(Debug, PartialEq, Eq, Copy, Clone)]
......@@ -547,27 +564,7 @@ struct HasErrorVisitor;
547564impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
548565 type Result = ControlFlow<I::ErrorGuaranteed>;
549566
550 fn visit_ty(&mut self, t: <I as Interner>::Ty) -> Self::Result {
551 if let ty::Error(guar) = t.kind() {
552 ControlFlow::Break(guar)
553 } else {
554 t.super_visit_with(self)
555 }
556 }
557
558 fn visit_const(&mut self, c: <I as Interner>::Const) -> Self::Result {
559 if let ty::ConstKind::Error(guar) = c.kind() {
560 ControlFlow::Break(guar)
561 } else {
562 c.super_visit_with(self)
563 }
564 }
565
566 fn visit_region(&mut self, r: <I as Interner>::Region) -> Self::Result {
567 if let ty::ReError(guar) = r.kind() {
568 ControlFlow::Break(guar)
569 } else {
570 ControlFlow::Continue(())
571 }
567 fn visit_error(&mut self, guar: <I as Interner>::ErrorGuaranteed) -> Self::Result {
568 ControlFlow::Break(guar)
572569 }
573570}
library/std/src/sys/pal/teeos/alloc.rs+9-9
......@@ -11,9 +11,9 @@ unsafe impl GlobalAlloc for System {
1111 // Also see <https://github.com/rust-lang/rust/issues/45955> and
1212 // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
1313 if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
14 libc::malloc(layout.size()) as *mut u8
14 unsafe { libc::malloc(layout.size()) as *mut u8 }
1515 } else {
16 aligned_malloc(&layout)
16 unsafe { aligned_malloc(&layout) }
1717 }
1818 }
1919
......@@ -21,11 +21,11 @@ unsafe impl GlobalAlloc for System {
2121 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
2222 // See the comment above in `alloc` for why this check looks the way it does.
2323 if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
24 libc::calloc(layout.size(), 1) as *mut u8
24 unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
2525 } else {
26 let ptr = self.alloc(layout);
26 let ptr = unsafe { self.alloc(layout) };
2727 if !ptr.is_null() {
28 ptr::write_bytes(ptr, 0, layout.size());
28 unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
2929 }
3030 ptr
3131 }
......@@ -33,15 +33,15 @@ unsafe impl GlobalAlloc for System {
3333
3434 #[inline]
3535 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
36 libc::free(ptr as *mut libc::c_void)
36 unsafe { libc::free(ptr as *mut libc::c_void) }
3737 }
3838
3939 #[inline]
4040 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
4141 if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
42 libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
42 unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
4343 } else {
44 realloc_fallback(self, ptr, layout, new_size)
44 unsafe { realloc_fallback(self, ptr, layout, new_size) }
4545 }
4646 }
4747}
......@@ -52,6 +52,6 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
5252 // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
5353 // Since these are all powers of 2, we can just use max.
5454 let align = layout.align().max(crate::mem::size_of::<usize>());
55 let ret = libc::posix_memalign(&mut out, align, layout.size());
55 let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
5656 if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
5757}
library/std/src/sys/pal/teeos/mod.rs+1-1
......@@ -2,7 +2,7 @@
22//!
33//! This module contains the facade (aka platform-specific) implementations of
44//! OS level functionality for Teeos.
5#![allow(unsafe_op_in_unsafe_fn)]
5#![deny(unsafe_op_in_unsafe_fn)]
66#![allow(unused_variables)]
77#![allow(dead_code)]
88
library/std/src/sys/pal/teeos/thread.rs+15-13
......@@ -28,22 +28,24 @@ impl Thread {
2828 // unsafe: see thread::Builder::spawn_unchecked for safety requirements
2929 pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
3030 let p = Box::into_raw(Box::new(p));
31 let mut native: libc::pthread_t = mem::zeroed();
32 let mut attr: libc::pthread_attr_t = mem::zeroed();
33 assert_eq!(libc::pthread_attr_init(&mut attr), 0);
31 let mut native: libc::pthread_t = unsafe { mem::zeroed() };
32 let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() };
33 assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0);
3434 assert_eq!(
35 libc::pthread_attr_settee(
36 &mut attr,
37 libc::TEESMP_THREAD_ATTR_CA_INHERIT,
38 libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT,
39 libc::TEESMP_THREAD_ATTR_HAS_SHADOW,
40 ),
35 unsafe {
36 libc::pthread_attr_settee(
37 &mut attr,
38 libc::TEESMP_THREAD_ATTR_CA_INHERIT,
39 libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT,
40 libc::TEESMP_THREAD_ATTR_HAS_SHADOW,
41 )
42 },
4143 0,
4244 );
4345
4446 let stack_size = cmp::max(stack, min_stack_size(&attr));
4547
46 match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
48 match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } {
4749 0 => {}
4850 n => {
4951 assert_eq!(n, libc::EINVAL);
......@@ -54,7 +56,7 @@ impl Thread {
5456 let page_size = os::page_size();
5557 let stack_size =
5658 (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
57 assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
59 assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0);
5860 }
5961 };
6062
......@@ -62,12 +64,12 @@ impl Thread {
6264 // Note: if the thread creation fails and this assert fails, then p will
6365 // be leaked. However, an alternative design could cause double-free
6466 // which is clearly worse.
65 assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
67 assert_eq!(unsafe { libc::pthread_attr_destroy(&mut attr) }, 0);
6668
6769 return if ret != 0 {
6870 // The thread failed to start and as a result p was not consumed. Therefore, it is
6971 // safe to reconstruct the box so that it gets deallocated.
70 drop(Box::from_raw(p));
72 drop(unsafe { Box::from_raw(p) });
7173 Err(io::Error::from_raw_os_error(ret))
7274 } else {
7375 // The new thread will start running earliest after the next yield.
library/std/src/sys/sync/condvar/teeos.rs+4-4
......@@ -76,16 +76,16 @@ impl Condvar {
7676
7777 #[inline]
7878 pub unsafe fn wait(&self, mutex: &Mutex) {
79 let mutex = mutex::raw(mutex);
79 let mutex = unsafe { mutex::raw(mutex) };
8080 self.verify(mutex);
81 let r = libc::pthread_cond_wait(raw(self), mutex);
81 let r = unsafe { libc::pthread_cond_wait(raw(self), mutex) };
8282 debug_assert_eq!(r, 0);
8383 }
8484
8585 pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
8686 use crate::sys::time::Timespec;
8787
88 let mutex = mutex::raw(mutex);
88 let mutex = unsafe { mutex::raw(mutex) };
8989 self.verify(mutex);
9090
9191 let timeout = Timespec::now(libc::CLOCK_MONOTONIC)
......@@ -93,7 +93,7 @@ impl Condvar {
9393 .and_then(|t| t.to_timespec())
9494 .unwrap_or(TIMESPEC_MAX);
9595
96 let r = pthread_cond_timedwait(raw(self), mutex, &timeout);
96 let r = unsafe { pthread_cond_timedwait(raw(self), mutex, &timeout) };
9797 assert!(r == libc::ETIMEDOUT || r == 0);
9898 r == 0
9999 }
src/bootstrap/src/core/builder.rs+1
......@@ -2001,6 +2001,7 @@ impl<'a> Builder<'a> {
20012001 // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
20022002 // of the individual lints are satisfied.
20032003 rustflags.arg("-Wkeyword_idents_2024");
2004 rustflags.arg("-Wunsafe_op_in_unsafe_fn");
20042005 }
20052006
20062007 if self.config.rust_frame_pointers {
src/tools/run-make-support/Cargo.toml+1-1
......@@ -9,7 +9,7 @@ object = "0.34.0"
99similar = "2.5.0"
1010wasmparser = "0.118.2"
1111regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
12gimli = "0.28.1"
12gimli = "0.31.0"
1313ar = "0.9.0"
1414
1515build_helper = { path = "../build_helper" }
tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs created+18
......@@ -0,0 +1,18 @@
1fn main() {
2 let fields = vec![1];
3 let variant = vec![2];
4
5 // should not suggest `*&variant.iter()`
6 for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
7 //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
8 //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
9 eprintln!("{} {}", src, dest);
10 }
11
12 // don't suggest add `variant.iter().clone().clone()`
13 for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
14 //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
15 //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
16 eprintln!("{} {}", src, dest);
17 }
18}
tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr created+61
......@@ -0,0 +1,61 @@
1error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
2 --> $DIR/invalid-suggest-deref-issue-127590.rs:6:54
3 |
4LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
5 | -------------- ^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
6 | |
7 | required by a bound introduced by this call
8 |
9 = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
10 = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
11note: required by a bound in `std::iter::zip`
12 --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
13help: consider removing the leading `&`-reference
14 |
15LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
16LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter()) {
17 |
18
19error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
20 --> $DIR/invalid-suggest-deref-issue-127590.rs:6:24
21 |
22LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
24 |
25 = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
26 = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
27 = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
28 = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
29
30error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
31 --> $DIR/invalid-suggest-deref-issue-127590.rs:13:54
32 |
33LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
34 | -------------- ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
35 | |
36 | required by a bound introduced by this call
37 |
38 = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
39 = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
40note: required by a bound in `std::iter::zip`
41 --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
42help: consider removing the leading `&`-reference
43 |
44LL - for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
45LL + for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone()) {
46 |
47
48error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
49 --> $DIR/invalid-suggest-deref-issue-127590.rs:13:24
50 |
51LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
52 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
53 |
54 = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
55 = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
56 = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
57 = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
58
59error: aborting due to 4 previous errors
60
61For more information about this error, try `rustc --explain E0277`.