diff options
Diffstat (limited to 'compiler/rustc_middle/src/mir/mod.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 984d4687ef8..48edbde68e5 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -20,6 +20,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::{self, CoroutineDesugaring, CoroutineKind, ImplicitSelfKind}; use rustc_hir::{self as hir, HirId}; use rustc_session::Session; +use rustc_span::source_map::Spanned; use rustc_target::abi::{FieldIdx, VariantIdx}; use polonius_engine::Atom; @@ -44,6 +45,7 @@ use std::ops::{Index, IndexMut}; use std::{iter, mem}; pub use self::query::*; +use self::visit::TyContext; pub use basic_blocks::BasicBlocks; mod basic_blocks; @@ -304,6 +306,21 @@ impl<'tcx> CoroutineInfo<'tcx> { } } +/// Some item that needs to monomorphize successfully for a MIR body to be considered well-formed. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeFoldable, TypeVisitable)] +pub enum MentionedItem<'tcx> { + /// A function that gets called. We don't necessarily know its precise type yet, since it can be + /// hidden behind a generic. + Fn(Ty<'tcx>), + /// A type that has its drop shim called. + Drop(Ty<'tcx>), + /// Unsizing casts might require vtables, so we have to record them. + UnsizeCast { source_ty: Ty<'tcx>, target_ty: Ty<'tcx> }, + /// A closure that is coerced to a function pointer. + Closure(Ty<'tcx>), +} + /// The lowered representation of a single function. #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct Body<'tcx> { @@ -367,8 +384,24 @@ pub struct Body<'tcx> { /// Constants that are required to evaluate successfully for this MIR to be well-formed. /// We hold in this field all the constants we are not able to evaluate yet. + /// + /// This is soundness-critical, we make a guarantee that all consts syntactically mentioned in a + /// function have successfully evaluated if the function ever gets executed at runtime. pub required_consts: Vec<ConstOperand<'tcx>>, + /// Further items that were mentioned in this function and hence *may* become monomorphized, + /// depending on optimizations. We use this to avoid optimization-dependent compile errors: the + /// collector recursively traverses all "mentioned" items and evaluates all their + /// `required_consts`. + /// + /// This is *not* soundness-critical and the contents of this list are *not* a stable guarantee. + /// All that's relevant is that this set is optimization-level-independent, and that it includes + /// everything that the collector would consider "used". (For example, we currently compute this + /// set after drop elaboration, so some drop calls that can never be reached are not considered + /// "mentioned".) See the documentation of `CollectionMode` in + /// `compiler/rustc_monomorphize/src/collector.rs` for more context. + pub mentioned_items: Vec<Spanned<MentionedItem<'tcx>>>, + /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check. /// /// Note that this does not actually mean that this body is not computable right now. @@ -445,6 +478,7 @@ impl<'tcx> Body<'tcx> { var_debug_info, span, required_consts: Vec::new(), + mentioned_items: Vec::new(), is_polymorphic: false, injection_phase: None, tainted_by_errors, @@ -474,6 +508,7 @@ impl<'tcx> Body<'tcx> { spread_arg: None, span: DUMMY_SP, required_consts: Vec::new(), + mentioned_items: Vec::new(), var_debug_info: Vec::new(), is_polymorphic: false, injection_phase: None, @@ -568,6 +603,17 @@ impl<'tcx> Body<'tcx> { } } + pub fn span_for_ty_context(&self, ty_context: TyContext) -> Span { + match ty_context { + TyContext::UserTy(span) => span, + TyContext::ReturnTy(source_info) + | TyContext::LocalDecl { source_info, .. } + | TyContext::YieldTy(source_info) + | TyContext::ResumeTy(source_info) => source_info.span, + TyContext::Location(loc) => self.source_info(loc).span, + } + } + /// Returns the return type; it always return first element from `local_decls` array. #[inline] pub fn return_ty(&self) -> Ty<'tcx> { |
