diff options
Diffstat (limited to 'compiler/rustc_const_eval/src/util')
-rw-r--r-- | compiler/rustc_const_eval/src/util/call_kind.rs | 137 | ||||
-rw-r--r-- | compiler/rustc_const_eval/src/util/collect_writes.rs | 36 | ||||
-rw-r--r-- | compiler/rustc_const_eval/src/util/compare_types.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_const_eval/src/util/find_self_call.rs | 36 | ||||
-rw-r--r-- | compiler/rustc_const_eval/src/util/mod.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_const_eval/src/util/type_name.rs | 3 |
6 files changed, 4 insertions, 217 deletions
diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs deleted file mode 100644 index 995363c0e..000000000 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ /dev/null @@ -1,137 +0,0 @@ -//! Common logic for borrowck use-after-move errors when moved into a `fn(self)`, -//! as well as errors when attempting to call a non-const function in a const -//! context. - -use rustc_hir::def_id::DefId; -use rustc_hir::{lang_items, LangItem}; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt}; -use rustc_span::symbol::Ident; -use rustc_span::{sym, DesugaringKind, Span}; - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum CallDesugaringKind { - /// for _ in x {} calls x.into_iter() - ForLoopIntoIter, - /// x? calls x.branch() - QuestionBranch, - /// x? calls type_of(x)::from_residual() - QuestionFromResidual, - /// try { ..; x } calls type_of(x)::from_output(x) - TryBlockFromOutput, -} - -impl CallDesugaringKind { - pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId { - match self { - Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), - Self::QuestionBranch | Self::TryBlockFromOutput => { - tcx.require_lang_item(LangItem::Try, None) - } - Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(), - } - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum CallKind<'tcx> { - /// A normal method call of the form `receiver.foo(a, b, c)` - Normal { - self_arg: Option<Ident>, - desugaring: Option<(CallDesugaringKind, Ty<'tcx>)>, - method_did: DefId, - method_substs: SubstsRef<'tcx>, - }, - /// A call to `Fn(..)::call(..)`, desugared from `my_closure(a, b, c)` - FnCall { fn_trait_id: DefId, self_ty: Ty<'tcx> }, - /// A call to an operator trait, desugared from operator syntax (e.g. `a << b`) - Operator { self_arg: Option<Ident>, trait_id: DefId, self_ty: Ty<'tcx> }, - DerefCoercion { - /// The `Span` of the `Target` associated type - /// in the `Deref` impl we are using. - deref_target: Span, - /// The type `T::Deref` we are dereferencing to - deref_target_ty: Ty<'tcx>, - self_ty: Ty<'tcx>, - }, -} - -pub fn call_kind<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - method_did: DefId, - method_substs: SubstsRef<'tcx>, - fn_call_span: Span, - from_hir_call: bool, - self_arg: Option<Ident>, -) -> CallKind<'tcx> { - let parent = tcx.opt_associated_item(method_did).and_then(|assoc| { - let container_id = assoc.container_id(tcx); - match assoc.container { - AssocItemContainer::ImplContainer => tcx.trait_id_of_impl(container_id), - AssocItemContainer::TraitContainer => Some(container_id), - } - }); - - let fn_call = parent.and_then(|p| { - lang_items::FN_TRAITS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p) - }); - - let operator = if !from_hir_call && let Some(p) = parent { - lang_items::OPERATORS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p) - } else { - None - }; - - let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did); - - // Check for a 'special' use of 'self' - - // an FnOnce call, an operator (e.g. `<<`), or a - // deref coercion. - let kind = if let Some(trait_id) = fn_call { - Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_substs.type_at(0) }) - } else if let Some(trait_id) = operator { - Some(CallKind::Operator { self_arg, trait_id, self_ty: method_substs.type_at(0) }) - } else if is_deref { - let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::resolve(tcx, param_env, deref_target, method_substs).transpose() - }); - if let Some(Ok(instance)) = deref_target { - let deref_target_ty = instance.ty(tcx, param_env); - Some(CallKind::DerefCoercion { - deref_target: tcx.def_span(instance.def_id()), - deref_target_ty, - self_ty: method_substs.type_at(0), - }) - } else { - None - } - } else { - None - }; - - kind.unwrap_or_else(|| { - // This isn't a 'special' use of `self` - debug!(?method_did, ?fn_call_span); - let desugaring = if Some(method_did) == tcx.lang_items().into_iter_fn() - && fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop) - { - Some((CallDesugaringKind::ForLoopIntoIter, method_substs.type_at(0))) - } else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) { - if Some(method_did) == tcx.lang_items().branch_fn() { - Some((CallDesugaringKind::QuestionBranch, method_substs.type_at(0))) - } else if Some(method_did) == tcx.lang_items().from_residual_fn() { - Some((CallDesugaringKind::QuestionFromResidual, method_substs.type_at(0))) - } else { - None - } - } else if Some(method_did) == tcx.lang_items().from_output_fn() - && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock) - { - Some((CallDesugaringKind::TryBlockFromOutput, method_substs.type_at(0))) - } else { - None - }; - CallKind::Normal { self_arg, desugaring, method_did, method_substs } - }) -} diff --git a/compiler/rustc_const_eval/src/util/collect_writes.rs b/compiler/rustc_const_eval/src/util/collect_writes.rs deleted file mode 100644 index 8d92bb359..000000000 --- a/compiler/rustc_const_eval/src/util/collect_writes.rs +++ /dev/null @@ -1,36 +0,0 @@ -use rustc_middle::mir::visit::PlaceContext; -use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::{Body, Local, Location}; - -pub trait FindAssignments { - // Finds all statements that assign directly to local (i.e., X = ...) - // and returns their locations. - fn find_assignments(&self, local: Local) -> Vec<Location>; -} - -impl<'tcx> FindAssignments for Body<'tcx> { - fn find_assignments(&self, local: Local) -> Vec<Location> { - let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] }; - visitor.visit_body(self); - visitor.locations - } -} - -// The Visitor walks the MIR to return the assignment statements corresponding -// to a Local. -struct FindLocalAssignmentVisitor { - needle: Local, - locations: Vec<Location>, -} - -impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor { - fn visit_local(&mut self, local: Local, place_context: PlaceContext, location: Location) { - if self.needle != local { - return; - } - - if place_context.is_place_assignment() { - self.locations.push(location); - } - } -} diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index f5f3d5de6..d6a2ffb75 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -3,8 +3,8 @@ //! FIXME: Move this to a more general place. The utility of this extends to //! other areas of the compiler as well. -use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; -use rustc_infer::traits::ObligationCause; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::traits::{DefiningAnchor, ObligationCause}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_trait_selection::traits::ObligationCtxt; diff --git a/compiler/rustc_const_eval/src/util/find_self_call.rs b/compiler/rustc_const_eval/src/util/find_self_call.rs deleted file mode 100644 index 33ad128ee..000000000 --- a/compiler/rustc_const_eval/src/util/find_self_call.rs +++ /dev/null @@ -1,36 +0,0 @@ -use rustc_middle::mir::*; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::def_id::DefId; - -/// Checks if the specified `local` is used as the `self` parameter of a method call -/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is -/// returned. -pub fn find_self_call<'tcx>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, - local: Local, - block: BasicBlock, -) -> Option<(DefId, SubstsRef<'tcx>)> { - debug!("find_self_call(local={:?}): terminator={:?}", local, &body[block].terminator); - if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) = - &body[block].terminator - { - debug!("find_self_call: func={:?}", func); - if let Operand::Constant(box Constant { literal, .. }) = func { - if let ty::FnDef(def_id, substs) = *literal.ty().kind() { - if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) = - tcx.opt_associated_item(def_id) - { - debug!("find_self_call: args={:?}", args); - if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args { - if self_place.as_local() == Some(local) { - return Some((def_id, substs)); - } - } - } - } - } - } - None -} diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index c0aabd77c..7641f5607 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -1,14 +1,9 @@ mod alignment; -mod call_kind; mod check_validity_requirement; -pub mod collect_writes; mod compare_types; -mod find_self_call; mod type_name; pub use self::alignment::is_disaligned; -pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind}; pub use self::check_validity_requirement::check_validity_requirement; pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype}; -pub use self::find_self_call::find_self_call; pub use self::type_name::type_name; diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 4e80a2851..11ad5b49d 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -58,11 +58,12 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { // Types with identity (print the module path). ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs) | ty::FnDef(def_id, substs) - | ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) | ty::Closure(def_id, substs) | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), ty::Foreign(def_id) => self.print_def_path(def_id, &[]), + ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"), ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"), ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"), } |