mv compiler to compiler/
This commit is contained in:
parent
db534b3ac2
commit
9e5f7d5631
1686 changed files with 941 additions and 1051 deletions
74
compiler/rustc_trait_selection/src/traits/misc.rs
Normal file
74
compiler/rustc_trait_selection/src/traits/misc.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
//! 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, TypeFoldable};
|
||||
|
||||
use crate::traits::error_reporting::InferCtxtExt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum CopyImplementationError<'tcx> {
|
||||
InfrigingFields(Vec<&'tcx ty::FieldDef>),
|
||||
NotAnAdt,
|
||||
HasDestructor,
|
||||
}
|
||||
|
||||
pub fn can_type_implement_copy(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
self_type: Ty<'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) => 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);
|
||||
let cause = 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);
|
||||
}
|
||||
}
|
||||
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(())
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue