From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_trait_selection/src/traits/misc.rs | 88 +++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 compiler/rustc_trait_selection/src/traits/misc.rs (limited to 'compiler/rustc_trait_selection/src/traits/misc.rs') diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs new file mode 100644 index 000000000..dd2769c71 --- /dev/null +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -0,0 +1,88 @@ +//! Miscellaneous type-system utilities that are too small to deserve their own modules. + +use crate::infer::InferCtxtExt as _; +use crate::traits::{self, ObligationCause}; + +use rustc_hir as hir; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; + +use crate::traits::error_reporting::InferCtxtExt; + +#[derive(Clone)] +pub enum CopyImplementationError<'tcx> { + InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>)>), + NotAnAdt, + HasDestructor, +} + +pub fn can_type_implement_copy<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + self_type: Ty<'tcx>, + parent_cause: ObligationCause<'tcx>, +) -> Result<(), CopyImplementationError<'tcx>> { + // FIXME: (@jroesch) float this code up + tcx.infer_ctxt().enter(|infcx| { + let (adt, substs) = match self_type.kind() { + // These types used to have a builtin impl. + // Now libcore provides that impl. + ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Float(_) + | ty::Char + | ty::RawPtr(..) + | ty::Never + | ty::Ref(_, _, hir::Mutability::Not) + | ty::Array(..) => return Ok(()), + + ty::Adt(adt, substs) => (adt, substs), + + _ => return Err(CopyImplementationError::NotAnAdt), + }; + + let mut infringing = Vec::new(); + for variant in adt.variants() { + for field in &variant.fields { + let ty = field.ty(tcx, substs); + if ty.references_error() { + continue; + } + let span = tcx.def_span(field.did); + // FIXME(compiler-errors): This gives us better spans for bad + // projection types like in issue-50480. + // If the ADT has substs, point to the cause we are given. + // If it does not, then this field probably doesn't normalize + // to begin with, and point to the bad field's span instead. + let cause = if field + .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did())) + .has_param_types_or_consts() + { + parent_cause.clone() + } else { + ObligationCause::dummy_with_span(span) + }; + let ctx = traits::FulfillmentContext::new(); + match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) { + Ok(ty) => { + if !infcx.type_is_copy_modulo_regions(param_env, ty, span) { + infringing.push((field, ty)); + } + } + Err(errors) => { + infcx.report_fulfillment_errors(&errors, None, false); + } + }; + } + } + if !infringing.is_empty() { + return Err(CopyImplementationError::InfrigingFields(infringing)); + } + if adt.has_dtor(tcx) { + return Err(CopyImplementationError::HasDestructor); + } + + Ok(()) + }) +} -- cgit v1.2.3