From 3d168c28f61565856f5d4726bf42235346848d5b Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Mon, 23 Sep 2024 15:20:23 +0200 Subject: [PATCH 01/14] Improve assembly test for CMSE ABIs This ensures the code-gen for these ABIs does not change silently. Co-authored-by: Folkert --- tests/assembly/cmse.rs | 86 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/tests/assembly/cmse.rs b/tests/assembly/cmse.rs index acad77b251357..e0ada8dc2f15c 100644 --- a/tests/assembly/cmse.rs +++ b/tests/assembly/cmse.rs @@ -1,6 +1,9 @@ +//@ revisions: hard soft //@ assembly-output: emit-asm -//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1 -//@ needs-llvm-components: arm +//@ [hard] compile-flags: --target thumbv8m.main-none-eabihf --crate-type lib -Copt-level=1 +//@ [soft] compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -Copt-level=1 +//@ [hard] needs-llvm-components: arm +//@ [soft] needs-llvm-components: arm #![crate_type = "lib"] #![feature(abi_c_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items)] #![no_core] @@ -9,15 +12,88 @@ pub trait Sized {} #[lang = "copy"] pub trait Copy {} -// CHECK-LABEL: __acle_se_entry_point -// CHECK: bxns +// CHECK-LABEL: __acle_se_entry_point: +// CHECK-NEXT: entry_point: +// +// Write return argument (two registers since 64bit integer) +// CHECK: movs r0, #0 +// CHECK: movs r1, #0 +// +// If we are using hard-float: +// * Check if the float registers were touched (bit 3 in CONTROL) +// hard: mrs [[REG:r[0-9]+]], control +// hard: tst.w [[REG]], #8 +// hard: beq [[LABEL:[\.a-zA-Z0-9_]+]] +// +// * If touched clear all float registers (d0..=d7) +// hard: vmov d0, +// hard: vmov d1, +// hard: vmov d2, +// hard: vmov d3, +// hard: vmov d4, +// hard: vmov d5, +// hard: vmov d6, +// hard: vmov d7, +// +// * If touched clear FPU status register +// hard: vmrs [[REG:r[0-9]+]], fpscr +// hard: bic [[REG]], [[REG]], #159 +// hard: bic [[REG]], [[REG]], #4026531840 +// hard: vmsr fpscr, [[REG]] +// hard: [[LABEL]]: +// +// Clear all other registers that might have been used +// CHECK: mov r2, +// CHECK: mov r3, +// CHECK: mov r12, +// +// Clear the flags +// CHECK: msr apsr_nzcvq, +// +// Branch back to non-secure side +// CHECK: bxns lr #[no_mangle] pub extern "C-cmse-nonsecure-entry" fn entry_point() -> i64 { 0 } +// NOTE for future codegen changes: +// The specific register assignment is not important, however: +// * all registers must be cleared before `blxns` is executed +// (either by writing arguments or any other value) +// * the lowest bit on the address of the callee must be cleared +// * the flags need to be overwritten +// * `blxns` needs to be called with the callee address +// (with the lowest bit cleared) +// // CHECK-LABEL: call_nonsecure -// CHECK: blxns +// Save callee pointer +// CHECK: mov r12, r0 +// +// All arguments are written to (writes r0..=r3) +// CHECK: movs r0, #0 +// CHECK: movs r1, #1 +// CHECK: movs r2, #2 +// CHECK: movs r3, #3 +// +// Lowest bit gets cleared on callee address +// CHECK: bic r12, r12, #1 +// +// Ununsed registers get cleared (r4..=r11) +// CHECK: mov r4, +// CHECK: mov r5, +// CHECK: mov r6, +// CHECK: mov r7, +// CHECK: mov r8, +// CHECK: mov r9, +// CHECK: mov r10, +// CHECK: mov r11, +// +// Flags get cleared +// CHECK: msr apsr_nzcvq, +// +// Call to non-secure +// CHECK: blxns r12 #[no_mangle] pub fn call_nonsecure( f: unsafe extern "C-cmse-nonsecure-call" fn(u32, u32, u32, u32) -> u64, From cfb8419900c1511b09320d70105128ce13de6e71 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 23 Sep 2024 18:07:42 -0400 Subject: [PATCH 02/14] Separate collection of crate-local inherent impls from error reporting --- .../src/coherence/inherent_impls.rs | 34 ++++---- .../src/coherence/inherent_impls_overlap.rs | 3 +- .../rustc_hir_analysis/src/coherence/mod.rs | 6 +- .../src/hir_ty_lowering/errors.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 1 - compiler/rustc_hir_typeck/src/method/probe.rs | 4 +- .../rustc_hir_typeck/src/method/suggest.rs | 11 +-- .../src/rmeta/decoder/cstore_impl.rs | 4 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +- compiler/rustc_middle/src/query/erase.rs | 6 ++ compiler/rustc_middle/src/query/mod.rs | 14 ++- compiler/rustc_middle/src/ty/trait_def.rs | 20 +---- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 6 +- .../ui/const-generics/wrong-normalization.rs | 1 - .../const-generics/wrong-normalization.stderr | 16 +--- tests/ui/impl-trait/where-allowed.rs | 3 +- tests/ui/impl-trait/where-allowed.stderr | 86 ++++++++----------- tests/ui/traits/incoherent-impl-ambiguity.rs | 14 +++ .../traits/incoherent-impl-ambiguity.stderr | 11 +++ 22 files changed, 127 insertions(+), 125 deletions(-) create mode 100644 tests/ui/traits/incoherent-impl-ambiguity.rs create mode 100644 tests/ui/traits/incoherent-impl-ambiguity.stderr diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c07d8009aa56c..dfb3c088afb0c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -22,36 +22,38 @@ use crate::errors; pub(crate) fn crate_inherent_impls( tcx: TyCtxt<'_>, (): (), -) -> Result<&'_ CrateInherentImpls, ErrorGuaranteed> { +) -> (&'_ CrateInherentImpls, Result<(), ErrorGuaranteed>) { let mut collect = InherentCollect { tcx, impls_map: Default::default() }; + let mut res = Ok(()); for id in tcx.hir().items() { res = res.and(collect.check_item(id)); } - res?; - Ok(tcx.arena.alloc(collect.impls_map)) + + (tcx.arena.alloc(collect.impls_map), res) } -pub(crate) fn crate_incoherent_impls( +pub(crate) fn crate_inherent_impls_validity_check( tcx: TyCtxt<'_>, - simp: SimplifiedType, -) -> Result<&[DefId], ErrorGuaranteed> { - let crate_map = tcx.crate_inherent_impls(())?; - Ok(tcx.arena.alloc_from_iter( + (): (), +) -> Result<(), ErrorGuaranteed> { + tcx.crate_inherent_impls(()).1 +} + +pub(crate) fn crate_incoherent_impls(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { + let (crate_map, _) = tcx.crate_inherent_impls(()); + tcx.arena.alloc_from_iter( crate_map.incoherent_impls.get(&simp).unwrap_or(&Vec::new()).iter().map(|d| d.to_def_id()), - )) + ) } /// On-demand query: yields a vector of the inherent impls for a specific type. -pub(crate) fn inherent_impls( - tcx: TyCtxt<'_>, - ty_def_id: LocalDefId, -) -> Result<&[DefId], ErrorGuaranteed> { - let crate_map = tcx.crate_inherent_impls(())?; - Ok(match crate_map.inherent_impls.get(&ty_def_id) { +pub(crate) fn inherent_impls(tcx: TyCtxt<'_>, ty_def_id: LocalDefId) -> &[DefId] { + let (crate_map, _) = tcx.crate_inherent_impls(()); + match crate_map.inherent_impls.get(&ty_def_id) { Some(v) => &v[..], None => &[], - }) + } } struct InherentCollect<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 43b9093ecac82..b8066b4b47d90 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -177,8 +177,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { return Ok(()); } - let impls = self.tcx.inherent_impls(id.owner_id)?; - + let impls = self.tcx.inherent_impls(id.owner_id); let overlap_mode = OverlapMode::get(self.tcx, id.owner_id.to_def_id()); let impls_items = impls diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 185f3176f0789..b25406583f6c4 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -124,7 +124,10 @@ fn enforce_empty_impls_for_marker_traits( pub(crate) fn provide(providers: &mut Providers) { use self::builtin::coerce_unsized_info; - use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls}; + use self::inherent_impls::{ + crate_incoherent_impls, crate_inherent_impls, crate_inherent_impls_validity_check, + inherent_impls, + }; use self::inherent_impls_overlap::crate_inherent_impls_overlap_check; use self::orphan::orphan_check_impl; @@ -133,6 +136,7 @@ pub(crate) fn provide(providers: &mut Providers) { crate_inherent_impls, crate_incoherent_impls, inherent_impls, + crate_inherent_impls_validity_check, crate_inherent_impls_overlap_check, coerce_unsized_info, orphan_check_impl, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 5e3203e847368..5775a8867b16a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1028,7 +1028,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .. }) = node && let Some(ty_def_id) = qself_ty.ty_def_id() - && let Ok([inherent_impl]) = tcx.inherent_impls(ty_def_id) + && let [inherent_impl] = tcx.inherent_impls(ty_def_id) && let name = format!("{ident2}_{ident3}") && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx .associated_items(inherent_impl) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index e95b5142559f4..d7d4a98e63fe6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1272,7 +1272,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let candidates: Vec<_> = tcx - .inherent_impls(adt_did)? + .inherent_impls(adt_did) .iter() .filter_map(|&impl_| { let (item, scope) = diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1dc85c4903e37..92d85d48a42c0 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -170,7 +170,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _ = tcx.ensure().coherent_trait(trait_def_id); } // these queries are executed for side-effects (error reporting): - let _ = tcx.ensure().crate_inherent_impls(()); + let _ = tcx.ensure().crate_inherent_impls_validity_check(()); let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); }); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 015a728325094..b34ed4640db12 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2126,7 +2126,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(def_id) .into_iter() - .flatten() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. .filter(|item| { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3828b40b88570..1a8afcf003d20 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -728,13 +728,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else { bug!("unexpected incoherent type: {:?}", self_ty) }; - for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter().flatten() { + for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() { self.assemble_inherent_impl_probe(impl_def_id); } } fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) { - let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter().flatten(); + let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter(); for &impl_def_id in impl_def_ids { self.assemble_inherent_impl_probe(impl_def_id); } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index feb47209f5e7b..e03be4f43f73d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -680,7 +680,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .inherent_impls(adt_def.did()) .into_iter() - .flatten() .any(|def_id| self.associated_value(*def_id, item_name).is_some()) } else { false @@ -1438,7 +1437,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(adt.did()) .into_iter() - .flatten() .copied() .filter(|def_id| { if let Some(assoc) = self.associated_value(*def_id, item_name) { @@ -1900,7 +1898,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_args: Option>>, ) -> Option { if let ty::Adt(adt, adt_args) = rcvr_ty.kind() { - for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter().flatten() { + for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter() { for inherent_method in self.tcx.associated_items(inherent_impl_did).in_definition_order() { @@ -2114,9 +2112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty::Adt(adt_def, _) = rcvr_ty.kind() else { return; }; - // FIXME(oli-obk): try out bubbling this error up one level and cancelling the other error in that case. - let Ok(impls) = self.tcx.inherent_impls(adt_def.did()) else { return }; - let mut items = impls + let mut items = self + .tcx + .inherent_impls(adt_def.did()) .iter() .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers and only if @@ -2495,7 +2493,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .and_then(|simp| { tcx.incoherent_impls(simp) .into_iter() - .flatten() .find_map(|&id| self.associated_value(id, item_name)) }) .is_some() diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 53d2089296d94..69707fdbe8fa1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -347,7 +347,7 @@ provide! { tcx, def_id, other, cdata, tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) } associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } - inherent_impls => { Ok(cdata.get_inherent_implementations_for_type(tcx, def_id.index)) } + inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } is_mir_available => { cdata.is_item_mir_available(def_id.index) } is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } @@ -393,7 +393,7 @@ provide! { tcx, def_id, other, cdata, traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) } trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } - crate_incoherent_impls => { Ok(cdata.get_incoherent_impls(tcx, other)) } + crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } dep_kind => { cdata.dep_kind } module_children => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 891f179344181..5f756672b049e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1540,7 +1540,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - for (def_id, impls) in &tcx.crate_inherent_impls(()).unwrap().inherent_impls { + for (def_id, impls) in &tcx.crate_inherent_impls(()).0.inherent_impls { record_defaulted_array!(self.tables.inherent_impls[def_id.to_def_id()] <- impls.iter().map(|def_id| { assert!(def_id.is_local()); def_id.index @@ -2089,7 +2089,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let all_impls: Vec<_> = tcx .crate_inherent_impls(()) - .unwrap() + .0 .incoherent_impls .iter() .map(|(&simp, impls)| IncoherentImpls { diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index bd20e6aa00537..48bf4ffced0ce 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -1,6 +1,8 @@ use std::intrinsics::transmute_unchecked; use std::mem::MaybeUninit; +use rustc_span::ErrorGuaranteed; + use crate::query::CyclePlaceholder; use crate::ty::adjustment::CoerceUnsizedInfo; use crate::ty::{self, Ty}; @@ -216,6 +218,10 @@ impl EraseType for (&'_ T0, &'_ [T1]) { type Result = [u8; size_of::<(&'static (), &'static [()])>()]; } +impl EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) { + type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()]; +} + macro_rules! trivial { ($($ty:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 00036097ef50e..9609ef46d5c31 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -881,13 +881,13 @@ rustc_queries! { /// Maps a `DefId` of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. - query inherent_impls(key: DefId) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query inherent_impls(key: DefId) -> &'tcx [DefId] { desc { |tcx| "collecting inherent impls for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - query incoherent_impls(key: SimplifiedType) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query incoherent_impls(key: SimplifiedType) -> &'tcx [DefId] { desc { |tcx| "collecting all inherent impls for `{:?}`", key } } @@ -1017,8 +1017,14 @@ rustc_queries! { /// Gets a complete map from all types to their inherent impls. /// Not meant to be used directly outside of coherence. - query crate_inherent_impls(k: ()) -> Result<&'tcx CrateInherentImpls, ErrorGuaranteed> { + query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { desc { "finding all inherent impls defined in crate" } + } + + /// Checks all types in the crate for overlap in their inherent impls. Reports errors. + /// Not meant to be used directly outside of coherence. + query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { + desc { "check for inherent impls that should not be defined in crate" } ensure_forwards_result_if_red } @@ -1715,7 +1721,7 @@ rustc_queries! { /// /// Do not call this directly, but instead use the `incoherent_impls` query. /// This query is only used to get the data necessary for that query. - query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> Result<&'tcx [DefId], ErrorGuaranteed> { + query crate_incoherent_impls(key: (CrateNum, SimplifiedType)) -> &'tcx [DefId] { desc { |tcx| "collecting all impls for a type in a crate" } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 82690f70e5f18..188107e5d5498 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -253,30 +253,16 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } /// Query provider for `incoherent_impls`. -pub(super) fn incoherent_impls_provider( - tcx: TyCtxt<'_>, - simp: SimplifiedType, -) -> Result<&[DefId], ErrorGuaranteed> { +pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { let mut impls = Vec::new(); - - let mut res = Ok(()); for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) { - let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) { - Ok(impls) => impls, - Err(e) => { - res = Err(e); - continue; - } - }; - for &impl_def_id in incoherent_impls { + for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) { impls.push(impl_def_id) } } - debug!(?impls); - res?; - Ok(tcx.arena.alloc_slice(&impls)) + tcx.arena.alloc_slice(&impls) } pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8d137b8d8f9f1..ee6b56ca753d5 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1183,7 +1183,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt } fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option { - for impl_def_id in tcx.inherent_impls(def_id).ok()? { + for impl_def_id in tcx.inherent_impls(def_id) { if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind( tcx, fn_ident, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 7ea057c7b4bcb..35d166e8b4ab3 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1825,10 +1825,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Doing analysis on local `DefId`s would cause infinite recursion. return; } - let Ok(impls) = self.r.tcx.inherent_impls(def_id) else { return }; // Look at all the associated functions without receivers in the type's // inherent impls to look for builders that return `Self` - let mut items = impls + let mut items = self + .r + .tcx + .inherent_impls(def_id) .iter() .flat_map(|i| self.r.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. diff --git a/tests/ui/const-generics/wrong-normalization.rs b/tests/ui/const-generics/wrong-normalization.rs index 8b2323e3d479c..f1ce317b3f78b 100644 --- a/tests/ui/const-generics/wrong-normalization.rs +++ b/tests/ui/const-generics/wrong-normalization.rs @@ -15,6 +15,5 @@ pub struct I8; impl as Identity>::Identity { //~^ ERROR no nominal type found for inherent implementation -//~| ERROR no associated item named `MIN` found for type `i8` pub fn foo(&self) {} } diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr index 379a5593dd640..2f8dfc895b279 100644 --- a/tests/ui/const-generics/wrong-normalization.stderr +++ b/tests/ui/const-generics/wrong-normalization.stderr @@ -6,18 +6,6 @@ LL | impl as Identity>::Identity { | = note: either implement a trait on it or create a newtype to wrap it instead -error[E0599]: no associated item named `MIN` found for type `i8` in the current scope - --> $DIR/wrong-normalization.rs:16:15 - | -LL | impl as Identity>::Identity { - | ^^^ associated item not found in `i8` - | -help: you are looking for the module in `std`, not the primitive type - | -LL | impl as Identity>::Identity { - | +++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0118, E0599. -For more information about an error, try `rustc --explain E0118`. +For more information about this error, try `rustc --explain E0118`. diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs index 72ce617693e40..3f435f0f443b4 100644 --- a/tests/ui/impl-trait/where-allowed.rs +++ b/tests/ui/impl-trait/where-allowed.rs @@ -42,7 +42,7 @@ fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } //~^ ERROR `impl Trait` is not allowed in the parameters of `Fn` trait bounds -// Allowed +// Allowed (but it's still ambiguous; nothing constrains the RPIT in this body). fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } //~^ ERROR: type annotations needed @@ -79,7 +79,6 @@ fn in_impl_Trait_in_parameters(_: impl Iterator) { panic!( // Allowed fn in_impl_Trait_in_return() -> impl IntoIterator { vec![vec![0; 10], vec![12; 7], vec![8; 3]] - //~^ ERROR: no function or associated item named `into_vec` found for slice `[_]` } // Disallowed diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 1fb69db98c162..2770a6cc40e59 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | outer `impl Trait` error[E0658]: `impl Trait` in associated types is unstable - --> $DIR/where-allowed.rs:122:16 + --> $DIR/where-allowed.rs:121:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | type Out = impl Debug; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:159:23 + --> $DIR/where-allowed.rs:158:23 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | type InTypeAlias = impl Debug; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:162:39 + --> $DIR/where-allowed.rs:161:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -143,7 +143,7 @@ LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in field types - --> $DIR/where-allowed.rs:86:32 + --> $DIR/where-allowed.rs:85:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ @@ -151,7 +151,7 @@ LL | struct InBraceStructField { x: impl Debug } = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in field types - --> $DIR/where-allowed.rs:90:41 + --> $DIR/where-allowed.rs:89:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ @@ -159,7 +159,7 @@ LL | struct InAdtInBraceStructField { x: Vec } = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in field types - --> $DIR/where-allowed.rs:94:27 + --> $DIR/where-allowed.rs:93:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | struct InTupleStructField(impl Debug); = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in field types - --> $DIR/where-allowed.rs:99:25 + --> $DIR/where-allowed.rs:98:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | InBraceVariant { x: impl Debug }, = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in field types - --> $DIR/where-allowed.rs:101:20 + --> $DIR/where-allowed.rs:100:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ @@ -183,7 +183,7 @@ LL | InTupleVariant(impl Debug), = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `extern fn` parameters - --> $DIR/where-allowed.rs:143:33 + --> $DIR/where-allowed.rs:142:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ @@ -191,7 +191,7 @@ LL | fn in_foreign_parameters(_: impl Debug); = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `extern fn` return types - --> $DIR/where-allowed.rs:146:31 + --> $DIR/where-allowed.rs:145:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | fn in_foreign_return() -> impl Debug; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/where-allowed.rs:162:39 + --> $DIR/where-allowed.rs:161:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -207,7 +207,7 @@ LL | type InReturnInTypeAlias = fn() -> impl Debug; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in traits - --> $DIR/where-allowed.rs:167:16 + --> $DIR/where-allowed.rs:166:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ @@ -215,7 +215,7 @@ LL | impl PartialEq for () { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:172:24 + --> $DIR/where-allowed.rs:171:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | impl PartialEq<()> for impl Debug { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:177:6 + --> $DIR/where-allowed.rs:176:6 | LL | impl impl Debug { | ^^^^^^^^^^ @@ -231,7 +231,7 @@ LL | impl impl Debug { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in impl headers - --> $DIR/where-allowed.rs:183:24 + --> $DIR/where-allowed.rs:182:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ @@ -239,7 +239,7 @@ LL | impl InInherentImplAdt { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:189:11 + --> $DIR/where-allowed.rs:188:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | where impl Debug: Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:196:15 + --> $DIR/where-allowed.rs:195:15 | LL | where Vec: Debug | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | where Vec: Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in bounds - --> $DIR/where-allowed.rs:203:24 + --> $DIR/where-allowed.rs:202:24 | LL | where T: PartialEq | ^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | where T: PartialEq = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds - --> $DIR/where-allowed.rs:210:17 + --> $DIR/where-allowed.rs:209:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | where T: Fn(impl Debug) = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds - --> $DIR/where-allowed.rs:217:22 + --> $DIR/where-allowed.rs:216:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | where T: Fn() -> impl Debug = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:223:40 + --> $DIR/where-allowed.rs:222:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | struct InStructGenericParamDefault(T); = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:227:36 + --> $DIR/where-allowed.rs:226:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | enum InEnumGenericParamDefault { Variant(T) } = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:231:38 + --> $DIR/where-allowed.rs:230:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ @@ -303,7 +303,7 @@ LL | trait InTraitGenericParamDefault {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:235:41 + --> $DIR/where-allowed.rs:234:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ @@ -311,7 +311,7 @@ LL | type InTypeAliasGenericParamDefault = T; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:239:11 + --> $DIR/where-allowed.rs:238:11 | LL | impl T {} | ^^^^^^^^^^ @@ -319,7 +319,7 @@ LL | impl T {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in generic parameter defaults - --> $DIR/where-allowed.rs:246:40 + --> $DIR/where-allowed.rs:245:40 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^ @@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default(_: T) {} = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/where-allowed.rs:252:29 + --> $DIR/where-allowed.rs:251:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ @@ -335,7 +335,7 @@ LL | let _in_local_variable: impl Fn() = || {}; = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in closure return types - --> $DIR/where-allowed.rs:254:46 + --> $DIR/where-allowed.rs:253:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ @@ -363,7 +363,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:239:7 + --> $DIR/where-allowed.rs:238:7 | LL | impl T {} | ^^^^^^^^^^^^^^ @@ -373,25 +373,15 @@ LL | impl T {} = note: `#[deny(invalid_type_param_default)]` on by default error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:239:1 + --> $DIR/where-allowed.rs:238:1 | LL | impl T {} | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead -error[E0599]: no function or associated item named `into_vec` found for slice `[_]` in the current scope - --> $DIR/where-allowed.rs:81:5 - | -LL | vec![vec![0; 10], vec![12; 7], vec![8; 3]] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `[_]` - | -help: there is an associated function `to_vec` with a similar name - --> $SRC_DIR/alloc/src/slice.rs:LL:COL - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - error[E0053]: method `in_trait_impl_return` has an incompatible type for trait - --> $DIR/where-allowed.rs:129:34 + --> $DIR/where-allowed.rs:128:34 | LL | type Out = impl Debug; | ---------- the expected opaque type @@ -400,7 +390,7 @@ LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ expected opaque type, found a different opaque type | note: type in trait - --> $DIR/where-allowed.rs:119:34 + --> $DIR/where-allowed.rs:118:34 | LL | fn in_trait_impl_return() -> Self::Out; | ^^^^^^^^^ @@ -413,7 +403,7 @@ LL | fn in_trait_impl_return() -> <() as DummyTrait>::Out { () } | ~~~~~~~~~~~~~~~~~~~~~~~ error: unconstrained opaque type - --> $DIR/where-allowed.rs:122:16 + --> $DIR/where-allowed.rs:121:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ @@ -421,7 +411,7 @@ LL | type Out = impl Debug; = note: `Out` must be used in combination with a concrete type within the same impl error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:246:36 + --> $DIR/where-allowed.rs:245:36 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^^^^^ @@ -429,13 +419,13 @@ LL | fn in_method_generic_param_default(_: T) {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36887 -error: aborting due to 50 previous errors +error: aborting due to 49 previous errors -Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0599, E0658, E0666. +Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666. For more information about an error, try `rustc --explain E0053`. Future incompatibility report: Future breakage diagnostic: error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:239:7 + --> $DIR/where-allowed.rs:238:7 | LL | impl T {} | ^^^^^^^^^^^^^^ @@ -446,7 +436,7 @@ LL | impl T {} Future breakage diagnostic: error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:246:36 + --> $DIR/where-allowed.rs:245:36 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/incoherent-impl-ambiguity.rs b/tests/ui/traits/incoherent-impl-ambiguity.rs new file mode 100644 index 0000000000000..b5fed95e11c44 --- /dev/null +++ b/tests/ui/traits/incoherent-impl-ambiguity.rs @@ -0,0 +1,14 @@ +// Make sure that an invalid inherent impl doesn't totally clobber all of the +// other inherent impls, which lead to mysterious method/assoc-item probing errors. + +impl () {} +//~^ ERROR cannot define inherent `impl` for primitive types + +struct W; +impl W { + const CONST: u32 = 0; +} + +fn main() { + let _ = W::CONST; +} diff --git a/tests/ui/traits/incoherent-impl-ambiguity.stderr b/tests/ui/traits/incoherent-impl-ambiguity.stderr new file mode 100644 index 0000000000000..9c050a7295581 --- /dev/null +++ b/tests/ui/traits/incoherent-impl-ambiguity.stderr @@ -0,0 +1,11 @@ +error[E0390]: cannot define inherent `impl` for primitive types + --> $DIR/incoherent-impl-ambiguity.rs:4:1 + | +LL | impl () {} + | ^^^^^^^ + | + = help: consider using an extension trait instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0390`. From 28f69805de661551d3bba35bd2c6df96777e2df2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 24 Sep 2024 10:11:23 -0400 Subject: [PATCH 03/14] Fix tools --- src/librustdoc/clean/inline.rs | 4 ++-- src/librustdoc/clean/types.rs | 4 ++-- src/librustdoc/passes/collect_intra_doc_links.rs | 1 - src/tools/clippy/clippy_lints/src/derive.rs | 1 - src/tools/clippy/clippy_lints/src/inherent_impl.rs | 4 +--- src/tools/clippy/clippy_lints/src/len_zero.rs | 3 +-- src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs | 1 - src/tools/clippy/clippy_utils/src/lib.rs | 8 ++------ src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 9 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 701bf61809673..b7d6b3dda72b4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -373,7 +373,7 @@ pub(crate) fn build_impls( let tcx = cx.tcx; // for each implementation of an item represented by `did`, build the clean::Item for that impl - for &did in tcx.inherent_impls(did).into_iter().flatten() { + for &did in tcx.inherent_impls(did).into_iter() { cx.with_param_env(did, |cx| { build_impl(cx, did, attrs, ret); }); @@ -388,7 +388,7 @@ pub(crate) fn build_impls( if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) { let type_ = if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) }; - for &did in tcx.incoherent_impls(type_).into_iter().flatten() { + for &did in tcx.incoherent_impls(type_).into_iter() { cx.with_param_env(did, |cx| { build_impl(cx, did, attrs, ret); }); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 31710bc014af4..986406c1e403a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1863,7 +1863,7 @@ impl PrimitiveType { .get(self) .into_iter() .flatten() - .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten()) + .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter()) .copied() } @@ -1871,7 +1871,7 @@ impl PrimitiveType { Self::simplified_types() .values() .flatten() - .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter().flatten()) + .flat_map(move |&simp| tcx.incoherent_impls(simp).into_iter()) .copied() } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index ddc80ea7cb128..29342dcac592b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -608,7 +608,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let mut assoc_items: Vec<_> = tcx .inherent_impls(did) .into_iter() - .flatten() .flat_map(|&imp| { filter_assoc_items_by_name_and_namespace( tcx, diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 636698e96f6d1..649c480fb92a1 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -386,7 +386,6 @@ fn check_unsafe_derive_deserialize<'tcx>( .tcx .inherent_impls(def.did()) .into_iter() - .flatten() .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index d39f910f9936d..309d2dfb28b87 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -51,9 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { // List of spans to lint. (lint_span, first_span) let mut lint_spans = Vec::new(); - let Ok(impls) = cx.tcx.crate_inherent_impls(()) else { - return; - }; + let (impls, _) = cx.tcx.crate_inherent_impls(()); for (&id, impl_ids) in &impls.inherent_impls { if impl_ids.len() < 2 diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 0bc7fc2dd9d1e..16f86b18e2e55 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -448,7 +448,6 @@ fn check_for_is_empty( .tcx .inherent_impls(impl_ty) .into_iter() - .flatten() .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty)) .find(|item| item.kind == AssocKind::Fn); @@ -616,7 +615,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// Checks the inherent impl's items for an `is_empty(self)` method. fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool { let is_empty = sym!(is_empty); - cx.tcx.inherent_impls(id).into_iter().flatten().any(|imp| { + cx.tcx.inherent_impls(id).into_iter().any(|imp| { cx.tcx .associated_items(*imp) .filter_by_name_unhygienic(is_empty) diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index e4326cb958e5f..af71799f0a731 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -78,7 +78,6 @@ pub(super) fn check<'tcx>( cx.tcx .inherent_impls(adt_def.did()) .into_iter() - .flatten() .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) .find_map(|assoc| { if assoc.fn_has_self_parameter diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 0d0d6219c5e05..aed0bc565d8e9 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -589,14 +589,11 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator SimplifiedType::Float(FloatTy::F32), "f64" => SimplifiedType::Float(FloatTy::F64), _ => { - return Result::<&[_], rustc_errors::ErrorGuaranteed>::Ok(&[]) - .into_iter() - .flatten() - .copied(); + return [].iter().copied(); }, }; - tcx.incoherent_impls(ty).into_iter().flatten().copied() + tcx.incoherent_impls(ty).into_iter().copied() } fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec { @@ -721,7 +718,6 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec { let inherent_impl_children = tcx .inherent_impls(def_id) .into_iter() - .flatten() .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment)); let direct_children = item_children_by_name(tcx, def_id, segment); diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 585134209ca3a..22aaaa1b73419 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -1316,7 +1316,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl /// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`. pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> { if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) { - cx.tcx.inherent_impls(ty_did).into_iter().flatten().find_map(|&did| { + cx.tcx.inherent_impls(ty_did).into_iter().find_map(|&did| { cx.tcx .associated_items(did) .filter_by_name_unhygienic(method_name) From e95d15a11519f0fe3d83f39feb71625a81be4249 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 26 Aug 2024 14:56:18 -0400 Subject: [PATCH 04/14] Pin memchr to 2.5.0 in the library rather than rustc_ast The latest versions of `memchr` experience LTO-related issues when compiling for windows-gnu [1], so needs to be pinned. The issue is present in the standard library. `memchr` has been pinned in `rustc_ast`, but since the workspace was recently split, this pin no longer has any effect on library crates. Resolve this by adding `memchr` as an _unused_ dependency in `std`, pinned to 2.5. Additionally, remove the pin in `rustc_ast` to allow non-library crates to upgrade to the latest version. Link: https://github.com/rust-lang/rust/issues/127890 [1] --- Cargo.lock | 4 ++-- compiler/rustc_ast/Cargo.toml | 3 +-- library/Cargo.lock | 1 + library/std/Cargo.toml | 4 ++++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e973d7f9a2ae0..47ad7ab3e9814 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2177,9 +2177,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index d33f9666b484c..34c612dac692b 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -4,10 +4,9 @@ version = "0.0.0" edition = "2021" [dependencies] -# FIXME: bumping memchr to 2.7.1 causes linker errors in MSVC thin-lto # tidy-alphabetical-start bitflags = "2.4.1" -memchr = "=2.5.0" +memchr = "2.7.4" rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } diff --git a/library/Cargo.lock b/library/Cargo.lock index ded30dd82f7b4..2343b2baf8347 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -326,6 +326,7 @@ dependencies = [ "hashbrown", "hermit-abi", "libc", + "memchr", "miniz_oxide", "object", "panic_abort", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 9a31fd21dc71a..ea11586f9a519 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -23,6 +23,10 @@ unwind = { path = "../unwind" } hashbrown = { version = "0.14", default-features = false, features = [ 'rustc-dep-of-std', ] } +# FIXME(#127890): `object` depends on `memchr`, but `memchr` > v2.5 causes +# issues with LTO. This dependency is not used directly, but pin it here so +# it resolves to 2.5. To be removed once rust-lang/rust#127890 is fixed. +memchr = { version = "=2.5.0", default-features = false, features = ["rustc-dep-of-std"] } std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = [ 'rustc-dep-of-std', ] } From 50729fe6ca20721c81bea279512124507256ee89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Tue, 24 Sep 2024 17:02:47 +0000 Subject: [PATCH 05/14] Mention `COMPILETEST_VERBOSE_CRASHES` on crash test failure --- src/tools/compiletest/src/runtest/crash.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tools/compiletest/src/runtest/crash.rs b/src/tools/compiletest/src/runtest/crash.rs index 7f2bec4949be7..885ed3b08faca 100644 --- a/src/tools/compiletest/src/runtest/crash.rs +++ b/src/tools/compiletest/src/runtest/crash.rs @@ -15,10 +15,11 @@ impl TestCx<'_> { // if a test does not crash, consider it an error if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) { self.fatal(&format!( - "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name, \ - add a doc-comment to the start of the test explaining why it exists and \ - move it to tests/ui or wherever you see fit. Adding 'Fixes #' to your PR description \ - ensures that the corresponding ticket is auto-closed upon merge." + "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful \ + name, add a doc-comment to the start of the test explaining why it exists and \ + move it to tests/ui or wherever you see fit. Adding 'Fixes #' to your PR \ + description ensures that the corresponding ticket is auto-closed upon merge. \ + If you want to see verbose output, set `COMPILETEST_VERBOSE_CRASHES=1`." )); } } From 46fd76e9a5687dc7ac6bfad1c715ceaef9e8cf29 Mon Sep 17 00:00:00 2001 From: Aviram Hassan Date: Tue, 24 Sep 2024 18:52:54 +0300 Subject: [PATCH 06/14] add InProgress ErrorKind gated behind io_error_inprogress feature Co-authored-by: David Tolnay Co-authored-by: nora <48135649+Noratrieb@users.noreply.github.com> --- library/std/src/io/error.rs | 6 ++++++ library/std/src/io/error/repr_bitpacked.rs | 1 + library/std/src/sys/pal/unix/mod.rs | 1 + 3 files changed, 8 insertions(+) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 6ecd9469c1740..795cc64e957da 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -400,6 +400,11 @@ pub enum ErrorKind { #[stable(feature = "out_of_memory_error", since = "1.54.0")] OutOfMemory, + /// The operation was partially successful and needs to be checked + /// later on due to not blocking. + #[unstable(feature = "io_error_inprogress", issue = "none")] + InProgress, + // "Unusual" error kinds which do not correspond simply to (sets // of) OS error codes, should be added just above this comment. // `Other` and `Uncategorized` should remain at the end: @@ -449,6 +454,7 @@ impl ErrorKind { FilesystemQuotaExceeded => "filesystem quota exceeded", HostUnreachable => "host unreachable", Interrupted => "operation interrupted", + InProgress => "in progress", InvalidData => "invalid data", InvalidFilename => "invalid filename", InvalidInput => "invalid input parameter", diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index 9d3ade46bd929..80ba8455df347 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -348,6 +348,7 @@ fn kind_from_prim(ek: u32) -> Option { UnexpectedEof, Unsupported, OutOfMemory, + InProgress, Uncategorized, }) } diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 1c9159e5fba86..0d63b1119d59a 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -279,6 +279,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::ETIMEDOUT => TimedOut, libc::ETXTBSY => ExecutableFileBusy, libc::EXDEV => CrossesDevices, + libc::EINPROGRESS => InProgress, libc::EACCES | libc::EPERM => PermissionDenied, From 2fdeb3b8f4cb91eb545880cc0b5db003ef4869b7 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 24 Sep 2024 20:17:52 +0200 Subject: [PATCH 07/14] rustdoc: inherit parent's stability where applicable --- compiler/rustc_attr/src/builtin.rs | 2 +- src/librustdoc/clean/types.rs | 40 +++++++++++++++++++++++++++++- tests/rustdoc/const-display.rs | 18 +++++++++----- tests/rustdoc/stability.rs | 31 ++++++++++++++++++++++- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index dcc4cf2478f33..762ebc47ca9d0 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -153,7 +153,7 @@ pub enum StabilityLevel { } /// Rust release in which a feature is stabilized. -#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] +#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)] #[derive(HashStable_Generic)] pub enum StableSince { Version(RustcVersion), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 31710bc014af4..a0f44d152b246 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -384,7 +384,45 @@ fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { impl Item { pub(crate) fn stability(&self, tcx: TyCtxt<'_>) -> Option { - self.def_id().and_then(|did| tcx.lookup_stability(did)) + let (mut def_id, mut stability) = if let Some(inlined) = self.inline_stmt_id { + let inlined_def_id = inlined.to_def_id(); + if let Some(stability) = tcx.lookup_stability(inlined_def_id) { + (inlined_def_id, stability) + } else { + // For re-exports into crates without `staged_api`, reuse the original stability. + // This is necessary, because we always want to mark unstable items. + let def_id = self.def_id()?; + return tcx.lookup_stability(def_id); + } + } else { + let def_id = self.def_id()?; + let stability = tcx.lookup_stability(def_id)?; + (def_id, stability) + }; + + let StabilityLevel::Stable { mut since, allowed_through_unstable_modules: false } = + stability.level + else { + return Some(stability); + }; + + // If any of the item's ancestors was stabilized later or is still unstable, + // then report the ancestor's stability instead. + while let Some(parent_def_id) = tcx.opt_parent(def_id) { + if let Some(parent_stability) = tcx.lookup_stability(parent_def_id) { + match parent_stability.level { + StabilityLevel::Unstable { .. } => return Some(parent_stability), + StabilityLevel::Stable { since: parent_since, .. } => { + if parent_since > since { + stability = parent_stability; + since = parent_since; + } + } + } + } + def_id = parent_def_id; + } + Some(stability) } pub(crate) fn const_stability(&self, tcx: TyCtxt<'_>) -> Option { diff --git a/tests/rustdoc/const-display.rs b/tests/rustdoc/const-display.rs index ac55a6302f785..a71825d883d6a 100644 --- a/tests/rustdoc/const-display.rs +++ b/tests/rustdoc/const-display.rs @@ -1,8 +1,6 @@ #![crate_name = "foo"] -#![unstable(feature = "humans", - reason = "who ever let humans program computers, we're apparently really bad at it", - issue = "none")] +#![stable(feature = "rust1", since = "1.0.0")] #![feature(foo, foo2)] #![feature(staged_api)] @@ -48,10 +46,18 @@ pub const unsafe fn foo2_gated() -> u32 { 42 } #[rustc_const_stable(feature = "rust1", since = "1.0.0")] pub const unsafe fn bar2_gated() -> u32 { 42 } -//@ has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32' -//@ !hasraw - '//span[@class="since"]' -pub const unsafe fn bar_not_gated() -> u32 { 42 } +#[unstable( + feature = "humans", + reason = "who ever let humans program computers, we're apparently really bad at it", + issue = "none", +)] +pub mod unstable { + //@ has 'foo/unstable/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32' + //@ !hasraw - '//span[@class="since"]' + pub const unsafe fn bar_not_gated() -> u32 { 42 } +} +#[stable(feature = "rust1", since = "1.0.0")] pub struct Foo; impl Foo { diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs index 270da822c009b..de855b43ba538 100644 --- a/tests/rustdoc/stability.rs +++ b/tests/rustdoc/stability.rs @@ -1,6 +1,6 @@ #![feature(staged_api)] -#![unstable(feature = "test", issue = "none")] +#![stable(feature = "rust1", since = "1.0.0")] //@ has stability/index.html //@ has - '//ul[@class="item-table"]/li[1]//a' AaStable @@ -10,6 +10,7 @@ #[stable(feature = "rust2", since = "2.2.2")] pub struct AaStable; +#[unstable(feature = "test", issue = "none")] pub struct Unstable { //@ has stability/struct.Unstable.html \ // '//span[@class="item-info"]//div[@class="stab unstable"]' \ @@ -21,3 +22,31 @@ pub struct Unstable { #[stable(feature = "rust2", since = "2.2.2")] pub struct ZzStable; + +#[unstable(feature = "unstable", issue = "none")] +pub mod unstable { + //@ !hasraw stability/unstable/struct.Foo.html '//span[@class="since"]' + //@ has - '//div[@class="stab unstable"]' 'experimental' + #[stable(feature = "rust1", since = "1.0.0")] + pub struct Foo; +} + +#[stable(feature = "rust2", since = "2.2.2")] +pub mod stable_later { + //@ has stability/stable_later/struct.Bar.html '//span[@class="since"]' '2.2.2' + #[stable(feature = "rust1", since = "1.0.0")] + pub struct Bar; +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub mod stable_earlier { + //@ has stability/stable_earlier/struct.Foo.html '//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::unstable::Foo; + + //@ has stability/stable_earlier/struct.Bar.html '//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::stable_later::Bar; +} From 46ecb23198fa83136a266cb5a18675d2d342ab18 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 15 Sep 2024 16:47:42 +0200 Subject: [PATCH 08/14] unify dyn* coercions with other pointer coercions --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/base.rs | 6 ++++- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- .../src/check_consts/check.rs | 12 +++++----- .../rustc_const_eval/src/interpret/cast.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 22 +++++++++---------- compiler/rustc_hir_typeck/src/coercion.rs | 5 ++++- .../rustc_hir_typeck/src/expr_use_visitor.rs | 7 ++---- compiler/rustc_middle/src/mir/statement.rs | 1 - compiler/rustc_middle/src/mir/syntax.rs | 2 -- compiler/rustc_middle/src/ty/adjustment.rs | 6 ++--- compiler/rustc_middle/src/ty/cast.rs | 6 ----- compiler/rustc_mir_build/src/thir/cx/expr.rs | 1 - .../src/mentioned_items.rs | 6 ++--- compiler/rustc_mir_transform/src/validate.rs | 6 ++--- compiler/rustc_monomorphize/src/collector.rs | 6 ++--- .../rustc_smir/src/rustc_smir/convert/mir.rs | 3 ++- .../rustc_smir/src/rustc_smir/convert/ty.rs | 1 + compiler/stable_mir/src/mir/body.rs | 1 + .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- tests/ui/dyn-star/dyn-to-rigid.rs | 2 +- tests/ui/dyn-star/dyn-to-rigid.stderr | 6 ++--- tests/ui/dyn-star/enum-cast.rs | 18 +++++++++++++++ 23 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 tests/ui/dyn-star/enum-cast.rs diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4056b42354898..29a0c5bdf572f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2139,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - CastKind::DynStar => { + CastKind::PointerCoercion(PointerCoercion::DynStar) => { // get the constraints from the target type (`dyn* Clone`) // // apply them to prove that the source type `Foo` implements `Clone` etc diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index dc342e151f33c..876466e79bc07 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -770,7 +770,11 @@ fn codegen_stmt<'tcx>( let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast(CastKind::DynStar, ref operand, _) => { + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::DynStar), + ref operand, + _, + ) => { let operand = codegen_operand(fx, operand); crate::unsize::coerce_dyn_star(fx, operand, lval); } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index ad0e03fc2630d..dc5377bf9d457 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::DynStar => { + mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => { let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 2c33ff9d219f3..dc7cdee00b2be 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -447,8 +447,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // These are all okay; they only change the type, not the data. } - Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), _, _) => { - // Unsizing is implemented for CTFE. + Rvalue::Cast( + CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar), + _, + _, + ) => { + // Unsizing and `dyn*` coercions are implemented for CTFE. } Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { @@ -458,10 +462,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Since no pointer can ever get exposed (rejected above), this is easy to support. } - Rvalue::Cast(CastKind::DynStar, _, _) => { - // `dyn*` coercion is implemented for CTFE. - } - Rvalue::Cast(_, _, _) => {} Rvalue::NullaryOp( diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 70d074cfdc59c..25fb5f12d61a6 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -125,7 +125,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::DynStar => { + CastKind::PointerCoercion(PointerCoercion::DynStar) => { if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() { // Initial cast from sized to dyn trait let vtable = self.get_vtable_ptr(src.layout.ty, data)?; diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index aab0c4c116afe..9e20e1d9745a7 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -33,12 +33,12 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind}; use rustc_macros::{TypeFoldable, TypeVisitable}; -use rustc_middle::bug; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -674,6 +674,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { use rustc_middle::ty::cast::CastTy::*; use rustc_middle::ty::cast::IntTy::*; + if self.cast_ty.is_dyn_star() { + if fcx.tcx.features().dyn_star { + span_bug!(self.span, "should be handled by `coerce`"); + } else { + // Report "casting is invalid" rather than "non-primitive cast" + // if the feature is not enabled. + return Err(CastError::IllegalCast); + } + } + let (t_from, t_cast) = match (CastTy::from_ty(self.expr_ty), CastTy::from_ty(self.cast_ty)) { (Some(t_from), Some(t_cast)) => (t_from, t_cast), @@ -780,16 +790,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast), (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), - - (_, DynStar) => { - if fcx.tcx.features().dyn_star { - bug!("should be handled by `coerce`") - } else { - Err(CastError::IllegalCast) - } - } - - (DynStar, _) => Err(CastError::IllegalCast), } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 7be91d78e19f6..b08c5bc6d9a36 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -769,7 +769,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )); Ok(InferOk { - value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b), + value: ( + vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], + b, + ), obligations, }) } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 29feed56290b8..bb5f351137305 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -759,9 +759,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { - adjustment::Adjust::NeverToAny - | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::DynStar => { + adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. self.consume_or_copy(&place_with_id, place_with_id.hir_id); @@ -1296,8 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::ReborrowPin(..) - | adjustment::Adjust::DynStar => { + | adjustment::Adjust::ReborrowPin(..) => { // Result is an rvalue. Ok(self.cat_rvalue(expr.hir_id, target)) } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index bc7dfa6205e71..c3891e70e9358 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -434,7 +434,6 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::PtrToPtr | CastKind::PointerCoercion(_) | CastKind::PointerWithExposedProvenance - | CastKind::DynStar | CastKind::Transmute, _, _, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 231eb1989834c..ff7360f06ed19 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1404,8 +1404,6 @@ pub enum CastKind { /// /// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR. PointerCoercion(PointerCoercion), - /// Cast into a dyn* object. - DynStar, IntToInt, FloatToInt, FloatToFloat, diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 5a32078760e5b..41a20e89cbf78 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -35,6 +35,9 @@ pub enum PointerCoercion { /// type. Codegen backends and miri figure out what has to be done /// based on the precise source/target type at hand. Unsize, + + /// Go from a pointer-like type to a `dyn*` object. + DynStar, } /// Represents coercing a value to a different type of value. @@ -102,9 +105,6 @@ pub enum Adjust<'tcx> { Pointer(PointerCoercion), - /// Cast into a dyn* object. - DynStar, - /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. ReborrowPin(ty::Region<'tcx>, hir::Mutability), } diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index 46f3765953678..b1316ceef5ac7 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -34,15 +34,12 @@ pub enum CastTy<'tcx> { FnPtr, /// Raw pointers. Ptr(ty::TypeAndMut<'tcx>), - /// Casting into a `dyn*` value. - DynStar, } /// Cast Kind. See [RFC 401](https://rust-lang.github.io/rfcs/0401-coercions.html) /// (or rustc_hir_analysis/check/cast.rs). #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum CastKind { - CoercionCast, PtrPtrCast, PtrAddrCast, AddrPtrCast, @@ -53,7 +50,6 @@ pub enum CastKind { ArrayPtrCast, FnPtrPtrCast, FnPtrAddrCast, - DynStarCast, } impl<'tcx> CastTy<'tcx> { @@ -71,7 +67,6 @@ impl<'tcx> CastTy<'tcx> { ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), ty::RawPtr(ty, mutbl) => Some(CastTy::Ptr(ty::TypeAndMut { ty, mutbl })), ty::FnPtr(..) => Some(CastTy::FnPtr), - ty::Dynamic(_, _, ty::DynStar) => Some(CastTy::DynStar), _ => None, } } @@ -86,7 +81,6 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin mir::CastKind::PointerExposeProvenance } (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance, - (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar, (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => mir::CastKind::IntToInt, (Some(CastTy::FnPtr), Some(CastTy::Ptr(_))) => mir::CastKind::FnPtrToPtr, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 55236933922ff..a3764b5d312aa 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -146,7 +146,6 @@ impl<'tcx> Cx<'tcx> { Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) } } - Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) }, Adjust::ReborrowPin(region, mutbl) => { debug!("apply ReborrowPin adjustment"); // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index f24de609e6b29..9f9b39b02d39e 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -70,11 +70,11 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { match *rvalue { // We need to detect unsizing casts that required vtables. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { // This isn't monomorphized yet so we can't tell what the actual types are -- just // add everything that may involve a vtable. let source_ty = operand.ty(self.body, self.tcx); diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 914dddc1a56ea..2b6498409d046 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1128,9 +1128,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Rvalue::Cast(kind, operand, target_type) => { let op_ty = operand.ty(self.body, self.tcx); match kind { - CastKind::DynStar => { - // FIXME(dyn-star): make sure nothing needs to be done here. - } // FIXME: Add Checks for these CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {} CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { @@ -1208,6 +1205,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // This is used for all `CoerceUnsized` types, // not just pointers/references, so is hard to check. } + CastKind::PointerCoercion(PointerCoercion::DynStar) => { + // FIXME(dyn-star): make sure nothing needs to be done here. + } CastKind::IntToInt | CastKind::IntToFloat => { let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool(); let target_valid = target_type.is_numeric() || target_type.is_char(); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8d137b8d8f9f1..986d0030a2406 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -665,11 +665,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), ref operand, target_ty, - ) - | mir::Rvalue::Cast(mir::CastKind::DynStar, ref operand, target_ty) => { + ) => { let source_ty = operand.ty(self.body, self.tcx); // *Before* monomorphizing, record that we already handled this mention. self.used_mentioned_items diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index f4c7fd7c90066..e702503724240 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -282,11 +282,12 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { type T = stable_mir::mir::CastKind; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { use rustc_middle::mir::CastKind::*; + use rustc_middle::ty::adjustment::PointerCoercion; match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, + PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar, PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), - DynStar => stable_mir::mir::CastKind::DynStar, IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index e54ab1f7e24c3..ac9a023576261 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -119,6 +119,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { } PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer, PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize, + PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"), } } } diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 7c09fe1a08541..ab9fc218d19fb 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -960,6 +960,7 @@ pub enum CastKind { PointerExposeAddress, PointerWithExposedProvenance, PointerCoercion(PointerCoercion), + // FIXME(smir-rename): change this to PointerCoercion(DynStar) DynStar, IntToInt, FloatToInt, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index d9befb3c157a3..6434c2f42cfb9 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -154,7 +154,7 @@ fn check_rvalue<'tcx>( Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { Err((span, "casting pointers to ints is unstable in const fn".into())) }, - Rvalue::Cast(CastKind::DynStar, _, _) => { + Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => { // FIXME(dyn-star) unimplemented!() }, diff --git a/tests/ui/dyn-star/dyn-to-rigid.rs b/tests/ui/dyn-star/dyn-to-rigid.rs index e80ee15902eef..dc33e288f24e6 100644 --- a/tests/ui/dyn-star/dyn-to-rigid.rs +++ b/tests/ui/dyn-star/dyn-to-rigid.rs @@ -5,7 +5,7 @@ trait Tr {} fn f(x: dyn* Tr) -> usize { x as usize - //~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid + //~^ ERROR non-primitive cast: `(dyn* Tr + 'static)` as `usize` } fn main() {} diff --git a/tests/ui/dyn-star/dyn-to-rigid.stderr b/tests/ui/dyn-star/dyn-to-rigid.stderr index b198c5245dea0..49b8f268aa4e9 100644 --- a/tests/ui/dyn-star/dyn-to-rigid.stderr +++ b/tests/ui/dyn-star/dyn-to-rigid.stderr @@ -1,9 +1,9 @@ -error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid +error[E0605]: non-primitive cast: `(dyn* Tr + 'static)` as `usize` --> $DIR/dyn-to-rigid.rs:7:5 | LL | x as usize - | ^^^^^^^^^^ + | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0606`. +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/dyn-star/enum-cast.rs b/tests/ui/dyn-star/enum-cast.rs new file mode 100644 index 0000000000000..6e895e9527aba --- /dev/null +++ b/tests/ui/dyn-star/enum-cast.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// This used to ICE, because the compiler confused a pointer-like to dyn* coercion +// with a c-like enum to integer cast. + +#![feature(dyn_star)] +#![expect(incomplete_features)] + +enum E { + Num(usize), +} + +trait Trait {} +impl Trait for E {} + +fn main() { + let _ = E::Num(42) as dyn* Trait; +} From b52dea823090223ee2e6faaf08210d085bbc52f2 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 10 Sep 2024 21:41:50 +0200 Subject: [PATCH 09/14] add another test --- .../ui/cast/ptr-to-trait-obj-different-regions-misc.rs | 5 +++++ .../ptr-to-trait-obj-different-regions-misc.stderr | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs index 01c347bfae5a0..d7c6c50d8bebc 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -33,5 +33,10 @@ fn change_assoc_1<'a, 'b>( //~| error: lifetime may not live long enough } +// This tests the default borrow check error, without the special casing for return values. +fn require_static(_: *const dyn Trait<'static>) {} +fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { + require_static(ptr as _) //~ error: lifetime may not live long enough +} fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 7044e4dec1fe5..4a699780c647f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -132,5 +132,13 @@ help: `'b` and `'a` must be the same: replace one with the other | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 8 previous errors +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:20 + | +LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { + | -- lifetime `'a` defined here +LL | require_static(ptr as _) + | ^^^ cast requires that `'a` must outlive `'static` + +error: aborting due to 9 previous errors From d1e82d438f9f3d2ce59be210a2710c560e93e688 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 10 Sep 2024 18:47:10 +0200 Subject: [PATCH 10/14] use more accurate spans for user type ascriptions --- compiler/rustc_middle/src/thir.rs | 4 +++- compiler/rustc_middle/src/thir/visit.rs | 3 ++- .../rustc_mir_build/src/build/expr/as_place.rs | 14 ++++++++------ compiler/rustc_mir_build/src/thir/cx/expr.rs | 13 +++++++++++-- compiler/rustc_mir_build/src/thir/print.rs | 6 ++++-- ...dress_of_reborrow.SimplifyCfg-initial.after.mir | 12 ++++++------ ...t-obj-different-regions-id-trait.current.stderr | 4 ++-- ...rait-obj-different-regions-id-trait.next.stderr | 4 ++-- tests/ui/kindck/kindck-impl-type-params.stderr | 4 ++-- .../user-annotations/cast_static_lifetime.stderr | 3 +-- .../type_ascription_static_lifetime.stderr | 7 +++---- .../trait-upcasting/type-checking-test-3.stderr | 8 ++++---- .../trait-upcasting/type-checking-test-4.stderr | 8 ++++---- 13 files changed, 52 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 32234d6b55d66..5b4f10e52adbf 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -453,12 +453,14 @@ pub enum ExprKind<'tcx> { source: ExprId, /// Type that the user gave to this expression user_ty: UserTy<'tcx>, + user_ty_span: Span, }, - /// A type ascription on a value, e.g. `42: i32`. + /// A type ascription on a value, e.g. `type_ascribe!(42, i32)` or `42 as i32`. ValueTypeAscription { source: ExprId, /// Type that the user gave to this expression user_ty: UserTy<'tcx>, + user_ty_span: Span, }, /// A closure definition. Closure(Box>), diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index e246ecebbec0b..af2e914cbf1a0 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -129,7 +129,8 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor.visit_expr(&visitor.thir()[base.base]); } } - PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => { + PlaceTypeAscription { source, user_ty: _, user_ty_span: _ } + | ValueTypeAscription { source, user_ty: _, user_ty_span: _ } => { visitor.visit_expr(&visitor.thir()[source]) } Closure(box ClosureExpr { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 2084bcae7b79e..c7298e3ddfa90 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -470,21 +470,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(place_builder) } - ExprKind::PlaceTypeAscription { source, ref user_ty } => { + ExprKind::PlaceTypeAscription { source, ref user_ty, user_ty_span } => { let place_builder = unpack!( block = this.expr_as_place(block, source, mutability, fake_borrow_temps,) ); if let Some(user_ty) = user_ty { + let ty_source_info = this.source_info(user_ty_span); let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span: source_info.span, + span: user_ty_span, user_ty: user_ty.clone(), inferred_ty: expr.ty, }); let place = place_builder.to_place(this); this.cfg.push(block, Statement { - source_info, + source_info: ty_source_info, kind: StatementKind::AscribeUserType( Box::new((place, UserTypeProjection { base: annotation_index, @@ -496,20 +497,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } block.and(place_builder) } - ExprKind::ValueTypeAscription { source, ref user_ty } => { + ExprKind::ValueTypeAscription { source, ref user_ty, user_ty_span } => { let source_expr = &this.thir[source]; let temp = unpack!( block = this.as_temp(block, source_expr.temp_lifetime, source, mutability) ); if let Some(user_ty) = user_ty { + let ty_source_info = this.source_info(user_ty_span); let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { - span: source_info.span, + span: user_ty_span, user_ty: user_ty.clone(), inferred_ty: expr.ty, }); this.cfg.push(block, Statement { - source_info, + source_info: ty_source_info, kind: StatementKind::AscribeUserType( Box::new((Place::from(temp), UserTypeProjection { base: annotation_index, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index a3764b5d312aa..00c6a1a4b49fa 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -840,6 +840,7 @@ impl<'tcx> Cx<'tcx> { ExprKind::ValueTypeAscription { source: cast_expr, user_ty: Some(Box::new(*user_ty)), + user_ty_span: cast_ty.span, } } else { cast @@ -851,9 +852,17 @@ impl<'tcx> Cx<'tcx> { debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty); let mirrored = self.mirror_expr(source); if source.is_syntactic_place_expr() { - ExprKind::PlaceTypeAscription { source: mirrored, user_ty } + ExprKind::PlaceTypeAscription { + source: mirrored, + user_ty, + user_ty_span: ty.span, + } } else { - ExprKind::ValueTypeAscription { source: mirrored, user_ty } + ExprKind::ValueTypeAscription { + source: mirrored, + user_ty, + user_ty_span: ty.span, + } } } hir::ExprKind::DropTemps(source) => ExprKind::Use { source: self.mirror_expr(source) }, diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ce7774f594882..a507aeb76acd9 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -454,16 +454,18 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_adt_expr(&**adt_expr, depth_lvl + 1); print_indented!(self, "}", depth_lvl); } - PlaceTypeAscription { source, user_ty } => { + PlaceTypeAscription { source, user_ty, user_ty_span } => { print_indented!(self, "PlaceTypeAscription {", depth_lvl); print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1); + print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } - ValueTypeAscription { source, user_ty } => { + ValueTypeAscription { source, user_ty, user_ty_span } => { print_indented!(self, "ValueTypeAscription {", depth_lvl); print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1); + print_indented!(self, format!("user_ty_span: {:?}", user_ty_span), depth_lvl + 1); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index be636da4517ca..edf62a1e17398 100644 --- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -1,8 +1,8 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10] -| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send +| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] +| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send | 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] | 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] | 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] @@ -11,8 +11,8 @@ | 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send | 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] | 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10] -| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send +| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] +| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send | 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] | 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] | 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] @@ -21,8 +21,8 @@ | 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send | 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] | 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10] -| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send +| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] +| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send | 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] | 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] | 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr index 5a5b4bfcacf43..4e43d3b93fa35 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr @@ -1,11 +1,11 @@ error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:27 | LL | fn m<'a>() { | -- lifetime `'a` defined here LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant = note: the struct `S` is invariant over the parameter `T` diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr index 5a5b4bfcacf43..4e43d3b93fa35 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr @@ -1,11 +1,11 @@ error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:27 | LL | fn m<'a>() { | -- lifetime `'a` defined here LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant = note: the struct `S` is invariant over the parameter `T` diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index aad020e4ec97a..5892596dc6adc 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -112,13 +112,13 @@ LL | struct Foo; // does not impl Copy | error: lifetime may not live long enough - --> $DIR/kindck-impl-type-params.rs:30:13 + --> $DIR/kindck-impl-type-params.rs:30:19 | LL | fn foo<'a>() { | -- lifetime `'a` defined here LL | let t: S<&'a isize> = S(marker::PhantomData); LL | let a = &t as &dyn Gettable<&'a isize>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: aborting due to 7 previous errors diff --git a/tests/ui/nll/user-annotations/cast_static_lifetime.stderr b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr index 35eec233ed5c0..efd14fe875dbe 100644 --- a/tests/ui/nll/user-annotations/cast_static_lifetime.stderr +++ b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr @@ -4,10 +4,9 @@ error[E0597]: `x` does not live long enough LL | let x = 22_u32; | - binding `x` declared here LL | let y: &u32 = (&x) as &'static u32; - | ^^^^---------------- + | ^^^^ ------------ type annotation requires that `x` is borrowed for `'static` | | | borrowed value does not live long enough - | type annotation requires that `x` is borrowed for `'static` LL | } | - `x` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr index 3e2706309b342..2ed0fadc06557 100644 --- a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr +++ b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr @@ -4,10 +4,9 @@ error[E0597]: `x` does not live long enough LL | let x = 22_u32; | - binding `x` declared here LL | let y: &u32 = type_ascribe!(&x, &'static u32); - | --------------^^--------------- - | | | - | | borrowed value does not live long enough - | type annotation requires that `x` is borrowed for `'static` + | ^^ ------------ type annotation requires that `x` is borrowed for `'static` + | | + | borrowed value does not live long enough LL | } | - `x` dropped here while still borrowed diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr index e6cb6a753998f..0a969b611e9d3 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-3.stderr @@ -1,18 +1,18 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:11:13 + --> $DIR/type-checking-test-3.rs:11:18 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a>; // Error - | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-3.rs:16:13 + --> $DIR/type-checking-test-3.rs:16:18 | LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr index ccced5875778d..090120a2327a8 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -1,18 +1,18 @@ error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:19:13 + --> $DIR/type-checking-test-4.rs:19:18 | LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'static, 'a>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/type-checking-test-4.rs:24:13 + --> $DIR/type-checking-test-4.rs:24:18 | LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) { | -- lifetime `'a` defined here LL | let _ = x as &dyn Bar<'a, 'static>; // Error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` error: lifetime may not live long enough --> $DIR/type-checking-test-4.rs:30:5 From 5e60d1f87e5c4abebb9a4eae9d68955113399d6e Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 10 Sep 2024 19:20:27 +0200 Subject: [PATCH 11/14] replace "cast" with "coercion" where applicable This changes the remaining span for the cast, because the new `Cast` category has a higher priority (lower `Ord`) than the old `Coercion` category, so we no longer report the region error for the "unsizing" coercion from `*const Trait` to itself. --- .../src/diagnostics/explain_borrow.rs | 4 ++- .../src/diagnostics/region_errors.rs | 3 ++- compiler/rustc_borrowck/src/type_check/mod.rs | 26 +++++++++++-------- compiler/rustc_middle/src/mir/query.rs | 4 ++- .../two-phase-surprise-no-conflict.stderr | 4 +-- ...to-trait-obj-different-regions-misc.stderr | 2 +- .../dropck/dropck_trait_cycle_checked.stderr | 12 ++++----- ...600-expected-return-static-indirect.stderr | 4 +-- .../issue-54779-anon-static-lifetime.stderr | 2 +- ...ore-lifetime-in-return-trait-object.stderr | 2 +- .../trait-object-lifetime-default-note.rs | 2 +- .../trait-object-lifetime-default-note.stderr | 2 +- 12 files changed, 38 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 7077d78f45941..63b653bc9f4cb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -333,7 +333,9 @@ impl<'tcx> BorrowExplanation<'tcx> { } } - if let ConstraintCategory::Cast { unsize_to: Some(unsize_ty) } = category { + if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } = + category + { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index ca0a3c6613052..a4a9734de3f0f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -47,7 +47,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { ConstraintCategory::Yield => "yielding this value ", ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", - ConstraintCategory::Cast { .. } => "cast ", + ConstraintCategory::Cast { is_coercion: false, .. } => "cast ", + ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ", ConstraintCategory::CallArgument(_) => "argument ", ConstraintCategory::TypeAnnotation => "type annotation ", ConstraintCategory::ClosureBounds => "closure body ", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 29a0c5bdf572f..db69f48e515a4 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2007,7 +2007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); let src_ty = self.normalize(src_ty, location); @@ -2015,7 +2015,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2036,7 +2036,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); // The type that we see in the fcx is like @@ -2049,7 +2049,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2074,7 +2074,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2103,7 +2103,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2128,6 +2128,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_coercion: true, unsize_to: Some(tcx.fold_regions(ty, |r, _| { if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased @@ -2155,7 +2156,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .iter() .map(|predicate| predicate.with_self_ty(tcx, self_ty)), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); let outlives_predicate = tcx.mk_predicate(Binder::dummy( @@ -2166,7 +2167,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( outlives_predicate, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); } @@ -2184,7 +2185,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2246,7 +2247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2427,7 +2428,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_obj, dst_obj, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { + is_coercion: false, + unsize_to: None, + }, ) .unwrap(); } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1002f64f849a2..47fea6f6d9057 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -234,7 +234,9 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation, Cast { - /// Whether this is an unsizing cast and if yes, this contains the target type. + /// Whether this cast is a coercion. + is_coercion: bool, + /// Whether this is an unsizing coercion and if yes, this contains the target type. /// Region variables are erased to ReErased. #[derive_where(skip)] unsize_to: Option>, diff --git a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr index b3bf2f924fc3e..89b15a7a659dd 100644 --- a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr +++ b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr @@ -75,7 +75,7 @@ LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); | ^^^^^^^^^^^^^^^^^^-----------------------------------------^ | | | | | | | immutable borrow occurs here - | | cast requires that `reg.sess_mut` is borrowed for `'a` + | | coercion requires that `reg.sess_mut` is borrowed for `'a` | mutable borrow occurs here | = note: due to object lifetime defaults, `Box LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>` @@ -119,7 +119,7 @@ LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); | ^^^^^^^^^^^^^^^^^^-------------------------------------------------^ | | | | | | | first mutable borrow occurs here - | | cast requires that `reg.sess_mut` is borrowed for `'a` + | | coercion requires that `reg.sess_mut` is borrowed for `'a` | second mutable borrow occurs here | = note: due to object lifetime defaults, `Box LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>` diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 4a699780c647f..6069f4f3b5563 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -138,7 +138,7 @@ error: lifetime may not live long enough LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { | -- lifetime `'a` defined here LL | require_static(ptr as _) - | ^^^ cast requires that `'a` must outlive `'static` + | ^^^^^^^^ cast requires that `'a` must outlive `'static` error: aborting due to 9 previous errors diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr index 63fd07a91633d..f32736f1a674c 100644 --- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr +++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr @@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:111:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` LL | o1.set0(&o2); | ^^^ borrowed value does not live long enough ... @@ -15,7 +15,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:112:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` LL | o1.set0(&o2); LL | o1.set1(&o3); | ^^^ borrowed value does not live long enough @@ -29,7 +29,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:113:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` ... LL | o2.set0(&o2); | ^^^ borrowed value does not live long enough @@ -43,7 +43,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:114:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` ... LL | o2.set1(&o3); | ^^^ borrowed value does not live long enough @@ -57,7 +57,7 @@ error[E0597]: `o1` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:115:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o1` declared here -------- cast requires that `o1` is borrowed for `'static` + | -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static` ... LL | o3.set0(&o1); | ^^^ borrowed value does not live long enough @@ -71,7 +71,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:116:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` ... LL | o3.set1(&o2); | ^^^ borrowed value does not live long enough diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr index 598f142419137..6bd6a0584c9f1 100644 --- a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr +++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -7,7 +7,7 @@ LL | let refcell = RefCell::new(&mut foo); | ^^^^^^^^ borrowed value does not live long enough LL | LL | let read = &refcell as &RefCell; - | -------- cast requires that `foo` is borrowed for `'static` + | -------- coercion requires that `foo` is borrowed for `'static` ... LL | } | - `foo` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | fn inner(mut foo: &[u8]) { | - let's call the lifetime of this reference `'1` ... LL | let read = &refcell as &RefCell; - | ^^^^^^^^ cast requires that `'1` must outlive `'static` + | ^^^^^^^^ coercion requires that `'1` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr index 92298c6617ff5..a454ed265685c 100644 --- a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr +++ b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr @@ -5,7 +5,7 @@ LL | cx: &dyn DebugContext, | - let's call the lifetime of this reference `'1` ... LL | bar.debug_with(cx); - | ^^ cast requires that `'1` must outlive `'static` + | ^^ coercion requires that `'1` must outlive `'static` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr index 73fa5ddb146e7..050ef7da9b936 100644 --- a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr +++ b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | fn foo(value: &T) -> Box { | - let's call the lifetime of this reference `'1` LL | Box::new(value) as Box - | ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` + | ^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | diff --git a/tests/ui/traits/trait-object-lifetime-default-note.rs b/tests/ui/traits/trait-object-lifetime-default-note.rs index 31e3eb4ba4155..275411ff61c85 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.rs +++ b/tests/ui/traits/trait-object-lifetime-default-note.rs @@ -8,7 +8,7 @@ fn main() { //~| NOTE borrowed value does not live long enough //~| NOTE due to object lifetime defaults, `Box` actually means `Box<(dyn A + 'static)>` require_box(Box::new(r)); - //~^ NOTE cast requires that `local` is borrowed for `'static` + //~^ NOTE coercion requires that `local` is borrowed for `'static` let _ = 0; } //~ NOTE `local` dropped here while still borrowed diff --git a/tests/ui/traits/trait-object-lifetime-default-note.stderr b/tests/ui/traits/trait-object-lifetime-default-note.stderr index 4244e34873ad1..8cb9bc0d80072 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.stderr +++ b/tests/ui/traits/trait-object-lifetime-default-note.stderr @@ -7,7 +7,7 @@ LL | let r = &local; | ^^^^^^ borrowed value does not live long enough ... LL | require_box(Box::new(r)); - | ----------- cast requires that `local` is borrowed for `'static` + | ----------- coercion requires that `local` is borrowed for `'static` ... LL | } | - `local` dropped here while still borrowed From bd31e3ed70b75e5936880b18f6b5d1c8f5ee344f Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 15 Sep 2024 19:35:06 +0200 Subject: [PATCH 12/14] be even more precise about "cast" vs "coercion" --- .../src/diagnostics/explain_borrow.rs | 8 ++- .../src/diagnostics/region_errors.rs | 4 +- compiler/rustc_borrowck/src/type_check/mod.rs | 69 +++++++++++-------- compiler/rustc_codegen_cranelift/src/base.rs | 11 +-- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 14 ++-- .../src/check_consts/check.rs | 3 +- .../rustc_const_eval/src/interpret/cast.rs | 11 +-- compiler/rustc_middle/src/mir/query.rs | 4 +- compiler/rustc_middle/src/mir/statement.rs | 2 +- compiler/rustc_middle/src/mir/syntax.rs | 13 +++- compiler/rustc_middle/src/thir.rs | 2 + compiler/rustc_middle/src/thir/visit.rs | 4 +- .../src/build/expr/as_rvalue.rs | 6 +- .../rustc_mir_build/src/build/matches/test.rs | 10 ++- compiler/rustc_mir_build/src/thir/cx/expr.rs | 26 +++++-- compiler/rustc_mir_build/src/thir/print.rs | 7 +- .../src/cleanup_post_borrowck.rs | 1 + .../src/dataflow_const_prop.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 10 +-- .../src/mentioned_items.rs | 8 +-- .../src/shim/async_destructor_ctor.rs | 9 +-- compiler/rustc_mir_transform/src/validate.rs | 14 ++-- compiler/rustc_monomorphize/src/collector.rs | 8 +-- .../rustc_smir/src/rustc_smir/convert/mir.rs | 4 +- .../clippy_utils/src/qualify_min_const_fn.rs | 8 +-- .../fail/dyn-upcast-trait-mismatch.stderr | 2 +- ..._of_reborrow.SimplifyCfg-initial.after.mir | 26 +++---- .../build_correct_coerce.main.built.after.mir | 2 +- ...ceiver_ptr_mutability.main.built.after.mir | 4 +- ...e_live_dead_in_statics.XXX.built.after.mir | 2 +- ...motion_extern_static.BAR.PromoteTemps.diff | 2 +- ...motion_extern_static.FOO.PromoteTemps.diff | 2 +- ...for_slices.main.GVN.32bit.panic-abort.diff | 2 +- ...or_slices.main.GVN.32bit.panic-unwind.diff | 2 +- ...for_slices.main.GVN.64bit.panic-abort.diff | 2 +- ...or_slices.main.GVN.64bit.panic-unwind.diff | 2 +- .../const_prop/reify_fn_ptr.main.GVN.diff | 2 +- tests/mir-opt/const_prop/reify_fn_ptr.rs | 2 +- .../slice_len.main.GVN.32bit.panic-abort.diff | 4 +- ...slice_len.main.GVN.32bit.panic-unwind.diff | 4 +- .../slice_len.main.GVN.64bit.panic-abort.diff | 4 +- ...slice_len.main.GVN.64bit.panic-unwind.diff | 4 +- tests/mir-opt/const_prop/slice_len.rs | 2 +- ...ssue_107511.main.CopyProp.panic-abort.diff | 2 +- ...sue_107511.main.CopyProp.panic-unwind.diff | 2 +- ...oxed_slice.main.GVN.32bit.panic-abort.diff | 2 +- ...xed_slice.main.GVN.32bit.panic-unwind.diff | 2 +- ...oxed_slice.main.GVN.64bit.panic-abort.diff | 2 +- ...xed_slice.main.GVN.64bit.panic-unwind.diff | 2 +- ...n.DataflowConstProp.32bit.panic-abort.diff | 2 +- ....DataflowConstProp.32bit.panic-unwind.diff | 2 +- ...n.DataflowConstProp.64bit.panic-abort.diff | 2 +- ....DataflowConstProp.64bit.panic-unwind.diff | 2 +- .../gvn.array_len.GVN.panic-abort.diff | 2 +- .../gvn.array_len.GVN.panic-unwind.diff | 2 +- .../gvn.fn_pointers.GVN.panic-abort.diff | 12 ++-- .../gvn.fn_pointers.GVN.panic-unwind.diff | 12 ++-- ...n.wide_ptr_provenance.GVN.panic-abort.diff | 20 +++--- ....wide_ptr_provenance.GVN.panic-unwind.diff | 20 +++--- ...e_ptr_same_provenance.GVN.panic-abort.diff | 20 +++--- ..._ptr_same_provenance.GVN.panic-unwind.diff | 20 +++--- ...yn_trait.get_query.Inline.panic-abort.diff | 2 +- ...n_trait.get_query.Inline.panic-unwind.diff | 2 +- ....try_execute_query.Inline.panic-abort.diff | 2 +- ...try_execute_query.Inline.panic-unwind.diff | 2 +- ...implifyComparisonIntegral.panic-abort.diff | 2 +- ...mplifyComparisonIntegral.panic-unwind.diff | 2 +- ...array_len.array_bound.GVN.panic-abort.diff | 2 +- ...rray_len.array_bound.GVN.panic-unwind.diff | 2 +- ...y_len.array_bound_mut.GVN.panic-abort.diff | 2 +- ..._len.array_bound_mut.GVN.panic-unwind.diff | 2 +- ...r_array_len.array_len.GVN.panic-abort.diff | 2 +- ..._array_len.array_len.GVN.panic-unwind.diff | 2 +- ...en.array_len_by_value.GVN.panic-abort.diff | 2 +- ...n.array_len_by_value.GVN.panic-unwind.diff | 2 +- ...ray_len.array_len_raw.GVN.panic-abort.diff | 2 +- ...ay_len.array_len_raw.GVN.panic-unwind.diff | 2 +- ...en.array_len_reborrow.GVN.panic-abort.diff | 2 +- ...n.array_len_reborrow.GVN.panic-unwind.diff | 2 +- ...d_constant.main.GVN.32bit.panic-abort.diff | 2 +- ...d_constant.main.GVN.64bit.panic-abort.diff | 2 +- ...fg-pre-optimizations.after.panic-abort.mir | 2 +- ...g-pre-optimizations.after.panic-unwind.mir | 2 +- ...ls.c.SimplifyLocals-before-const-prop.diff | 2 +- ...mes.foo.ScalarReplacementOfAggregates.diff | 2 +- ...600-expected-return-static-indirect.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 3 +- .../regions-close-object-into-object-5.stderr | 3 +- ...regions-close-over-type-parameter-1.stderr | 4 +- ...ore-lifetime-in-return-trait-object.stderr | 2 +- 90 files changed, 289 insertions(+), 231 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 63b653bc9f4cb..31a5d451ff6b6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -333,8 +333,10 @@ impl<'tcx> BorrowExplanation<'tcx> { } } - if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } = - category + if let ConstraintCategory::Cast { + is_implicit_coercion: true, + unsize_to: Some(unsize_ty), + } = category { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } @@ -742,7 +744,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // If we see an unsized cast, then if it is our data we should check // whether it is being cast to a trait object. Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, _), operand, ty, ) => { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a4a9734de3f0f..39175b406a4aa 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -47,8 +47,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { ConstraintCategory::Yield => "yielding this value ", ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", - ConstraintCategory::Cast { is_coercion: false, .. } => "cast ", - ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ", + ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ", + ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ", ConstraintCategory::CallArgument(_) => "argument ", ConstraintCategory::TypeAnnotation => "type annotation ", ConstraintCategory::ClosureBounds => "closure body ", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index db69f48e515a4..16e51e82f85e0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1975,8 +1975,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::Cast(cast_kind, op, ty) => { self.check_operand(op, location); - match cast_kind { - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + match *cast_kind { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => { + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; let src_sig = op.ty(body, tcx).fn_sig(tcx); // HACK: This shouldn't be necessary... We can remove this when we actually @@ -2007,7 +2008,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); let src_ty = self.normalize(src_ty, location); @@ -2015,7 +2016,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); // The type that we see in the fcx is like @@ -2049,7 +2050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(safety)) => { + CastKind::PointerCoercion( + PointerCoercion::ClosureFnPointer(safety), + coercion_source, + ) => { let sig = match op.ty(body, tcx).kind() { ty::Closure(_, args) => args.as_closure().sig(), _ => bug!(), }; let ty_fn_ptr_from = - Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, *safety)); + Ty::new_fn_ptr(tcx, tcx.signature_unclosure(sig, safety)); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion( + PointerCoercion::UnsafeFnPointer, + coercion_source, + ) => { let fn_sig = op.ty(body, tcx).fn_sig(tcx); // The type that we see in the fcx is like @@ -2099,11 +2107,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2116,7 +2125,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => { let &ty = ty; let trait_ref = ty::TraitRef::new( tcx, @@ -2124,23 +2133,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { [op.ty(body, tcx), ty], ); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; + let unsize_to = tcx.fold_regions(ty, |r, _| { + if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r } + }); self.prove_trait_ref( trait_ref, location.to_locations(), ConstraintCategory::Cast { - is_coercion: true, - unsize_to: Some(tcx.fold_regions(ty, |r, _| { - if let ty::ReVar(_) = r.kind() { - tcx.lifetimes.re_erased - } else { - r - } - })), + is_implicit_coercion, + unsize_to: Some(unsize_to), }, ); } - CastKind::PointerCoercion(PointerCoercion::DynStar) => { + CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => { // get the constraints from the target type (`dyn* Clone`) // // apply them to prove that the source type `Foo` implements `Clone` etc @@ -2151,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let self_ty = op.ty(body, tcx); + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; self.prove_predicates( existential_predicates .iter() .map(|predicate| predicate.with_self_ty(tcx, self_ty)), location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); let outlives_predicate = tcx.mk_predicate(Binder::dummy( @@ -2167,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicate( outlives_predicate, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ); } - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => { + CastKind::PointerCoercion( + PointerCoercion::MutToConstPointer, + coercion_source, + ) => { let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind() else { span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,); @@ -2181,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,); return; }; + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2198,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => { + CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => { let ty_from = op.ty(body, tcx); let opt_ty_elem_mut = match ty_from.kind() { @@ -2243,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } + let is_implicit_coercion = coercion_source == CoercionSource::Implicit; if let Err(terr) = self.sub_types( *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, + ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, ) { span_mirbug!( self, @@ -2429,7 +2442,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { dst_obj, location.to_locations(), ConstraintCategory::Cast { - is_coercion: false, + is_implicit_coercion: false, unsize_to: None, }, ) diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 876466e79bc07..1ce0aacab4998 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -652,7 +652,7 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, res); } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, to_ty, ) => { @@ -677,7 +677,7 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer), + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _), ref operand, to_ty, ) => { @@ -688,6 +688,7 @@ fn codegen_stmt<'tcx>( Rvalue::Cast( CastKind::PointerCoercion( PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + _, ), .., ) => { @@ -741,7 +742,7 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _to_ty, ) => { @@ -763,7 +764,7 @@ fn codegen_stmt<'tcx>( } } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref operand, _to_ty, ) => { @@ -771,7 +772,7 @@ fn codegen_stmt<'tcx>( crate::unsize::coerce_unsized_into(fx, operand, lval); } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::DynStar), + CastKind::PointerCoercion(PointerCoercion::DynStar, _), ref operand, _, ) => { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index dc5377bf9d457..f9c0f3ce94146 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -34,7 +34,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _), ref source, _, ) => { @@ -465,7 +465,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let lladdr = bx.ptrtoint(llptr, llcast_ty); OperandValue::Immediate(lladdr) } - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { match *operand.layout.ty.kind() { ty::FnDef(def_id, args) => { let instance = ty::Instance::resolve_for_fn_ptr( @@ -481,7 +481,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty), } } - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => { + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => { match *operand.layout.ty.kind() { ty::Closure(def_id, args) => { let instance = Instance::resolve_closure( @@ -496,11 +496,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty), } } - mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { // This is a no-op at the LLVM level. operand.val } - mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => { + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { assert!(bx.cx().is_backend_scalar_pair(cast)); let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = @@ -508,7 +508,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Pair(lldata, llextra) } mir::CastKind::PointerCoercion( - PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _ ) => { bug!("{kind:?} is for borrowck, and should never appear in codegen"); } @@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => { + mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index dc7cdee00b2be..e1b605979972d 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -440,6 +440,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) | PointerCoercion::ReifyFnPointer, + _, ), _, _, @@ -448,7 +449,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar), + CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _), _, _, ) => { diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 25fb5f12d61a6..85e7d91c2ad50 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -32,7 +32,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if cast_ty == dest.layout.ty { dest.layout } else { self.layout_of(cast_ty)? }; // FIXME: In which cases should we trigger UB when the source is uninit? match cast_kind { - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { self.unsize_into(src, cast_layout, dest)?; } @@ -68,11 +68,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { CastKind::PointerCoercion( PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + _, ) => { bug!("{cast_kind:?} casts are for borrowck only, not runtime MIR"); } - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { // All reifications must be monomorphic, bail out otherwise. ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; @@ -94,7 +95,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { let src = self.read_immediate(src)?; match cast_ty.kind() { ty::FnPtr(..) => { @@ -105,7 +106,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => { + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => { // All reifications must be monomorphic, bail out otherwise. ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; @@ -125,7 +126,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::PointerCoercion(PointerCoercion::DynStar) => { + CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { if let ty::Dynamic(data, _, ty::DynStar) = cast_ty.kind() { // Initial cast from sized to dyn trait let vtable = self.get_vtable_ptr(src.layout.ty, data)?; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 47fea6f6d9057..70331214ac5a8 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -234,8 +234,8 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation, Cast { - /// Whether this cast is a coercion. - is_coercion: bool, + /// Whether this cast is a coercion that was automatically inserted by the compiler. + is_implicit_coercion: bool, /// Whether this is an unsizing coercion and if yes, this contains the target type. /// Region variables are erased to ReErased. #[derive_where(skip)] diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index c3891e70e9358..88ed90c311463 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -432,7 +432,7 @@ impl<'tcx> Rvalue<'tcx> { | CastKind::IntToFloat | CastKind::FnPtrToPtr | CastKind::PtrToPtr - | CastKind::PointerCoercion(_) + | CastKind::PointerCoercion(_, _) | CastKind::PointerWithExposedProvenance | CastKind::Transmute, _, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ff7360f06ed19..bba3aee820ab2 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -579,7 +579,7 @@ pub struct CopyNonOverlapping<'tcx> { pub count: Operand<'tcx>, } -/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics +/// Represents how a [`TerminatorKind::Call`] was constructed, used for diagnostics. #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub enum CallSource { @@ -1403,7 +1403,7 @@ pub enum CastKind { /// * [`PointerCoercion::MutToConstPointer`] /// /// Both are runtime nops, so should be [`CastKind::PtrToPtr`] instead in runtime MIR. - PointerCoercion(PointerCoercion), + PointerCoercion(PointerCoercion, CoercionSource), IntToInt, FloatToInt, FloatToFloat, @@ -1419,6 +1419,15 @@ pub enum CastKind { Transmute, } +/// Represents how a [`CastKind::PointerCoercion`] was constructed, used for diagnostics. +#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +pub enum CoercionSource { + /// The coercion was manually written by the user with an `as` cast. + AsCast, + /// The coercion was automatically inserted by the compiler. + Implicit, +} + #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub enum AggregateKind<'tcx> { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 5b4f10e52adbf..e614d41899a0e 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -338,6 +338,8 @@ pub enum ExprKind<'tcx> { PointerCoercion { cast: PointerCoercion, source: ExprId, + /// Whether this coercion is written with an `as` cast in the source code. + is_from_as_cast: bool, }, /// A `loop` expression. Loop { diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index af2e914cbf1a0..58e2ebaeaf8df 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -68,7 +68,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( Cast { source } => visitor.visit_expr(&visitor.thir()[source]), Use { source } => visitor.visit_expr(&visitor.thir()[source]), NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]), - PointerCoercion { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]), + PointerCoercion { source, cast: _, is_from_as_cast: _ } => { + visitor.visit_expr(&visitor.thir()[source]) + } Let { expr, ref pat } => { visitor.visit_expr(&visitor.thir()[expr]); visitor.visit_pat(pat); diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index ffedee8a1e816..fd949a533845e 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -292,7 +292,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cast_kind = mir_cast_kind(ty, expr.ty); block.and(Rvalue::Cast(cast_kind, source, expr.ty)) } - ExprKind::PointerCoercion { cast, source } => { + ExprKind::PointerCoercion { cast, source, is_from_as_cast } => { let source = unpack!( block = this.as_operand( block, @@ -302,7 +302,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { NeedsTemporary::No ) ); - block.and(Rvalue::Cast(CastKind::PointerCoercion(cast), source, expr.ty)) + let origin = + if is_from_as_cast { CoercionSource::AsCast } else { CoercionSource::Implicit }; + block.and(Rvalue::Cast(CastKind::PointerCoercion(cast, origin), source, expr.ty)) } ExprKind::Array { ref fields } => { // (*) We would (maybe) be closer to codegen if we diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 63873aad02a44..020c202f96503 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -407,7 +407,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, temp, Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion( + PointerCoercion::Unsize, + CoercionSource::Implicit, + ), Operand::Copy(val), ty, ), @@ -421,7 +424,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, slice, Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion( + PointerCoercion::Unsize, + CoercionSource::Implicit, + ), expect, ty, ), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 00c6a1a4b49fa..fbd45f59a4fb4 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -104,16 +104,29 @@ impl<'tcx> Cx<'tcx> { }; let kind = match adjustment.kind { - Adjust::Pointer(PointerCoercion::Unsize) => { - adjust_span(&mut expr); + Adjust::Pointer(cast) => { + if cast == PointerCoercion::Unsize { + adjust_span(&mut expr); + } + + let is_from_as_cast = if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Cast(..), + span: cast_span, + .. + }) = self.tcx.parent_hir_node(hir_expr.hir_id) + { + // Use the whole span of the `x as T` expression for the coercion. + span = *cast_span; + true + } else { + false + }; ExprKind::PointerCoercion { - cast: PointerCoercion::Unsize, + cast, source: self.thir.exprs.push(expr), + is_from_as_cast, } } - Adjust::Pointer(cast) => { - ExprKind::PointerCoercion { cast, source: self.thir.exprs.push(expr) } - } Adjust::NeverToAny if adjustment.target.is_never() => return expr, Adjust::NeverToAny => ExprKind::NeverToAny { source: self.thir.exprs.push(expr) }, Adjust::Deref(None) => { @@ -235,6 +248,7 @@ impl<'tcx> Cx<'tcx> { ExprKind::PointerCoercion { source: self.mirror_expr(source), cast: PointerCoercion::ArrayToPointer, + is_from_as_cast: true, } } else if let hir::ExprKind::Path(ref qpath) = source.kind && let res = self.typeck_results().qpath_res(qpath, source.hir_id) diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index a507aeb76acd9..61317925d09e5 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -292,9 +292,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } - PointerCoercion { cast, source } => { + PointerCoercion { cast, is_from_as_cast, source } => { print_indented!(self, "Pointer {", depth_lvl); print_indented!(self, format!("cast: {:?}", cast), depth_lvl + 1); + print_indented!( + self, + format!("is_from_as_cast: {:?}", is_from_as_cast), + depth_lvl + 1 + ); print_indented!(self, "source:", depth_lvl + 1); self.print_expr(*source, depth_lvl + 2); print_indented!(self, "}", depth_lvl); diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 5395e1b0e94d8..6a22a58470c95 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -42,6 +42,7 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck { ref mut cast_kind @ CastKind::PointerCoercion( PointerCoercion::ArrayToPointer | PointerCoercion::MutToConstPointer, + _, ), .., ), diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 2026b7893159e..88dc8e74a8c29 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -189,7 +189,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { } } Rvalue::Cast( - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize), + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _), operand, _, ) => { diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 4d44669fa3ec5..f735d08fca573 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -576,7 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } value.offset(Size::ZERO, to, &self.ecx).ok()? } - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) => { + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) => { let src = self.evaluated[value].as_ref()?; let to = self.ecx.layout_of(to).ok()?; let dest = self.ecx.allocate(to, MemoryKind::Stack).ok()?; @@ -593,7 +593,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let ret = self.ecx.ptr_to_ptr(&src, to).ok()?; ret.into() } - CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer, _) => { let src = self.evaluated[value].as_ref()?; let src = self.ecx.read_immediate(src).ok()?; let to = self.ecx.layout_of(to).ok()?; @@ -1138,7 +1138,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { ( UnOp::PtrMetadata, Value::Cast { - kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize), + kind: CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _), from, to, .. @@ -1342,7 +1342,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return Some(value); } - if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_)) = kind { + if let CastKind::PointerCoercion(ReifyFnPointer | ClosureFnPointer(_), _) = kind { // Each reification of a generic fn may get a different pointer. // Do not try to merge them. return self.new_opaque(); @@ -1429,7 +1429,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { // We have an unsizing cast, which assigns the length to fat pointer metadata. if let Value::Cast { kind, from, to, .. } = self.get(inner) - && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize) = kind + && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind && let Some(from) = from.builtin_deref(true) && let ty::Array(_, len) = from.kind() && let Some(to) = to.builtin_deref(true) diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index 9f9b39b02d39e..cf5c5f85a9ff6 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -70,8 +70,8 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { match *rvalue { // We need to detect unsizing casts that required vtables. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize) - | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), ref operand, target_ty, ) => { @@ -96,7 +96,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { } // Similarly, record closures that are turned into function pointers. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _, ) => { @@ -106,7 +106,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { } // And finally, function pointer reification casts. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, _, ) => { diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index c206252c15aa4..71723f040b3b6 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -7,9 +7,10 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{ - BasicBlock, BasicBlockData, Body, CallSource, CastKind, Const, ConstOperand, ConstValue, Local, - LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue, SourceInfo, Statement, - StatementKind, Terminator, TerminatorKind, UnwindAction, UnwindTerminateReason, + BasicBlock, BasicBlockData, Body, CallSource, CastKind, CoercionSource, Const, ConstOperand, + ConstValue, Local, LocalDecl, MirSource, Operand, Place, PlaceElem, RETURN_PLACE, Rvalue, + SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnwindAction, + UnwindTerminateReason, }; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::{AsyncDropGlueMorphology, Discr}; @@ -329,7 +330,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { fn put_array_as_slice(&mut self, elem_ty: Ty<'tcx>) { let slice_ptr_ty = Ty::new_mut_ptr(self.tcx, Ty::new_slice(self.tcx, elem_ty)); self.put_temp_rvalue(Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::Unsize), + CastKind::PointerCoercion(PointerCoercion::Unsize, CoercionSource::Implicit), Operand::Copy(Self::SELF_PTR.into()), slice_ptr_ty, )) diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 2b6498409d046..eda0b8c75f322 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1130,7 +1130,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { match kind { // FIXME: Add Checks for these CastKind::PointerWithExposedProvenance | CastKind::PointerExposeProvenance => {} - CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => { // FIXME: check signature compatibility. check_kinds!( op_ty, @@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => { + CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => { // FIXME: check safety and signature compatibility. check_kinds!( op_ty, @@ -1156,7 +1156,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..)) => { + CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(..), _) => { // FIXME: check safety, captures, and signature compatibility. check_kinds!( op_ty, @@ -1169,7 +1169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::FnPtr(..) ); } - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => { + CastKind::PointerCoercion(PointerCoercion::MutToConstPointer, _) => { // FIXME: check same pointee? check_kinds!( op_ty, @@ -1185,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => { + CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, _) => { // FIXME: Check pointee types check_kinds!( op_ty, @@ -1201,11 +1201,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("After borrowck, MIR disallows {kind:?}")); } } - CastKind::PointerCoercion(PointerCoercion::Unsize) => { + CastKind::PointerCoercion(PointerCoercion::Unsize, _) => { // This is used for all `CoerceUnsized` types, // not just pointers/references, so is hard to check. } - CastKind::PointerCoercion(PointerCoercion::DynStar) => { + CastKind::PointerCoercion(PointerCoercion::DynStar, _) => { // FIXME(dyn-star): make sure nothing needs to be done here. } CastKind::IntToInt | CastKind::IntToFloat => { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 986d0030a2406..fd3ae4435a683 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -665,8 +665,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::Unsize) - | mir::CastKind::PointerCoercion(PointerCoercion::DynStar), + mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) + | mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _), ref operand, target_ty, ) => { @@ -694,7 +694,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { } } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer), + mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _), ref operand, _, ) => { @@ -705,7 +705,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { visit_fn_use(self.tcx, fn_ty, false, span, self.used_items); } mir::Rvalue::Cast( - mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), + mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _), ref operand, _, ) => { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index e702503724240..0dbbc338e738b 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -286,8 +286,8 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, - PointerCoercion(PointerCoercion::DynStar) => stable_mir::mir::CastKind::DynStar, - PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), + PointerCoercion(PointerCoercion::DynStar, _) => stable_mir::mir::CastKind::DynStar, + PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 6434c2f42cfb9..ce1895b7fb19b 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -123,7 +123,7 @@ fn check_rvalue<'tcx>( | CastKind::FloatToFloat | CastKind::FnPtrToPtr | CastKind::PtrToPtr - | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer), + | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _), operand, _, ) => check_operand(tcx, operand, span, body, msrv), @@ -131,12 +131,12 @@ fn check_rvalue<'tcx>( CastKind::PointerCoercion( PointerCoercion::UnsafeFnPointer | PointerCoercion::ClosureFnPointer(_) - | PointerCoercion::ReifyFnPointer, + | PointerCoercion::ReifyFnPointer, _ ), _, _, ) => Err((span, "function pointer casts are not allowed in const fn".into())), - Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => { + Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize, _), op, cast_ty) => { let Some(pointee_ty) = cast_ty.builtin_deref(true) else { // We cannot allow this for now. return Err((span, "unsizing casts are only allowed for references right now".into())); @@ -154,7 +154,7 @@ fn check_rvalue<'tcx>( Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => { Err((span, "casting pointers to ints is unstable in const fn".into())) }, - Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar), _, _) => { + Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::DynStar, _), _, _) => { // FIXME(dyn-star) unimplemented!() }, diff --git a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr index b40f83e86541a..d0fd0e6fcc144 100644 --- a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr +++ b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.stderr @@ -2,7 +2,7 @@ error: Undefined Behavior: using vtable for `Baz` but `Bar` was expected --> tests/fail/dyn-upcast-trait-mismatch.rs:LL:CC | LL | let _err = baz_fake as *const dyn Foo; - | ^^^^^^^^ using vtable for `Baz` but `Bar` was expected + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ using vtable for `Baz` but `Bar` was expected | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index edf62a1e17398..ae445ad9b915b 100644 --- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -150,7 +150,7 @@ fn address_of_reborrow() -> () { StorageLive(_9); StorageLive(_10); _10 = &raw const (*_1); - _9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize)); + _9 = move _10 as *const dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_10); AscribeUserType(_9, o, UserTypeProjection { base: UserType(1), projs: [] }); _8 = copy _9; @@ -159,13 +159,13 @@ fn address_of_reborrow() -> () { StorageLive(_11); StorageLive(_12); _12 = &raw const (*_1); - _11 = move _12 as *const [i32] (PointerCoercion(Unsize)); + _11 = move _12 as *const [i32] (PointerCoercion(Unsize, AsCast)); StorageDead(_12); StorageDead(_11); StorageLive(_13); StorageLive(_14); _14 = &raw const (*_1); - _13 = move _14 as *const i32 (PointerCoercion(ArrayToPointer)); + _13 = move _14 as *const i32 (PointerCoercion(ArrayToPointer, AsCast)); StorageDead(_14); StorageDead(_13); StorageLive(_15); @@ -179,14 +179,14 @@ fn address_of_reborrow() -> () { StorageLive(_17); StorageLive(_18); _18 = &raw const (*_1); - _17 = move _18 as *const dyn std::marker::Send (PointerCoercion(Unsize)); + _17 = move _18 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); StorageDead(_18); FakeRead(ForLet(None), _17); AscribeUserType(_17, o, UserTypeProjection { base: UserType(7), projs: [] }); StorageLive(_19); StorageLive(_20); _20 = &raw const (*_1); - _19 = move _20 as *const [i32] (PointerCoercion(Unsize)); + _19 = move _20 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_20); FakeRead(ForLet(None), _19); AscribeUserType(_19, o, UserTypeProjection { base: UserType(9), projs: [] }); @@ -204,7 +204,7 @@ fn address_of_reborrow() -> () { StorageLive(_25); StorageLive(_26); _26 = &raw const (*_3); - _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize)); + _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_26); AscribeUserType(_25, o, UserTypeProjection { base: UserType(11), projs: [] }); _24 = copy _25; @@ -213,7 +213,7 @@ fn address_of_reborrow() -> () { StorageLive(_27); StorageLive(_28); _28 = &raw const (*_3); - _27 = move _28 as *const [i32] (PointerCoercion(Unsize)); + _27 = move _28 as *const [i32] (PointerCoercion(Unsize, AsCast)); StorageDead(_28); StorageDead(_27); StorageLive(_29); @@ -227,14 +227,14 @@ fn address_of_reborrow() -> () { StorageLive(_31); StorageLive(_32); _32 = &raw const (*_3); - _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize)); + _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); StorageDead(_32); FakeRead(ForLet(None), _31); AscribeUserType(_31, o, UserTypeProjection { base: UserType(17), projs: [] }); StorageLive(_33); StorageLive(_34); _34 = &raw const (*_3); - _33 = move _34 as *const [i32] (PointerCoercion(Unsize)); + _33 = move _34 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_34); FakeRead(ForLet(None), _33); AscribeUserType(_33, o, UserTypeProjection { base: UserType(19), projs: [] }); @@ -252,7 +252,7 @@ fn address_of_reborrow() -> () { StorageLive(_39); StorageLive(_40); _40 = &raw mut (*_3); - _39 = move _40 as *mut dyn std::marker::Send (PointerCoercion(Unsize)); + _39 = move _40 as *mut dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_40); AscribeUserType(_39, o, UserTypeProjection { base: UserType(21), projs: [] }); _38 = copy _39; @@ -261,7 +261,7 @@ fn address_of_reborrow() -> () { StorageLive(_41); StorageLive(_42); _42 = &raw mut (*_3); - _41 = move _42 as *mut [i32] (PointerCoercion(Unsize)); + _41 = move _42 as *mut [i32] (PointerCoercion(Unsize, AsCast)); StorageDead(_42); StorageDead(_41); StorageLive(_43); @@ -275,14 +275,14 @@ fn address_of_reborrow() -> () { StorageLive(_45); StorageLive(_46); _46 = &raw mut (*_3); - _45 = move _46 as *mut dyn std::marker::Send (PointerCoercion(Unsize)); + _45 = move _46 as *mut dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); StorageDead(_46); FakeRead(ForLet(None), _45); AscribeUserType(_45, o, UserTypeProjection { base: UserType(27), projs: [] }); StorageLive(_47); StorageLive(_48); _48 = &raw mut (*_3); - _47 = move _48 as *mut [i32] (PointerCoercion(Unsize)); + _47 = move _48 as *mut [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_48); FakeRead(ForLet(None), _47); AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); diff --git a/tests/mir-opt/build_correct_coerce.main.built.after.mir b/tests/mir-opt/build_correct_coerce.main.built.after.mir index 061174d69bb05..583a5ecd22702 100644 --- a/tests/mir-opt/build_correct_coerce.main.built.after.mir +++ b/tests/mir-opt/build_correct_coerce.main.built.after.mir @@ -9,7 +9,7 @@ fn main() -> () { bb0: { StorageLive(_1); - _1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer)); + _1 = foo as for<'a> fn(&'a (), &'a ()) (PointerCoercion(ReifyFnPointer, AsCast)); FakeRead(ForLet(None), _1); _0 = const (); StorageDead(_1); diff --git a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir index 296d71a319d1b..be972b62cbd31 100644 --- a/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir +++ b/tests/mir-opt/building/receiver_ptr_mutability.main.built.after.mir @@ -39,7 +39,7 @@ fn main() -> () { StorageLive(_3); StorageLive(_4); _4 = copy _1; - _3 = move _4 as *const Test (PointerCoercion(MutToConstPointer)); + _3 = move _4 as *const Test (PointerCoercion(MutToConstPointer, Implicit)); StorageDead(_4); _2 = Test::x(move _3) -> [return: bb2, unwind: bb4]; } @@ -64,7 +64,7 @@ fn main() -> () { StorageLive(_11); StorageLive(_12); _12 = copy (*(*(*(*_5)))); - _11 = move _12 as *const Test (PointerCoercion(MutToConstPointer)); + _11 = move _12 as *const Test (PointerCoercion(MutToConstPointer, Implicit)); StorageDead(_12); _10 = Test::x(move _11) -> [return: bb3, unwind: bb4]; } diff --git a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir index 683f63065f76b..73ead005f8c62 100644 --- a/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir +++ b/tests/mir-opt/building/storage_live_dead_in_statics.XXX.built.after.mir @@ -187,7 +187,7 @@ static XXX: &Foo = { StorageDead(_7); _5 = &_6; _4 = &(*_5); - _3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize)); + _3 = move _4 as &[(u32, u32)] (PointerCoercion(Unsize, Implicit)); StorageDead(_4); _2 = Foo { tup: const "hi", data: move _3 }; StorageDead(_3); diff --git a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index f412048b6ec7e..487f68a8d4dfe 100644 --- a/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -22,7 +22,7 @@ - _2 = &_3; + _6 = const BAR::promoted[0]; + _2 = &(*_6); - _1 = move _2 as &[&i32] (PointerCoercion(Unsize)); + _1 = move _2 as &[&i32] (PointerCoercion(Unsize, Implicit)); - StorageDead(_4); StorageDead(_2); _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index bfefd2b8c95c6..0e4eed2c028d0 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -22,7 +22,7 @@ - _2 = &_3; + _6 = const FOO::promoted[0]; + _2 = &(*_6); - _1 = move _2 as &[&i32] (PointerCoercion(Unsize)); + _1 = move _2 as &[&i32] (PointerCoercion(Unsize, Implicit)); - StorageDead(_4); StorageDead(_2); _0 = core::slice::::as_ptr(move _1) -> [return: bb1, unwind: bb2]; diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff index 52aa4da49efaf..15d3014036713 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff @@ -26,7 +26,7 @@ _9 = const main::promoted[0]; _3 = &(*_9); _2 = &raw const (*_3); - _1 = move _2 as *const [i32] (PointerCoercion(Unsize)); + _1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_2); StorageDead(_3); StorageLive(_5); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff index 242ff0e664f1d..dd411d84f9fbe 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff @@ -26,7 +26,7 @@ _9 = const main::promoted[0]; _3 = &(*_9); _2 = &raw const (*_3); - _1 = move _2 as *const [i32] (PointerCoercion(Unsize)); + _1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_2); StorageDead(_3); StorageLive(_5); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff index 52aa4da49efaf..15d3014036713 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff @@ -26,7 +26,7 @@ _9 = const main::promoted[0]; _3 = &(*_9); _2 = &raw const (*_3); - _1 = move _2 as *const [i32] (PointerCoercion(Unsize)); + _1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_2); StorageDead(_3); StorageLive(_5); diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff index 242ff0e664f1d..dd411d84f9fbe 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff @@ -26,7 +26,7 @@ _9 = const main::promoted[0]; _3 = &(*_9); _2 = &raw const (*_3); - _1 = move _2 as *const [i32] (PointerCoercion(Unsize)); + _1 = move _2 as *const [i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_2); StorageDead(_3); StorageLive(_5); diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff index e5786bcf701ef..50a17326c2aae 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff +++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff @@ -13,7 +13,7 @@ StorageLive(_1); StorageLive(_2); StorageLive(_3); - _3 = main as fn() (PointerCoercion(ReifyFnPointer)); + _3 = main as fn() (PointerCoercion(ReifyFnPointer, AsCast)); _2 = move _3 as usize (PointerExposeProvenance); StorageDead(_3); _1 = move _2 as *const fn() (PointerWithExposedProvenance); diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs index ffce4e97f5de1..d56f21e586aa8 100644 --- a/tests/mir-opt/const_prop/reify_fn_ptr.rs +++ b/tests/mir-opt/const_prop/reify_fn_ptr.rs @@ -3,7 +3,7 @@ fn main() { // CHECK-LABEL: fn main( - // CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer)); + // CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer, AsCast)); // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeProvenance); // CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance); let _ = main as usize as *const fn(); diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff index e834a5802c33f..41ce94eda7517 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff @@ -24,9 +24,9 @@ _9 = const main::promoted[0]; _4 = copy _9; - _3 = copy _4; -- _2 = move _3 as &[u32] (PointerCoercion(Unsize)); +- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize)); ++ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff index 55ffc50180569..8cced96cd4331 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff @@ -24,9 +24,9 @@ _9 = const main::promoted[0]; _4 = copy _9; - _3 = copy _4; -- _2 = move _3 as &[u32] (PointerCoercion(Unsize)); +- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize)); ++ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff index e834a5802c33f..41ce94eda7517 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff @@ -24,9 +24,9 @@ _9 = const main::promoted[0]; _4 = copy _9; - _3 = copy _4; -- _2 = move _3 as &[u32] (PointerCoercion(Unsize)); +- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize)); ++ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff index 55ffc50180569..8cced96cd4331 100644 --- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff @@ -24,9 +24,9 @@ _9 = const main::promoted[0]; _4 = copy _9; - _3 = copy _4; -- _2 = move _3 as &[u32] (PointerCoercion(Unsize)); +- _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + _3 = copy _9; -+ _2 = copy _9 as &[u32] (PointerCoercion(Unsize)); ++ _2 = copy _9 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/const_prop/slice_len.rs b/tests/mir-opt/const_prop/slice_len.rs index 46604cfe1e091..ebd3c9e792dca 100644 --- a/tests/mir-opt/const_prop/slice_len.rs +++ b/tests/mir-opt/const_prop/slice_len.rs @@ -7,7 +7,7 @@ fn main() { // CHECK-LABEL: fn main( // CHECK: debug a => [[a:_.*]]; - // CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize)); + // CHECK: [[slice:_.*]] = copy {{.*}} as &[u32] (PointerCoercion(Unsize, AsCast)); // CHECK: assert(const true, // CHECK: [[a]] = const 2_u32; let a = (&[1u32, 2, 3] as &[u32])[1]; diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff index f4411886f9a7a..6d967257df1f5 100644 --- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff @@ -47,7 +47,7 @@ StorageLive(_6); StorageLive(_7); _7 = &_2; - _6 = move _7 as &[i32] (PointerCoercion(Unsize)); + _6 = move _7 as &[i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); _5 = core::slice::::len(move _6) -> [return: bb1, unwind unreachable]; } diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff index 833588aa4e920..3580c87c46995 100644 --- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff +++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff @@ -47,7 +47,7 @@ StorageLive(_6); StorageLive(_7); _7 = &_2; - _6 = move _7 as &[i32] (PointerCoercion(Unsize)); + _6 = move _7 as &[i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); _5 = core::slice::::len(move _6) -> [return: bb1, unwind continue]; } diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff index c7870a7902b98..e62fcb66e3a6d 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff @@ -89,7 +89,7 @@ - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize)); +- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff index f5de7a361bc10..8183abd315ae5 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff @@ -93,7 +93,7 @@ - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize)); +- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff index 3b0bc6377da62..4fa6ef29e0697 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff @@ -89,7 +89,7 @@ - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize)); +- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff index 5dd7ad9a11773..753292045632f 100644 --- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff @@ -93,7 +93,7 @@ - _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> }; + _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }}; StorageDead(_5); -- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize)); +- _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize, Implicit)); + _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}; StorageDead(_4); - _2 = Box::<[bool]>(copy _3, const std::alloc::Global); diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff index 40632db667a8d..e71992316dcf4 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff @@ -32,7 +32,7 @@ _14 = const main::promoted[0]; _4 = copy _14; _3 = copy _4; - _2 = move _3 as &[u32] (PointerCoercion(Unsize)); + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff index 596b4ac9b1e5b..26de859576896 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff @@ -32,7 +32,7 @@ _14 = const main::promoted[0]; _4 = copy _14; _3 = copy _4; - _2 = move _3 as &[u32] (PointerCoercion(Unsize)); + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff index 40632db667a8d..e71992316dcf4 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff @@ -32,7 +32,7 @@ _14 = const main::promoted[0]; _4 = copy _14; _3 = copy _4; - _2 = move _3 as &[u32] (PointerCoercion(Unsize)); + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff index 596b4ac9b1e5b..26de859576896 100644 --- a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff @@ -32,7 +32,7 @@ _14 = const main::promoted[0]; _4 = copy _14; _3 = copy _4; - _2 = move _3 as &[u32] (PointerCoercion(Unsize)); + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); StorageDead(_3); StorageLive(_6); _6 = const 1_usize; diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff index 90654e0566284..0d0477fe7729f 100644 --- a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff @@ -16,7 +16,7 @@ + nop; StorageLive(_3); _3 = &(*_1); - _2 = move _3 as &[i32] (PointerCoercion(Unsize)); + _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageLive(_4); _4 = &raw const (*_2); diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff index 90654e0566284..0d0477fe7729f 100644 --- a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff @@ -16,7 +16,7 @@ + nop; StorageLive(_3); _3 = &(*_1); - _2 = move _3 as &[i32] (PointerCoercion(Unsize)); + _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageLive(_4); _4 = &raw const (*_2); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff index 292b812b50c85..130b011630cc2 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-abort.diff @@ -37,7 +37,7 @@ bb0: { - StorageLive(_1); + nop; - _1 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer)); + _1 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast)); StorageLive(_2); StorageLive(_3); _3 = copy _1; @@ -50,7 +50,7 @@ StorageDead(_2); - StorageLive(_4); + nop; - _4 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer)); + _4 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast)); StorageLive(_5); StorageLive(_6); _6 = copy _4; @@ -69,9 +69,9 @@ + nop; StorageLive(_9); - _9 = copy _7; -- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe))); +- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); + _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -87,9 +87,9 @@ + nop; StorageLive(_13); - _13 = copy _7; -- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe))); +- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); + _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff index a60d986132e56..372a08d547306 100644 --- a/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.fn_pointers.GVN.panic-unwind.diff @@ -37,7 +37,7 @@ bb0: { - StorageLive(_1); + nop; - _1 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer)); + _1 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast)); StorageLive(_2); StorageLive(_3); _3 = copy _1; @@ -50,7 +50,7 @@ StorageDead(_2); - StorageLive(_4); + nop; - _4 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer)); + _4 = identity:: as fn(u8) -> u8 (PointerCoercion(ReifyFnPointer, AsCast)); StorageLive(_5); StorageLive(_6); _6 = copy _4; @@ -69,9 +69,9 @@ + nop; StorageLive(_9); - _9 = copy _7; -- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe))); +- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); + _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_9); StorageLive(_10); StorageLive(_11); @@ -87,9 +87,9 @@ + nop; StorageLive(_13); - _13 = copy _7; -- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe))); +- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); + _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21}; -+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe))); ++ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe), AsCast)); StorageDead(_13); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff index c58362e391c43..43cd8ba7809a2 100644 --- a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-abort.diff @@ -64,10 +64,10 @@ _44 = const wide_ptr_provenance::promoted[1]; _5 = &(*_44); _4 = &(*_5); - _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_4); _2 = &raw const (*_3); -- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_2); + _1 = copy _2; + nop; @@ -82,10 +82,10 @@ _43 = const wide_ptr_provenance::promoted[0]; _11 = &(*_43); _10 = &(*_11); - _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_10); _8 = &raw const (*_9); -- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_8); + _7 = copy _8; + nop; @@ -99,7 +99,7 @@ StorageLive(_16); StorageLive(_17); - _17 = copy _7; -- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _17 = copy _8; + _16 = copy _8; StorageDead(_17); @@ -121,7 +121,7 @@ StorageLive(_21); StorageLive(_22); - _22 = copy _7; -- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _22 = copy _8; + _21 = copy _8; StorageDead(_22); @@ -143,7 +143,7 @@ StorageLive(_26); StorageLive(_27); - _27 = copy _7; -- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _27 = copy _8; + _26 = copy _8; StorageDead(_27); @@ -165,7 +165,7 @@ StorageLive(_31); StorageLive(_32); - _32 = copy _7; -- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _32 = copy _8; + _31 = copy _8; StorageDead(_32); @@ -187,7 +187,7 @@ StorageLive(_36); StorageLive(_37); - _37 = copy _7; -- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _37 = copy _8; + _36 = copy _8; StorageDead(_37); @@ -209,7 +209,7 @@ StorageLive(_41); StorageLive(_42); - _42 = copy _7; -- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _42 = copy _8; + _41 = copy _8; StorageDead(_42); diff --git a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff index b29ee862c81a3..49cca20153bd4 100644 --- a/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wide_ptr_provenance.GVN.panic-unwind.diff @@ -64,10 +64,10 @@ _44 = const wide_ptr_provenance::promoted[1]; _5 = &(*_44); _4 = &(*_5); - _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _3 = move _4 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_4); _2 = &raw const (*_3); -- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _1 = move _2 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_2); + _1 = copy _2; + nop; @@ -82,10 +82,10 @@ _43 = const wide_ptr_provenance::promoted[0]; _11 = &(*_43); _10 = &(*_11); - _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _9 = move _10 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_10); _8 = &raw const (*_9); -- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _7 = move _8 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_8); + _7 = copy _8; + nop; @@ -99,7 +99,7 @@ StorageLive(_16); StorageLive(_17); - _17 = copy _7; -- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _16 = move _17 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _17 = copy _8; + _16 = copy _8; StorageDead(_17); @@ -121,7 +121,7 @@ StorageLive(_21); StorageLive(_22); - _22 = copy _7; -- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _21 = move _22 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _22 = copy _8; + _21 = copy _8; StorageDead(_22); @@ -143,7 +143,7 @@ StorageLive(_26); StorageLive(_27); - _27 = copy _7; -- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _26 = move _27 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _27 = copy _8; + _26 = copy _8; StorageDead(_27); @@ -165,7 +165,7 @@ StorageLive(_31); StorageLive(_32); - _32 = copy _7; -- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _31 = move _32 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _32 = copy _8; + _31 = copy _8; StorageDead(_32); @@ -187,7 +187,7 @@ StorageLive(_36); StorageLive(_37); - _37 = copy _7; -- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _36 = move _37 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _37 = copy _8; + _36 = copy _8; StorageDead(_37); @@ -209,7 +209,7 @@ StorageLive(_41); StorageLive(_42); - _42 = copy _7; -- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _41 = move _42 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _42 = copy _8; + _41 = copy _8; StorageDead(_42); diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff index f4c38b7ab071e..6b6152c1117e3 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff @@ -86,10 +86,10 @@ - _7 = &(*_1)[_8]; + _7 = &(*_1)[0 of 1]; _6 = &(*_7); - _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_6); _4 = &raw const (*_5); -- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_4); + _3 = copy _4; + nop; @@ -115,10 +115,10 @@ - _15 = &(*_1)[_16]; + _15 = &(*_1)[1 of 2]; _14 = &(*_15); - _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_14); _12 = &raw const (*_13); -- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_12); + _11 = copy _12; + nop; @@ -132,7 +132,7 @@ StorageLive(_22); StorageLive(_23); - _23 = copy _11; -- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _23 = copy _12; + _22 = copy _12; StorageDead(_23); @@ -154,7 +154,7 @@ StorageLive(_27); StorageLive(_28); - _28 = copy _11; -- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _28 = copy _12; + _27 = copy _12; StorageDead(_28); @@ -176,7 +176,7 @@ StorageLive(_32); StorageLive(_33); - _33 = copy _11; -- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _33 = copy _12; + _32 = copy _12; StorageDead(_33); @@ -198,7 +198,7 @@ StorageLive(_37); StorageLive(_38); - _38 = copy _11; -- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _38 = copy _12; + _37 = copy _12; StorageDead(_38); @@ -220,7 +220,7 @@ StorageLive(_42); StorageLive(_43); - _43 = copy _11; -- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _43 = copy _12; + _42 = copy _12; StorageDead(_43); @@ -242,7 +242,7 @@ StorageLive(_47); StorageLive(_48); - _48 = copy _11; -- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _48 = copy _12; + _47 = copy _12; StorageDead(_48); diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff index 03f2d129a9b6f..093c1ec6ce379 100644 --- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff @@ -86,10 +86,10 @@ - _7 = &(*_1)[_8]; + _7 = &(*_1)[0 of 1]; _6 = &(*_7); - _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _5 = move _6 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_6); _4 = &raw const (*_5); -- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _3 = move _4 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_4); + _3 = copy _4; + nop; @@ -115,10 +115,10 @@ - _15 = &(*_1)[_16]; + _15 = &(*_1)[1 of 2]; _14 = &(*_15); - _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize)); + _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast)); StorageDead(_14); _12 = &raw const (*_13); -- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); - StorageDead(_12); + _11 = copy _12; + nop; @@ -132,7 +132,7 @@ StorageLive(_22); StorageLive(_23); - _23 = copy _11; -- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _23 = copy _12; + _22 = copy _12; StorageDead(_23); @@ -154,7 +154,7 @@ StorageLive(_27); StorageLive(_28); - _28 = copy _11; -- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _28 = copy _12; + _27 = copy _12; StorageDead(_28); @@ -176,7 +176,7 @@ StorageLive(_32); StorageLive(_33); - _33 = copy _11; -- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _33 = copy _12; + _32 = copy _12; StorageDead(_33); @@ -198,7 +198,7 @@ StorageLive(_37); StorageLive(_38); - _38 = copy _11; -- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _38 = copy _12; + _37 = copy _12; StorageDead(_38); @@ -220,7 +220,7 @@ StorageLive(_42); StorageLive(_43); - _43 = copy _11; -- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _43 = copy _12; + _42 = copy _12; StorageDead(_43); @@ -242,7 +242,7 @@ StorageLive(_47); StorageLive(_48); - _48 = copy _11; -- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize)); +- _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit)); + _48 = copy _12; + _47 = copy _12; StorageDead(_48); diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff index 2d64d49ce5c13..df79001ce75b6 100644 --- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-abort.diff @@ -31,7 +31,7 @@ _4 = copy _2; - _0 = try_execute_query::<::C>(move _4) -> [return: bb2, unwind unreachable]; + StorageLive(_5); -+ _5 = copy _4 as &dyn Cache::V> (PointerCoercion(Unsize)); ++ _5 = copy _4 as &dyn Cache::V> (PointerCoercion(Unsize, Implicit)); + _0 = ::V> as Cache>::store_nocache(move _5) -> [return: bb2, unwind unreachable]; } diff --git a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff index c5e9654e19cfd..014f950940c5f 100644 --- a/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/dyn_trait.get_query.Inline.panic-unwind.diff @@ -31,7 +31,7 @@ _4 = copy _2; - _0 = try_execute_query::<::C>(move _4) -> [return: bb2, unwind continue]; + StorageLive(_5); -+ _5 = copy _4 as &dyn Cache::V> (PointerCoercion(Unsize)); ++ _5 = copy _4 as &dyn Cache::V> (PointerCoercion(Unsize, Implicit)); + _0 = ::V> as Cache>::store_nocache(move _5) -> [return: bb2, unwind continue]; } diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff index f02ca6233173f..64d12461e8de1 100644 --- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-abort.diff @@ -14,7 +14,7 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; - _2 = move _3 as &dyn Cache::V> (PointerCoercion(Unsize)); + _2 = move _3 as &dyn Cache::V> (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = mk_cycle::<::V>(move _2) -> [return: bb1, unwind unreachable]; + _0 = ::V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind unreachable]; diff --git a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff index 31080dff4ded7..21791cb0d2a59 100644 --- a/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/dyn_trait.try_execute_query.Inline.panic-unwind.diff @@ -14,7 +14,7 @@ StorageLive(_2); StorageLive(_3); _3 = copy _1; - _2 = move _3 as &dyn Cache::V> (PointerCoercion(Unsize)); + _2 = move _3 as &dyn Cache::V> (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = mk_cycle::<::V>(move _2) -> [return: bb1, unwind continue]; + _0 = ::V> as Cache>::store_nocache(move _2) -> [return: bb1, unwind continue]; diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index f03691ad67316..c02bab3524bca 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -26,7 +26,7 @@ StorageLive(_4); _4 = [copy _1, copy _1, copy _1]; _3 = &_4; - _2 = copy _3 as &[T] (PointerCoercion(Unsize)); + _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); nop; nop; goto -> bb2; diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 633e5c740a1a8..49be042588cb3 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -26,7 +26,7 @@ StorageLive(_4); _4 = [copy _1, copy _1, copy _1]; _3 = &_4; - _2 = copy _3 as &[T] (PointerCoercion(Unsize)); + _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); nop; nop; goto -> bb2; diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff index 8223cbbb41216..f052c8f63dcaa 100644 --- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff @@ -24,7 +24,7 @@ StorageLive(_6); StorageLive(_7); _7 = &(*_2); - _6 = move _7 as &[u8] (PointerCoercion(Unsize)); + _6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); - _5 = PtrMetadata(move _6); + _5 = const N; diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff index d8f33accbc005..3299e3004317d 100644 --- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff @@ -24,7 +24,7 @@ StorageLive(_6); StorageLive(_7); _7 = &(*_2); - _6 = move _7 as &[u8] (PointerCoercion(Unsize)); + _6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); - _5 = PtrMetadata(move _6); + _5 = const N; diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff index 1cb9963c00e94..329eb80b3c4f5 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff @@ -27,7 +27,7 @@ StorageLive(_6); StorageLive(_7); _7 = &(*_2); - _6 = move _7 as &[u8] (PointerCoercion(Unsize)); + _6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); - _5 = PtrMetadata(move _6); + _5 = const N; diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff index fa4e11ed20192..ab007e133ecc1 100644 --- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff @@ -27,7 +27,7 @@ StorageLive(_6); StorageLive(_7); _7 = &(*_2); - _6 = move _7 as &[u8] (PointerCoercion(Unsize)); + _6 = move _7 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_7); - _5 = PtrMetadata(move _6); + _5 = const N; diff --git a/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff index 9c1b9a708c59a..369bd2f473297 100644 --- a/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len.GVN.panic-abort.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = &(*_1); - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = PtrMetadata(move _2); + _0 = const N; diff --git a/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff index 9c1b9a708c59a..369bd2f473297 100644 --- a/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len.GVN.panic-unwind.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = &(*_1); - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = PtrMetadata(move _2); + _0 = const N; diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff index 97fa503ac2e46..d9c289bf58aee 100644 --- a/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-abort.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = &_1; - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = PtrMetadata(move _2); + _0 = const N; diff --git a/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff index 97fa503ac2e46..d9c289bf58aee 100644 --- a/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_by_value.GVN.panic-unwind.diff @@ -11,7 +11,7 @@ StorageLive(_2); StorageLive(_3); _3 = &_1; - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); - _0 = PtrMetadata(move _2); + _0 = const N; diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff index b5e8b66813ae3..180a7db029794 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff @@ -24,7 +24,7 @@ StorageLive(_4); _4 = &_1; _3 = &(*_4); - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageDead(_4); StorageLive(_5); diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff index b5e8b66813ae3..180a7db029794 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff @@ -24,7 +24,7 @@ StorageLive(_4); _4 = &_1; _3 = &(*_4); - _2 = move _3 as &[u8] (PointerCoercion(Unsize)); + _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageDead(_4); StorageLive(_5); diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff index 0299c6acd804a..49964f8b49e26 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff @@ -23,7 +23,7 @@ StorageLive(_4); _4 = &mut _1; _3 = &mut (*_4); - _2 = move _3 as &mut [u8] (PointerCoercion(Unsize)); + _2 = move _3 as &mut [u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageDead(_4); StorageLive(_5); diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff index 0299c6acd804a..49964f8b49e26 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff @@ -23,7 +23,7 @@ StorageLive(_4); _4 = &mut _1; _3 = &mut (*_4); - _2 = move _3 as &mut [u8] (PointerCoercion(Unsize)); + _2 = move _3 as &mut [u8] (PointerCoercion(Unsize, Implicit)); StorageDead(_3); StorageDead(_4); StorageLive(_5); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 6cac8b109eea6..87fbcca917736 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -93,7 +93,7 @@ bb5: { StorageLive(_15); _16 = &_13; - _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 10fde25e3178b..13258c171605c 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -93,7 +93,7 @@ bb5: { StorageLive(_15); _16 = &_13; - _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + _15 = copy _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize, Implicit)); _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } diff --git a/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir index d0f454e456934..cca2b3ae188c3 100644 --- a/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir +++ b/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -105,7 +105,7 @@ fn main() -> () { StorageLive(_14); _14 = {closure@main::{closure#0}}; Retag(_14); - _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe))); + _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe), Implicit)); StorageDead(_14); StorageLive(_15); StorageLive(_16); diff --git a/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index 685277d7a5328..bcd3a47ac04fb 100644 --- a/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/retag.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -105,7 +105,7 @@ fn main() -> () { StorageLive(_14); _14 = {closure@main::{closure#0}}; Retag(_14); - _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe))); + _13 = move _14 as for<'a> fn(&'a i32) -> &'a i32 (PointerCoercion(ClosureFnPointer(Safe), Implicit)); StorageDead(_14); StorageLive(_15); StorageLive(_16); diff --git a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff index 7cc5e335cb00a..37a669d72b85e 100644 --- a/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff +++ b/tests/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff @@ -21,7 +21,7 @@ - StorageLive(_4); - _4 = &_1; - _3 = &(*_4); -- _2 = move _3 as &[u8] (PointerCoercion(Unsize)); +- _2 = move _3 as &[u8] (PointerCoercion(Unsize, Implicit)); - StorageDead(_3); - StorageDead(_4); - StorageDead(_2); diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 478dacc327668..a1df868cde051 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -61,7 +61,7 @@ } bb1: { - _3 = move _4 as std::boxed::Box (PointerCoercion(Unsize)); + _3 = move _4 as std::boxed::Box (PointerCoercion(Unsize, Implicit)); StorageDead(_4); _2 = Result::, ::Err>::Ok(move _3); StorageDead(_3); diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr index 6bd6a0584c9f1..e4cd54ac33741 100644 --- a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr +++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -7,7 +7,7 @@ LL | let refcell = RefCell::new(&mut foo); | ^^^^^^^^ borrowed value does not live long enough LL | LL | let read = &refcell as &RefCell; - | -------- coercion requires that `foo` is borrowed for `'static` + | ------------------------------ cast requires that `foo` is borrowed for `'static` ... LL | } | - `foo` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | fn inner(mut foo: &[u8]) { | - let's call the lifetime of this reference `'1` ... LL | let read = &refcell as &RefCell; - | ^^^^^^^^ coercion requires that `'1` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/regions/regions-close-object-into-object-4.stderr b/tests/ui/regions/regions-close-object-into-object-4.stderr index b8b414b7e125e..f6a79be09477c 100644 --- a/tests/ui/regions/regions-close-object-into-object-4.stderr +++ b/tests/ui/regions/regions-close-object-into-object-4.stderr @@ -30,12 +30,11 @@ error[E0310]: the parameter type `U` may not live long enough --> $DIR/regions-close-object-into-object-4.rs:9:5 | LL | Box::new(B(&*v)) as Box - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `U` must be valid for the static lifetime... | ...so that the type `U` will meet its required lifetime bounds | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider adding an explicit lifetime bound | LL | fn i<'a, T, U: 'static>(v: Box+'a>) -> Box { diff --git a/tests/ui/regions/regions-close-object-into-object-5.stderr b/tests/ui/regions/regions-close-object-into-object-5.stderr index 4a2f4f847a308..881d9e03cdfab 100644 --- a/tests/ui/regions/regions-close-object-into-object-5.stderr +++ b/tests/ui/regions/regions-close-object-into-object-5.stderr @@ -30,12 +30,11 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/regions-close-object-into-object-5.rs:17:5 | LL | Box::new(B(&*v)) as Box - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `T` must be valid for the static lifetime... | ...so that the type `T` will meet its required lifetime bounds | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider adding an explicit lifetime bound | LL | fn f<'a, T: 'static, U>(v: Box + 'static>) -> Box { diff --git a/tests/ui/regions/regions-close-over-type-parameter-1.stderr b/tests/ui/regions/regions-close-over-type-parameter-1.stderr index 1cd5b7f225079..7c8c5fe5cf68b 100644 --- a/tests/ui/regions/regions-close-over-type-parameter-1.stderr +++ b/tests/ui/regions/regions-close-over-type-parameter-1.stderr @@ -2,7 +2,7 @@ error[E0310]: the parameter type `A` may not live long enough --> $DIR/regions-close-over-type-parameter-1.rs:11:5 | LL | Box::new(v) as Box - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `A` must be valid for the static lifetime... | ...so that the type `A` will meet its required lifetime bounds @@ -18,7 +18,7 @@ error[E0309]: the parameter type `A` may not live long enough LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box { | -- the parameter type `A` must be valid for the lifetime `'b` as defined here... LL | Box::new(v) as Box - | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr index 050ef7da9b936..fa203150444c8 100644 --- a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr +++ b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | fn foo(value: &T) -> Box { | - let's call the lifetime of this reference `'1` LL | Box::new(value) as Box - | ^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | From 39f66baa68ed3ad0d60eb31020dd00ca2c05f811 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Wed, 11 Sep 2024 01:16:10 +0200 Subject: [PATCH 13/14] improve errors for invalid pointer casts --- compiler/rustc_hir_typeck/src/cast.rs | 122 +++++++++++++----- tests/ui/cast/casts-differing-anon.stderr | 2 +- .../cast/ptr-to-trait-obj-different-args.rs | 8 +- .../ptr-to-trait-obj-different-args.stderr | 41 ++---- .../cast/ptr-to-trait-obj-wrap-upcast.stderr | 2 +- tests/ui/mismatched_types/cast-rfc0401.stderr | 8 +- tests/ui/traits/upcast_soundness_bug.rs | 2 +- tests/ui/traits/upcast_soundness_bug.stderr | 10 +- 8 files changed, 121 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 9e20e1d9745a7..fcd2940b83ae3 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,6 +32,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; @@ -152,12 +153,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[derive(Copy, Clone, Debug)] -pub enum CastError { +enum CastError<'tcx> { ErrorGuaranteed(ErrorGuaranteed), CastToBool, CastToChar, - DifferingKinds, + DifferingKinds { + src_kind: PointerKind<'tcx>, + dst_kind: PointerKind<'tcx>, + }, /// Cast of thin to fat raw ptr (e.g., `*const () as *const [u8]`). SizedUnsizedCast, IllegalCast, @@ -177,7 +181,7 @@ pub enum CastError { ForeignNonExhaustiveAdt, } -impl From for CastError { +impl From for CastError<'_> { fn from(err: ErrorGuaranteed) -> Self { CastError::ErrorGuaranteed(err) } @@ -251,7 +255,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } - fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError) { + fn report_cast_error(&self, fcx: &FnCtxt<'a, 'tcx>, e: CastError<'tcx>) { match e { CastError::ErrorGuaranteed(_) => { // an error has already been reported @@ -303,10 +307,52 @@ impl<'a, 'tcx> CastCheck<'tcx> { CastError::IllegalCast => { make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx).emit(); } - CastError::DifferingKinds => { - make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx) - .with_note("vtable kinds may not match") - .emit(); + CastError::DifferingKinds { src_kind, dst_kind } => { + let mut err = + make_invalid_casting_error(self.span, self.expr_ty, self.cast_ty, fcx); + + match (src_kind, dst_kind) { + (PointerKind::VTable(_), PointerKind::VTable(_)) => { + err.note("the trait objects may have different vtables"); + } + ( + PointerKind::OfParam(_) | PointerKind::OfAlias(_), + PointerKind::OfParam(_) + | PointerKind::OfAlias(_) + | PointerKind::VTable(_) + | PointerKind::Length, + ) + | ( + PointerKind::VTable(_) | PointerKind::Length, + PointerKind::OfParam(_) | PointerKind::OfAlias(_), + ) => { + err.note("the pointers may have different metadata"); + } + (PointerKind::VTable(_), PointerKind::Length) + | (PointerKind::Length, PointerKind::VTable(_)) => { + err.note("the pointers have different metadata"); + } + ( + PointerKind::Thin, + PointerKind::Thin + | PointerKind::VTable(_) + | PointerKind::Length + | PointerKind::OfParam(_) + | PointerKind::OfAlias(_), + ) + | ( + PointerKind::VTable(_) + | PointerKind::Length + | PointerKind::OfParam(_) + | PointerKind::OfAlias(_), + PointerKind::Thin, + ) + | (PointerKind::Length, PointerKind::Length) => { + span_bug!(self.span, "unexpected cast error: {e:?}") + } + } + + err.emit(); } CastError::CastToBool => { let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); @@ -670,7 +716,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { /// Checks a cast, and report an error if one exists. In some cases, this /// can return Ok and create type errors in the fcx rather than returning /// directly. coercion-cast is handled in check instead of here. - fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result { + fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result> { use rustc_middle::ty::cast::CastTy::*; use rustc_middle::ty::cast::IntTy::*; @@ -798,27 +844,34 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx: &FnCtxt<'a, 'tcx>, m_src: ty::TypeAndMut<'tcx>, m_dst: ty::TypeAndMut<'tcx>, - ) -> Result { + ) -> Result> { debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}"); - // ptr-ptr cast. vtables must match. + // ptr-ptr cast. metadata must match. let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?); let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?); - match (src_kind, dst_kind) { - // We can't cast if target pointer kind is unknown - (_, None) => Err(CastError::UnknownCastPtrKind), - // Cast to thin pointer is OK - (_, Some(PointerKind::Thin)) => Ok(CastKind::PtrPtrCast), + // We can't cast if target pointer kind is unknown + let Some(dst_kind) = dst_kind else { + return Err(CastError::UnknownCastPtrKind); + }; + + // Cast to thin pointer is OK + if dst_kind == PointerKind::Thin { + return Ok(CastKind::PtrPtrCast); + } - // We can't cast to fat pointer if source pointer kind is unknown - (None, _) => Err(CastError::UnknownExprPtrKind), + // We can't cast to fat pointer if source pointer kind is unknown + let Some(src_kind) = src_kind else { + return Err(CastError::UnknownCastPtrKind); + }; + match (src_kind, dst_kind) { // thin -> fat? report invalid cast (don't complain about vtable kinds) - (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast), + (PointerKind::Thin, _) => Err(CastError::SizedUnsizedCast), // trait object -> trait object? need to do additional checks - (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { + (PointerKind::VTable(src_tty), PointerKind::VTable(dst_tty)) => { match (src_tty.principal(), dst_tty.principal()) { // A + SrcAuto> -> B + DstAuto>. need to make sure // - `Src` and `Dst` traits are the same @@ -834,7 +887,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) // and is unaffected by this check. if src_principal.def_id() != dst_principal.def_id() { - return Err(CastError::DifferingKinds); + return Err(CastError::DifferingKinds { src_kind, dst_kind }); } // We need to reconstruct trait object types. @@ -860,7 +913,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { )); // `dyn Src = dyn Dst`, this checks for matching traits/generics - fcx.demand_eqtype(self.span, src_obj, dst_obj); + // This is `demand_eqtype`, but inlined to give a better error. + let cause = fcx.misc(self.span); + if fcx + .at(&cause, fcx.param_env) + .eq(DefineOpaqueTypes::Yes, src_obj, dst_obj) + .map(|infer_ok| fcx.register_infer_ok_obligations(infer_ok)) + .is_err() + { + return Err(CastError::DifferingKinds { src_kind, dst_kind }); + } // Check that `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto`. // Emit an FCW otherwise. @@ -905,17 +967,17 @@ impl<'a, 'tcx> CastCheck<'tcx> { // dyn Trait -> dyn Auto? should be ok, but we used to not allow it. // FIXME: allow this - (Some(_), None) => Err(CastError::DifferingKinds), + (Some(_), None) => Err(CastError::DifferingKinds { src_kind, dst_kind }), // dyn Auto -> dyn Trait? not ok. - (None, Some(_)) => Err(CastError::DifferingKinds), + (None, Some(_)) => Err(CastError::DifferingKinds { src_kind, dst_kind }), } } // fat -> fat? metadata kinds must match - (Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast), + (src_kind, dst_kind) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast), - (_, _) => Err(CastError::DifferingKinds), + (_, _) => Err(CastError::DifferingKinds { src_kind, dst_kind }), } } @@ -923,7 +985,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_cast: ty::TypeAndMut<'tcx>, - ) -> Result { + ) -> Result> { // fptr-ptr cast. must be to thin ptr match fcx.pointer_kind(m_cast.ty, self.span)? { @@ -937,7 +999,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_expr: ty::TypeAndMut<'tcx>, - ) -> Result { + ) -> Result> { // ptr-addr cast. must be from thin ptr match fcx.pointer_kind(m_expr.ty, self.span)? { @@ -952,7 +1014,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx: &FnCtxt<'a, 'tcx>, m_expr: ty::TypeAndMut<'tcx>, m_cast: ty::TypeAndMut<'tcx>, - ) -> Result { + ) -> Result> { // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const if m_expr.mutbl >= m_cast.mutbl { if let ty::Array(ety, _) = m_expr.ty.kind() { @@ -987,7 +1049,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { &self, fcx: &FnCtxt<'a, 'tcx>, m_cast: TypeAndMut<'tcx>, - ) -> Result { + ) -> Result> { // ptr-addr cast. pointer must be thin. match fcx.pointer_kind(m_cast.ty, self.span)? { None => Err(CastError::UnknownCastPtrKind), diff --git a/tests/ui/cast/casts-differing-anon.stderr b/tests/ui/cast/casts-differing-anon.stderr index 8ddd97137c30d..fc4882d2d2774 100644 --- a/tests/ui/cast/casts-differing-anon.stderr +++ b/tests/ui/cast/casts-differing-anon.stderr @@ -4,7 +4,7 @@ error[E0606]: casting `*mut impl Debug + ?Sized` as `*mut impl Debug + ?Sized` i LL | b_raw = f_raw as *mut _; | ^^^^^^^^^^^^^^^ | - = note: vtable kinds may not match + = note: the pointers may have different metadata error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index c6038cfe86401..bb103f789f55b 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -18,14 +18,14 @@ fn main() { let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid let x: *const dyn Trait = &(); - let y: *const dyn Trait = x as _; //~ error: mismatched types + let y: *const dyn Trait = x as _; //~ error: casting `*const dyn Trait` as `*const dyn Trait` is invalid _ = (b, y); } fn generic(x: *const dyn Trait, t: *const dyn Trait) { - let _: *const dyn Trait = x as _; //~ error: mismatched types - let _: *const dyn Trait = t as _; //~ error: mismatched types + let _: *const dyn Trait = x as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid + let _: *const dyn Trait = t as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid } trait Assocked { @@ -33,5 +33,5 @@ trait Assocked { } fn change_assoc(x: *mut dyn Assocked) -> *mut dyn Assocked { - x as _ //~ error: mismatched types + x as _ //~ error: casting `*mut (dyn Assocked + 'static)` as `*mut (dyn Assocked + 'static)` is invalid } diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index 8e60ca42f0a52..e571a43959ffd 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -4,53 +4,40 @@ error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid LL | let b: *const dyn B = a as _; | ^^^^^^ | - = note: vtable kinds may not match + = note: the trait objects may have different vtables -error[E0308]: mismatched types +error[E0606]: casting `*const dyn Trait` as `*const dyn Trait` is invalid --> $DIR/ptr-to-trait-obj-different-args.rs:21:34 | LL | let y: *const dyn Trait = x as _; - | ^^^^^^ expected `X`, found `Y` + | ^^^^^^ | - = note: expected trait object `dyn Trait` - found trait object `dyn Trait` - = help: `dyn Trait` implements `Trait` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well + = note: the trait objects may have different vtables -error[E0308]: mismatched types +error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid --> $DIR/ptr-to-trait-obj-different-args.rs:27:34 | -LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) { - | - found this type parameter LL | let _: *const dyn Trait = x as _; - | ^^^^^^ expected `X`, found type parameter `T` + | ^^^^^^ | - = note: expected trait object `dyn Trait` - found trait object `dyn Trait` - = help: `dyn Trait` implements `Trait` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well + = note: the trait objects may have different vtables -error[E0308]: mismatched types +error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 | -LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) { - | - expected this type parameter -LL | let _: *const dyn Trait = x as _; LL | let _: *const dyn Trait = t as _; - | ^^^^^^ expected type parameter `T`, found `X` + | ^^^^^^ | - = note: expected trait object `dyn Trait` - found trait object `dyn Trait` - = help: `dyn Trait` implements `Trait` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well + = note: the trait objects may have different vtables -error[E0308]: mismatched types +error[E0606]: casting `*mut (dyn Assocked + 'static)` as `*mut (dyn Assocked + 'static)` is invalid --> $DIR/ptr-to-trait-obj-different-args.rs:36:5 | LL | x as _ - | ^^^^^^ expected `u8`, found `u32` + | ^^^^^^ | - = note: expected trait object `dyn Assocked` - found trait object `dyn Assocked` + = note: the trait objects may have different vtables error: aborting due to 5 previous errors -Some errors have detailed explanations: E0308, E0606. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr index 38c8ba96bc5b7..5687aba625ff7 100644 --- a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr @@ -4,7 +4,7 @@ error[E0606]: casting `*const (dyn Sub + 'static)` as `*const Wrapper LL | ptr as _ | ^^^^^^^^ | - = note: vtable kinds may not match + = note: the trait objects may have different vtables error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 142a52aef13d0..3d12ba9899bc5 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -4,7 +4,7 @@ error[E0606]: casting `*const U` as `*const V` is invalid LL | u as *const V | ^^^^^^^^^^^^^ | - = note: vtable kinds may not match + = note: the pointers may have different metadata error[E0606]: casting `*const U` as `*const str` is invalid --> $DIR/cast-rfc0401.rs:8:5 @@ -12,7 +12,7 @@ error[E0606]: casting `*const U` as `*const str` is invalid LL | u as *const str | ^^^^^^^^^^^^^^^ | - = note: vtable kinds may not match + = note: the pointers may have different metadata error[E0609]: no field `f` on type `fn() {main}` --> $DIR/cast-rfc0401.rs:65:18 @@ -208,7 +208,7 @@ error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid LL | let _ = cf as *const [u16]; | ^^^^^^^^^^^^^^^^^^ | - = note: vtable kinds may not match + = note: the pointers have different metadata error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid --> $DIR/cast-rfc0401.rs:69:13 @@ -216,7 +216,7 @@ error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid LL | let _ = cf as *const dyn Bar; | ^^^^^^^^^^^^^^^^^^^^ | - = note: vtable kinds may not match + = note: the trait objects may have different vtables error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/cast-rfc0401.rs:53:13 diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index 5eaa58f7efe7f..0ddae1d1417c7 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -57,7 +57,7 @@ pub fn user2() -> &'static dyn Trait { fn main() { let p: *const dyn Trait = &(); let p = p as *const dyn Trait; // <- this is bad! - //~^ error: mismatched types + //~^ error: casting `*const dyn Trait` as `*const dyn Trait` is invalid let p = p as *const dyn Super; // <- this upcast accesses improper vtable entry // accessing from L__unnamed_2 the position for the 'Super vtable (pointer)', // thus reading 'null pointer for missing_method' diff --git a/tests/ui/traits/upcast_soundness_bug.stderr b/tests/ui/traits/upcast_soundness_bug.stderr index 5864abcdb41f5..19d1a5e5926e0 100644 --- a/tests/ui/traits/upcast_soundness_bug.stderr +++ b/tests/ui/traits/upcast_soundness_bug.stderr @@ -1,13 +1,11 @@ -error[E0308]: mismatched types +error[E0606]: casting `*const dyn Trait` as `*const dyn Trait` is invalid --> $DIR/upcast_soundness_bug.rs:59:13 | LL | let p = p as *const dyn Trait; // <- this is bad! - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected trait object `dyn Trait` - found trait object `dyn Trait` - = help: `dyn Trait` implements `Trait` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well + = note: the trait objects may have different vtables error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0606`. From b62e72ce8c31bbfd028136570a5e46bee233d4f3 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 15 Sep 2024 23:26:51 +0200 Subject: [PATCH 14/14] update doc comment --- compiler/rustc_middle/src/mir/syntax.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bba3aee820ab2..ae75f2d4187ba 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -579,7 +579,8 @@ pub struct CopyNonOverlapping<'tcx> { pub count: Operand<'tcx>, } -/// Represents how a [`TerminatorKind::Call`] was constructed, used for diagnostics. +/// Represents how a [`TerminatorKind::Call`] was constructed. +/// Used only for diagnostics. #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub enum CallSource { @@ -1419,7 +1420,8 @@ pub enum CastKind { Transmute, } -/// Represents how a [`CastKind::PointerCoercion`] was constructed, used for diagnostics. +/// Represents how a [`CastKind::PointerCoercion`] was constructed. +/// Used only for diagnostics. #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] pub enum CoercionSource { /// The coercion was manually written by the user with an `as` cast.