Auto merge of #74113 - lcnr:type-dependent-consts-2, r=eddyb
Support const args in type dependent paths (Take 2) once more, except it is sound this time 🥰 previously #71154 ----- ```rust #![feature(const_generics)] struct A; impl A { fn foo<const N: usize>(&self) -> usize { N } } struct B; impl B { fn foo<const N: usize>(&self) -> usize { 42 } } fn main() { let a = A; a.foo::<7>(); } ``` When calling `type_of` for generic const arguments, we now use the `TypeckTables` of the surrounding body to get the expected type. This alone causes cycle errors though, as we now have `typeck_tables_of(main)` -> `...` -> `type_of(main_ANON0 := 7)` -> `typeck_tables_of(main)` ⚡ (see https://github.com/rust-lang/rust/issues/68400#issuecomment-611760290) To prevent this we must not call `type_of(const_arg)` during `typeck_tables_of`. This is achieved by calling `type_of(param_def_id)` instead. We have to somehow remember the `DefId` of the param through all of typeck, which is done using the struct `ty::WithOptConstParam<DefId>`, which replaces `DefId` where needed and contains an `Option<DefId>` to be able to store the const parameter in case it exists. Queries which are currently cached on disk are split into two variants: `query_name`(cached) and `query_name_(of|for)_const_arg`(not cached), with `query_name_of_const_arg` taking a pair `(did, param_did): (LocalDefId, DefId)`. For some queries a method `query_name_of_opt_const_arg` is added to `TyCtxt` which takes a `ty::WithOptConstParam` and either calls `query_name` or `query_name_of_const_arg` depending on the value of `const_param_did`. r? @eddyb @varkor
This commit is contained in:
commit
7e11379f3b
@ -248,9 +248,9 @@ fn exported_symbols_provider_local(
|
||||
}
|
||||
|
||||
match *mono_item {
|
||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => {
|
||||
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
|
||||
if substs.non_erasable_generics().next().is_some() {
|
||||
let symbol = ExportedSymbol::Generic(def_id, substs);
|
||||
let symbol = ExportedSymbol::Generic(def.did, substs);
|
||||
symbols.push((symbol, SymbolExportLevel::Rust));
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
||||
match self.monomorphize(&constant.literal).val {
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => self
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => self
|
||||
.cx
|
||||
.tcx()
|
||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None)
|
||||
.const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
|
||||
.map_err(|err| {
|
||||
if promoted.is_none() {
|
||||
self.cx
|
||||
|
@ -64,8 +64,7 @@ const BASE_IMPL: &[&str] =
|
||||
|
||||
/// DepNodes for mir_built/Optimized, which is relevant in "executable"
|
||||
/// code, i.e., functions+methods
|
||||
const BASE_MIR: &[&str] =
|
||||
&[label_strs::optimized_mir, label_strs::promoted_mir, label_strs::mir_built];
|
||||
const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir];
|
||||
|
||||
/// Struct, Enum and Union DepNodes
|
||||
///
|
||||
@ -376,7 +375,7 @@ impl DirtyCleanVisitor<'tcx> {
|
||||
let def_path_hash = self.tcx.def_path_hash(def_id);
|
||||
labels.iter().map(move |label| match DepNode::from_label_string(label, def_path_hash) {
|
||||
Ok(dep_node) => dep_node,
|
||||
Err(()) => unreachable!(),
|
||||
Err(()) => unreachable!("label: {}", label),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1536,7 +1536,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn const_eval_resolve(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
promoted: Option<mir::Promoted>,
|
||||
span: Option<Span>,
|
||||
@ -1547,7 +1547,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
let (param_env, substs) = canonical.value;
|
||||
// The return value is the evaluated value which doesn't contain any reference to inference
|
||||
// variables, thus we don't need to substitute back the original values.
|
||||
self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
|
||||
self.tcx.const_eval_resolve(param_env, def, substs, promoted, span)
|
||||
}
|
||||
|
||||
/// If `typ` is a type variable of some kind, resolve it one level
|
||||
|
@ -891,7 +891,8 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
|
||||
mir::transform::check_unsafety::check_unsafety(tcx, def_id);
|
||||
|
||||
if tcx.hir().body_const_context(def_id).is_some() {
|
||||
tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
|
||||
tcx.ensure()
|
||||
.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -111,8 +111,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||
bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
|
||||
})
|
||||
}
|
||||
optimized_mir => { cdata.get_optimized_mir(tcx, def_id.index) }
|
||||
promoted_mir => { cdata.get_promoted_mir(tcx, def_id.index) }
|
||||
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
|
||||
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
||||
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
|
||||
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
|
||||
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
||||
|
@ -14,7 +14,37 @@ macro_rules! arena_types {
|
||||
[] layouts: rustc_target::abi::Layout, rustc_target::abi::Layout;
|
||||
// AdtDef are interned and compared by address
|
||||
[] adt_def: rustc_middle::ty::AdtDef, rustc_middle::ty::AdtDef;
|
||||
[] steal_mir:
|
||||
rustc_middle::ty::steal::Steal<rustc_middle::mir::Body<$tcx>>,
|
||||
rustc_middle::ty::steal::Steal<rustc_middle::mir::Body<$tcx>>;
|
||||
[decode] mir: rustc_middle::mir::Body<$tcx>, rustc_middle::mir::Body<'_x>;
|
||||
[] steal_promoted:
|
||||
rustc_middle::ty::steal::Steal<
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
>
|
||||
>,
|
||||
rustc_middle::ty::steal::Steal<
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
>
|
||||
>;
|
||||
[decode] promoted:
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
>,
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<'_x>
|
||||
>;
|
||||
[decode] tables: rustc_middle::ty::TypeckTables<$tcx>, rustc_middle::ty::TypeckTables<'_x>;
|
||||
[decode] borrowck_result:
|
||||
rustc_middle::mir::BorrowCheckResult<$tcx>,
|
||||
rustc_middle::mir::BorrowCheckResult<'_x>;
|
||||
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, rustc_middle::mir::UnsafetyCheckResult;
|
||||
[] const_allocs: rustc_middle::mir::interpret::Allocation, rustc_middle::mir::interpret::Allocation;
|
||||
// Required for the incremental on-disk cache
|
||||
[few, decode] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;
|
||||
|
@ -34,12 +34,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn const_eval_resolve(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
promoted: Option<mir::Promoted>,
|
||||
span: Option<Span>,
|
||||
) -> ConstEvalResult<'tcx> {
|
||||
match ty::Instance::resolve(self, param_env, def_id, substs) {
|
||||
match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
|
||||
Ok(Some(instance)) => {
|
||||
let cid = GlobalId { instance, promoted };
|
||||
self.const_eval_global_id(param_env, cid, span)
|
||||
|
@ -346,8 +346,8 @@ impl<'tcx> CodegenUnit<'tcx> {
|
||||
// instances into account. The others don't matter for
|
||||
// the codegen tests and can even make item order
|
||||
// unstable.
|
||||
InstanceDef::Item(def_id) => {
|
||||
def_id.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id))
|
||||
InstanceDef::Item(def) => {
|
||||
def.did.as_local().map(|def_id| tcx.hir().as_local_hir_id(def_id))
|
||||
}
|
||||
InstanceDef::VtableShim(..)
|
||||
| InstanceDef::ReifyShim(..)
|
||||
|
@ -1,10 +1,11 @@
|
||||
//! Values computed by queries that use MIR.
|
||||
|
||||
use crate::ty::{self, Ty};
|
||||
use crate::mir::{Body, Promoted};
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_index::bit_set::BitMatrix;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_span::{Span, Symbol};
|
||||
@ -323,3 +324,38 @@ pub struct CoverageInfo {
|
||||
/// The total number of coverage region counters added to the MIR `Body`.
|
||||
pub num_counters: u32,
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn mir_borrowck_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx BorrowCheckResult<'tcx> {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.mir_borrowck_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.mir_borrowck(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mir_const_qualif_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> ConstQualifs {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.mir_const_qualif_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.mir_const_qualif(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn promoted_mir_of_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
self.promoted_mir_of_const_arg((did, param_did))
|
||||
} else {
|
||||
self.promoted_mir(def.did)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,25 @@ rustc_queries! {
|
||||
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
|
||||
/// const argument and returns `None` otherwise.
|
||||
///
|
||||
/// ```rust
|
||||
/// let a = foo::<7>();
|
||||
/// // ^ Calling `opt_const_param_of` for this argument,
|
||||
///
|
||||
/// fn foo<const N: usize>()
|
||||
/// // ^ returns this `DefId`.
|
||||
///
|
||||
/// fn bar() {
|
||||
/// // ^ While calling `opt_const_param_of` for other bodies returns `None`.
|
||||
/// }
|
||||
/// ```
|
||||
query opt_const_param_of(key: LocalDefId) -> Option<DefId> {
|
||||
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
// FIXME(#74113): consider storing this query on disk.
|
||||
}
|
||||
|
||||
/// Records the type of every item.
|
||||
query type_of(key: DefId) -> Ty<'tcx> {
|
||||
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
|
||||
@ -189,47 +208,66 @@ rustc_queries! {
|
||||
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
|
||||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
query mir_const_qualif_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> mir::ConstQualifs {
|
||||
desc {
|
||||
|tcx| "const checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` right after it's built - this includes
|
||||
/// unreachable code.
|
||||
query mir_built(key: LocalDefId) -> Steal<mir::Body<'tcx>> {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` up till the point where it is
|
||||
/// ready for const qualification.
|
||||
///
|
||||
/// See the README for the `mir` module for details.
|
||||
query mir_const(key: DefId) -> Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key) }
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc {
|
||||
|tcx| "processing MIR for {}`{}`",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
no_hash
|
||||
}
|
||||
|
||||
query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> Steal<mir::Body<'tcx>> {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
query mir_drops_elaborated_and_const_checked(
|
||||
key: ty::WithOptConstParam<LocalDefId>
|
||||
) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
no_hash
|
||||
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||
}
|
||||
|
||||
query mir_validated(key: LocalDefId) ->
|
||||
query mir_validated(key: ty::WithOptConstParam<LocalDefId>) ->
|
||||
(
|
||||
Steal<mir::Body<'tcx>>,
|
||||
Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
|
||||
&'tcx Steal<mir::Body<'tcx>>,
|
||||
&'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
|
||||
) {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
no_hash
|
||||
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
desc {
|
||||
|tcx| "processing {}`{}`",
|
||||
if key.const_param_did.is_some() { "the const argument " } else { "" },
|
||||
tcx.def_path_str(key.did.to_def_id()),
|
||||
}
|
||||
}
|
||||
|
||||
/// MIR after our optimization passes have run. This is MIR that is ready
|
||||
/// for codegen. This is also the only query that can fetch non-local MIR, at present.
|
||||
query optimized_mir(key: DefId) -> mir::Body<'tcx> {
|
||||
query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> {
|
||||
desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) }
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
query optimized_mir_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
||||
desc {
|
||||
|tcx| "optimizing MIR for the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns coverage summary info for a function, after executing the `InstrumentCoverage`
|
||||
/// MIR pass (assuming the -Zinstrument-coverage option is enabled).
|
||||
@ -239,11 +277,18 @@ rustc_queries! {
|
||||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
|
||||
query promoted_mir(key: DefId) -> IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
||||
query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
||||
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
query promoted_mir_of_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
|
||||
desc {
|
||||
|tcx| "optimizing promoted MIR for the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
@ -451,11 +496,16 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
/// The result of unsafety-checking this `DefId`.
|
||||
query unsafety_check_result(key: LocalDefId) -> mir::UnsafetyCheckResult {
|
||||
/// The result of unsafety-checking this `LocalDefId`.
|
||||
query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult {
|
||||
desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
}
|
||||
query unsafety_check_result_for_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::UnsafetyCheckResult {
|
||||
desc {
|
||||
|tcx| "unsafety-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error.
|
||||
@ -537,6 +587,14 @@ rustc_queries! {
|
||||
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query typeck_tables_of_const_arg(
|
||||
key: (LocalDefId, DefId)
|
||||
) -> &'tcx ty::TypeckTables<'tcx> {
|
||||
desc {
|
||||
|tcx| "type-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id()),
|
||||
}
|
||||
}
|
||||
query diagnostic_only_typeck_tables_of(key: LocalDefId) -> &'tcx ty::TypeckTables<'tcx> {
|
||||
desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
@ -570,14 +628,19 @@ rustc_queries! {
|
||||
BorrowChecking {
|
||||
/// Borrow-checks the function body. If this is a closure, returns
|
||||
/// additional requirements that the closure's creator must verify.
|
||||
query mir_borrowck(key: LocalDefId) -> mir::BorrowCheckResult<'tcx> {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> {
|
||||
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if(tcx, opt_result) {
|
||||
tcx.is_closure(key.to_def_id())
|
||||
|| opt_result.map_or(false, |r| !r.concrete_opaque_types.is_empty())
|
||||
}
|
||||
}
|
||||
query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> {
|
||||
desc {
|
||||
|tcx| "borrow-checking the const argument`{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TypeChecking {
|
||||
@ -1444,5 +1507,14 @@ rustc_queries! {
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorReported> {
|
||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||
}
|
||||
|
||||
query resolve_instance_of_const_arg(
|
||||
key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorReported> {
|
||||
desc {
|
||||
"resolving instance of the const argument `{}`",
|
||||
ty::Instance::new(key.value.0.to_def_id(), key.value.2),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -980,15 +980,26 @@ pub struct GlobalCtxt<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> Steal<Body<'tcx>> {
|
||||
Steal::new(mir)
|
||||
pub fn typeck_tables_of_opt_const_arg(
|
||||
self,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx TypeckTables<'tcx> {
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
self.typeck_tables_of_const_arg((def.did, param_did))
|
||||
} else {
|
||||
self.typeck_tables_of(def.did)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
|
||||
self.arena.alloc(Steal::new(mir))
|
||||
}
|
||||
|
||||
pub fn alloc_steal_promoted(
|
||||
self,
|
||||
promoted: IndexVec<Promoted, Body<'tcx>>,
|
||||
) -> Steal<IndexVec<Promoted, Body<'tcx>>> {
|
||||
Steal::new(promoted)
|
||||
) -> &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
|
||||
self.arena.alloc(Steal::new(promoted))
|
||||
}
|
||||
|
||||
pub fn alloc_adt_def(
|
||||
|
@ -29,7 +29,7 @@ pub enum InstanceDef<'tcx> {
|
||||
/// - `fn` items
|
||||
/// - closures
|
||||
/// - generators
|
||||
Item(DefId),
|
||||
Item(ty::WithOptConstParam<DefId>),
|
||||
|
||||
/// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
|
||||
///
|
||||
@ -160,8 +160,8 @@ impl<'tcx> Instance<'tcx> {
|
||||
self.substs.non_erasable_generics().next()?;
|
||||
|
||||
match self.def {
|
||||
InstanceDef::Item(def_id) => tcx
|
||||
.upstream_monomorphizations_for(def_id)
|
||||
InstanceDef::Item(def) => tcx
|
||||
.upstream_monomorphizations_for(def.did)
|
||||
.and_then(|monos| monos.get(&self.substs).cloned()),
|
||||
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
|
||||
_ => None,
|
||||
@ -171,10 +171,10 @@ impl<'tcx> Instance<'tcx> {
|
||||
|
||||
impl<'tcx> InstanceDef<'tcx> {
|
||||
#[inline]
|
||||
pub fn def_id(&self) -> DefId {
|
||||
match *self {
|
||||
InstanceDef::Item(def_id)
|
||||
| InstanceDef::VtableShim(def_id)
|
||||
pub fn def_id(self) -> DefId {
|
||||
match self {
|
||||
InstanceDef::Item(def) => def.did,
|
||||
InstanceDef::VtableShim(def_id)
|
||||
| InstanceDef::ReifyShim(def_id)
|
||||
| InstanceDef::FnPtrShim(def_id, _)
|
||||
| InstanceDef::Virtual(def_id, _)
|
||||
@ -185,6 +185,21 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
|
||||
match self {
|
||||
InstanceDef::Item(def) => def,
|
||||
InstanceDef::VtableShim(def_id)
|
||||
| InstanceDef::ReifyShim(def_id)
|
||||
| InstanceDef::FnPtrShim(def_id, _)
|
||||
| InstanceDef::Virtual(def_id, _)
|
||||
| InstanceDef::Intrinsic(def_id)
|
||||
| InstanceDef::ClosureOnceShim { call_once: def_id }
|
||||
| InstanceDef::DropGlue(def_id, _)
|
||||
| InstanceDef::CloneShim(def_id, _) => ty::WithOptConstParam::unknown(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn attrs(&self, tcx: TyCtxt<'tcx>) -> ty::Attributes<'tcx> {
|
||||
tcx.get_attrs(self.def_id())
|
||||
@ -198,7 +213,7 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
let def_id = match *self {
|
||||
ty::InstanceDef::Item(def_id) => def_id,
|
||||
ty::InstanceDef::Item(def) => def.did,
|
||||
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
|
||||
_ => return true,
|
||||
};
|
||||
@ -244,8 +259,8 @@ impl<'tcx> InstanceDef<'tcx> {
|
||||
|
||||
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
match *self {
|
||||
InstanceDef::Item(def_id) => {
|
||||
tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
||||
InstanceDef::Item(def) => {
|
||||
tcx.codegen_fn_attrs(def.did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@ -283,7 +298,7 @@ impl<'tcx> Instance<'tcx> {
|
||||
def_id,
|
||||
substs
|
||||
);
|
||||
Instance { def: InstanceDef::Item(def_id), substs }
|
||||
Instance { def: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs }
|
||||
}
|
||||
|
||||
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||
@ -323,6 +338,21 @@ impl<'tcx> Instance<'tcx> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorReported> {
|
||||
Instance::resolve_opt_const_arg(
|
||||
tcx,
|
||||
param_env,
|
||||
ty::WithOptConstParam::unknown(def_id),
|
||||
substs,
|
||||
)
|
||||
}
|
||||
|
||||
// This should be kept up to date with `resolve`.
|
||||
pub fn resolve_opt_const_arg(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorReported> {
|
||||
// All regions in the result of this query are erased, so it's
|
||||
// fine to erase all of the input regions.
|
||||
@ -333,7 +363,13 @@ impl<'tcx> Instance<'tcx> {
|
||||
let substs = tcx.erase_regions(&substs);
|
||||
|
||||
// FIXME(eddyb) should this always use `param_env.with_reveal_all()`?
|
||||
tcx.resolve_instance(tcx.erase_regions(¶m_env.and((def_id, substs))))
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
tcx.resolve_instance_of_const_arg(
|
||||
tcx.erase_regions(¶m_env.and((did, param_did, substs))),
|
||||
)
|
||||
} else {
|
||||
tcx.resolve_instance(tcx.erase_regions(¶m_env.and((def.did, substs))))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_for_fn_ptr(
|
||||
@ -345,9 +381,9 @@ impl<'tcx> Instance<'tcx> {
|
||||
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
||||
Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
|
||||
match resolved.def {
|
||||
InstanceDef::Item(def_id) if resolved.def.requires_caller_location(tcx) => {
|
||||
InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
|
||||
debug!(" => fn pointer created for function with #[track_caller]");
|
||||
resolved.def = InstanceDef::ReifyShim(def_id);
|
||||
resolved.def = InstanceDef::ReifyShim(def.did);
|
||||
}
|
||||
InstanceDef::Virtual(def_id, _) => {
|
||||
debug!(" => fn pointer created for virtual call");
|
||||
|
@ -1,5 +1,4 @@
|
||||
// ignore-tidy-filelength
|
||||
|
||||
pub use self::fold::{TypeFoldable, TypeVisitor};
|
||||
pub use self::AssocItemContainer::*;
|
||||
pub use self::BorrowKind::*;
|
||||
@ -1101,7 +1100,7 @@ pub enum PredicateKind<'tcx> {
|
||||
Subtype(PolySubtypePredicate<'tcx>),
|
||||
|
||||
/// Constant initializer must evaluate successfully.
|
||||
ConstEvaluatable(DefId, SubstsRef<'tcx>),
|
||||
ConstEvaluatable(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
|
||||
|
||||
/// Constants must be equal. The first component is the const that is expected.
|
||||
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
|
||||
@ -1572,6 +1571,95 @@ pub type PlaceholderType = Placeholder<BoundVar>;
|
||||
|
||||
pub type PlaceholderConst = Placeholder<BoundVar>;
|
||||
|
||||
/// A `DefId` which is potentially bundled with its corresponding generic parameter
|
||||
/// in case `did` is a const argument.
|
||||
///
|
||||
/// This is used to prevent cycle errors during typeck
|
||||
/// as `type_of(const_arg)` depends on `typeck_tables_of(owning_body)`
|
||||
/// which once again requires the type of its generic arguments.
|
||||
///
|
||||
/// Luckily we only need to deal with const arguments once we
|
||||
/// know their corresponding parameters. We (ab)use this by
|
||||
/// calling `type_of(param_did)` for these arguments.
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(const_generics)]
|
||||
///
|
||||
/// struct A;
|
||||
/// impl A {
|
||||
/// fn foo<const N: usize>(&self) -> usize { N }
|
||||
/// }
|
||||
/// struct B;
|
||||
/// impl B {
|
||||
/// fn foo<const N: u8>(&self) -> usize { 42 }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let a = A;
|
||||
/// a.foo::<7>();
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable, Lift, RustcEncodable, RustcDecodable)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Hash, HashStable)]
|
||||
pub struct WithOptConstParam<T> {
|
||||
pub did: T,
|
||||
/// The `DefId` of the corresponding generic paramter in case `did` is
|
||||
/// a const argument.
|
||||
///
|
||||
/// Note that even if `did` is a const argument, this may still be `None`.
|
||||
/// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)`
|
||||
/// to potentially update `param_did` in case it `None`.
|
||||
pub const_param_did: Option<DefId>,
|
||||
}
|
||||
|
||||
impl<T> WithOptConstParam<T> {
|
||||
/// Creates a new `WithOptConstParam` setting `const_param_did` to `None`.
|
||||
pub fn unknown(did: T) -> WithOptConstParam<T> {
|
||||
WithOptConstParam { did, const_param_did: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl WithOptConstParam<LocalDefId> {
|
||||
pub fn to_global(self) -> WithOptConstParam<DefId> {
|
||||
WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did }
|
||||
}
|
||||
|
||||
pub fn def_id_for_type_of(self) -> DefId {
|
||||
if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() }
|
||||
}
|
||||
}
|
||||
|
||||
impl WithOptConstParam<DefId> {
|
||||
pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> {
|
||||
self.did
|
||||
.as_local()
|
||||
.map(|did| WithOptConstParam { did, const_param_did: self.const_param_did })
|
||||
}
|
||||
|
||||
pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> {
|
||||
if let Some(param_did) = self.const_param_did {
|
||||
if let Some(did) = self.did.as_local() {
|
||||
return Some((did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn expect_local(self) -> WithOptConstParam<LocalDefId> {
|
||||
self.as_local().unwrap()
|
||||
}
|
||||
|
||||
pub fn is_local(self) -> bool {
|
||||
self.did.is_local()
|
||||
}
|
||||
|
||||
pub fn def_id_for_type_of(self) -> DefId {
|
||||
self.const_param_did.unwrap_or(self.did)
|
||||
}
|
||||
}
|
||||
|
||||
/// When type checking, we use the `ParamEnv` to track
|
||||
/// details about the set of where-clauses that are in scope at this
|
||||
/// particular point.
|
||||
@ -2843,7 +2931,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
||||
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
||||
match instance {
|
||||
ty::InstanceDef::Item(did) => self.optimized_mir(did),
|
||||
ty::InstanceDef::Item(def) => {
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
self.optimized_mir_of_const_arg((did, param_did))
|
||||
} else {
|
||||
self.optimized_mir(def.did)
|
||||
}
|
||||
}
|
||||
ty::InstanceDef::VtableShim(..)
|
||||
| ty::InstanceDef::ReifyShim(..)
|
||||
| ty::InstanceDef::Intrinsic(..)
|
||||
|
@ -883,18 +883,18 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
|
||||
match ct.val {
|
||||
ty::ConstKind::Unevaluated(did, substs, promoted) => {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
if let Some(promoted) = promoted {
|
||||
p!(print_value_path(did, substs));
|
||||
p!(print_value_path(def.did, substs));
|
||||
p!(write("::{:?}", promoted));
|
||||
} else {
|
||||
match self.tcx().def_kind(did) {
|
||||
match self.tcx().def_kind(def.did) {
|
||||
DefKind::Static | DefKind::Const | DefKind::AssocConst => {
|
||||
p!(print_value_path(did, substs))
|
||||
p!(print_value_path(def.did, substs))
|
||||
}
|
||||
_ => {
|
||||
if did.is_local() {
|
||||
let span = self.tcx().def_span(did);
|
||||
if def.is_local() {
|
||||
let span = self.tcx().def_span(def.did);
|
||||
if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
p!(write("{}", snip))
|
||||
@ -2027,9 +2027,9 @@ define_print_and_forward_display! {
|
||||
print_value_path(closure_def_id, &[]),
|
||||
write("` implements the trait `{}`", kind))
|
||||
}
|
||||
&ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
&ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
p!(write("the constant `"),
|
||||
print_value_path(def_id, substs),
|
||||
print_value_path(def.did, substs),
|
||||
write("` can be evaluated"))
|
||||
}
|
||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||
|
@ -105,6 +105,17 @@ impl Key for DefId {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for ty::WithOptConstParam<LocalDefId> {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
fn query_crate(&self) -> CrateNum {
|
||||
self.did.query_crate()
|
||||
}
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.did.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (DefId, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
@ -127,6 +138,17 @@ impl Key for (DefId, LocalDefId) {
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (LocalDefId, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
fn query_crate(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Key for (CrateNum, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
@ -171,6 +193,17 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
fn query_crate(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||
self.0.default_span(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector;
|
||||
|
||||
|
@ -578,12 +578,12 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
||||
|
||||
// FIXME(const_generics): this is wrong, as it is a projection
|
||||
(
|
||||
ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
|
||||
ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
|
||||
) if a_def_id == b_def_id && a_promoted == b_promoted => {
|
||||
ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
|
||||
ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
|
||||
) if a_def == b_def && a_promoted == b_promoted => {
|
||||
let substs =
|
||||
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
|
||||
Ok(ty::ConstKind::Unevaluated(a_def_id, substs, a_promoted))
|
||||
Ok(ty::ConstKind::Unevaluated(a_def, substs, a_promoted))
|
||||
}
|
||||
_ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))),
|
||||
};
|
||||
|
@ -272,6 +272,7 @@ CloneTypeFoldableAndLiftImpls! {
|
||||
::rustc_span::symbol::Symbol,
|
||||
::rustc_hir::def::Res,
|
||||
::rustc_hir::def_id::DefId,
|
||||
::rustc_hir::def_id::LocalDefId,
|
||||
::rustc_hir::LlvmInlineAsmInner,
|
||||
::rustc_hir::MatchSource,
|
||||
::rustc_hir::Mutability,
|
||||
@ -719,6 +720,18 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
|
||||
for (A, B, C)
|
||||
{
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> (A, B, C) {
|
||||
(self.0.fold_with(folder), self.1.fold_with(folder), self.2.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.0.visit_with(visitor) || self.1.visit_with(visitor) || self.2.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
EnumTypeFoldableImpl! {
|
||||
impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
|
||||
(Some)(a),
|
||||
@ -838,7 +851,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||
Self {
|
||||
substs: self.substs.fold_with(folder),
|
||||
def: match self.def {
|
||||
Item(did) => Item(did.fold_with(folder)),
|
||||
Item(def) => Item(def.fold_with(folder)),
|
||||
VtableShim(did) => VtableShim(did.fold_with(folder)),
|
||||
ReifyShim(did) => ReifyShim(did.fold_with(folder)),
|
||||
Intrinsic(did) => Intrinsic(did.fold_with(folder)),
|
||||
@ -857,7 +870,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||
use crate::ty::InstanceDef::*;
|
||||
self.substs.visit_with(visitor)
|
||||
|| match self.def {
|
||||
Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
|
||||
Item(def) => def.visit_with(visitor),
|
||||
VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
|
||||
did.visit_with(visitor)
|
||||
}
|
||||
FnPtrShim(did, ty) | CloneShim(did, ty) => {
|
||||
|
@ -2210,21 +2210,28 @@ impl<'tcx> Const<'tcx> {
|
||||
/// Literals and const generic parameters are eagerly converted to a constant, everything else
|
||||
/// becomes `Unevaluated`.
|
||||
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
|
||||
debug!("Const::from_anon_const(id={:?})", def_id);
|
||||
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
pub fn from_opt_const_arg_anon_const(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx Self {
|
||||
debug!("Const::from_anon_const(def={:?})", def);
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
|
||||
let body_id = match tcx.hir().get(hir_id) {
|
||||
hir::Node::AnonConst(ac) => ac.body,
|
||||
_ => span_bug!(
|
||||
tcx.def_span(def_id.to_def_id()),
|
||||
tcx.def_span(def.did.to_def_id()),
|
||||
"from_anon_const can only process anonymous constants"
|
||||
),
|
||||
};
|
||||
|
||||
let expr = &tcx.hir().body(body_id).value;
|
||||
|
||||
let ty = tcx.type_of(def_id.to_def_id());
|
||||
let ty = tcx.type_of(def.def_id_for_type_of());
|
||||
|
||||
let lit_input = match expr.kind {
|
||||
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
|
||||
@ -2271,8 +2278,8 @@ impl<'tcx> Const<'tcx> {
|
||||
ty::ConstKind::Param(ty::ParamConst::new(index, name))
|
||||
}
|
||||
_ => ty::ConstKind::Unevaluated(
|
||||
def_id.to_def_id(),
|
||||
InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
|
||||
def.to_global(),
|
||||
InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
None,
|
||||
),
|
||||
};
|
||||
@ -2340,7 +2347,7 @@ impl<'tcx> Const<'tcx> {
|
||||
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
|
||||
/// unevaluated constant.
|
||||
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
|
||||
if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
|
||||
if let ConstKind::Unevaluated(def, substs, promoted) = self.val {
|
||||
use crate::mir::interpret::ErrorHandled;
|
||||
|
||||
let param_env_and_substs = param_env.with_reveal_all().and(substs);
|
||||
@ -2356,7 +2363,7 @@ impl<'tcx> Const<'tcx> {
|
||||
// FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
|
||||
// we can call `infcx.const_eval_resolve` which handles inference variables.
|
||||
let param_env_and_substs = if param_env_and_substs.needs_infer() {
|
||||
tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did))
|
||||
tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did))
|
||||
} else {
|
||||
param_env_and_substs
|
||||
};
|
||||
@ -2366,7 +2373,7 @@ impl<'tcx> Const<'tcx> {
|
||||
let (param_env, substs) = param_env_and_substs.into_parts();
|
||||
// try to resolve e.g. associated constants to their definition on an impl, and then
|
||||
// evaluate the const.
|
||||
match tcx.const_eval_resolve(param_env, did, substs, promoted, None) {
|
||||
match tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
|
||||
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
|
||||
// and we use the original type, so nothing from `substs`
|
||||
// (which may be identity substs, see above),
|
||||
@ -2426,7 +2433,7 @@ pub enum ConstKind<'tcx> {
|
||||
|
||||
/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
|
||||
/// variants when the code is monomorphic enough for that.
|
||||
Unevaluated(DefId, SubstsRef<'tcx>, Option<Promoted>),
|
||||
Unevaluated(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Option<Promoted>),
|
||||
|
||||
/// Used to hold computed value.
|
||||
Value(ConstValue<'tcx>),
|
||||
|
@ -17,7 +17,7 @@ use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind
|
||||
use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
|
||||
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, RegionVid, TyCtxt};
|
||||
use rustc_middle::ty::{self, InstanceDef, RegionVid, TyCtxt};
|
||||
use rustc_session::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT, UNUSED_MUT};
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
|
||||
@ -87,34 +87,49 @@ crate struct Upvar {
|
||||
const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref];
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { mir_borrowck, ..*providers };
|
||||
*providers = Providers {
|
||||
mir_borrowck: |tcx, did| mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)),
|
||||
mir_borrowck_const_arg: |tcx, (did, param_did)| {
|
||||
mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
||||
fn mir_borrowck(tcx: TyCtxt<'_>, def_id: LocalDefId) -> BorrowCheckResult<'_> {
|
||||
let (input_body, promoted) = tcx.mir_validated(def_id);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id.to_def_id()));
|
||||
fn mir_borrowck<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx BorrowCheckResult<'tcx> {
|
||||
if def.const_param_did.is_none() {
|
||||
if let Some(param_did) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_borrowck_const_arg((def.did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
let (input_body, promoted) = tcx.mir_validated(def);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
|
||||
|
||||
let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
let promoted: &IndexVec<_, _> = &promoted.borrow();
|
||||
do_mir_borrowck(&infcx, input_body, promoted, def_id)
|
||||
do_mir_borrowck(&infcx, input_body, promoted, def)
|
||||
});
|
||||
debug!("mir_borrowck done");
|
||||
|
||||
opt_closure_req
|
||||
tcx.arena.alloc(opt_closure_req)
|
||||
}
|
||||
|
||||
fn do_mir_borrowck<'a, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'tcx>,
|
||||
input_body: &Body<'tcx>,
|
||||
input_promoted: &IndexVec<Promoted, Body<'tcx>>,
|
||||
def_id: LocalDefId,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> BorrowCheckResult<'tcx> {
|
||||
debug!("do_mir_borrowck(def_id = {:?})", def_id);
|
||||
debug!("do_mir_borrowck(def = {:?})", def);
|
||||
|
||||
let tcx = infcx.tcx;
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let id = tcx.hir().as_local_hir_id(def_id);
|
||||
let param_env = tcx.param_env(def.did);
|
||||
let id = tcx.hir().as_local_hir_id(def.did);
|
||||
|
||||
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
|
||||
for var_debug_info in &input_body.var_debug_info {
|
||||
@ -135,13 +150,13 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
}
|
||||
|
||||
// Gather the upvars of a closure, if any.
|
||||
let tables = tcx.typeck_tables_of(def_id);
|
||||
let tables = tcx.typeck_tables_of_opt_const_arg(def);
|
||||
if let Some(ErrorReported) = tables.tainted_by_errors {
|
||||
infcx.set_tainted_by_errors();
|
||||
}
|
||||
let upvars: Vec<_> = tables
|
||||
.closure_captures
|
||||
.get(&def_id.to_def_id())
|
||||
.get(&def.did.to_def_id())
|
||||
.into_iter()
|
||||
.flat_map(|v| v.values())
|
||||
.map(|upvar_id| {
|
||||
@ -171,8 +186,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
// will have a lifetime tied to the inference context.
|
||||
let mut body = input_body.clone();
|
||||
let mut promoted = input_promoted.clone();
|
||||
let free_regions =
|
||||
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
|
||||
let free_regions = nll::replace_regions_in_mir(infcx, def, param_env, &mut body, &mut promoted);
|
||||
let body = &body; // no further changes
|
||||
|
||||
let location_table = &LocationTable::new(&body);
|
||||
@ -190,7 +204,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
let mdpe = MoveDataParamEnv { move_data, param_env };
|
||||
|
||||
let mut flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe)
|
||||
.into_engine(tcx, &body, def_id.to_def_id())
|
||||
.into_engine(tcx, &body, def.did.to_def_id())
|
||||
.iterate_to_fixpoint()
|
||||
.into_results_cursor(&body);
|
||||
|
||||
@ -207,7 +221,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
nll_errors,
|
||||
} = nll::compute_regions(
|
||||
infcx,
|
||||
def_id,
|
||||
def.did,
|
||||
free_regions,
|
||||
body,
|
||||
&promoted,
|
||||
@ -223,7 +237,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
// write unit-tests, as well as helping with debugging.
|
||||
nll::dump_mir_results(
|
||||
infcx,
|
||||
MirSource::item(def_id.to_def_id()),
|
||||
MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None },
|
||||
&body,
|
||||
®ioncx,
|
||||
&opt_closure_req,
|
||||
@ -234,7 +248,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
nll::dump_annotation(
|
||||
infcx,
|
||||
&body,
|
||||
def_id.to_def_id(),
|
||||
def.did.to_def_id(),
|
||||
®ioncx,
|
||||
&opt_closure_req,
|
||||
&opaque_type_values,
|
||||
@ -249,13 +263,13 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
let regioncx = Rc::new(regioncx);
|
||||
|
||||
let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set)
|
||||
.into_engine(tcx, &body, def_id.to_def_id())
|
||||
.into_engine(tcx, &body, def.did.to_def_id())
|
||||
.iterate_to_fixpoint();
|
||||
let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe)
|
||||
.into_engine(tcx, &body, def_id.to_def_id())
|
||||
.into_engine(tcx, &body, def.did.to_def_id())
|
||||
.iterate_to_fixpoint();
|
||||
let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe)
|
||||
.into_engine(tcx, &body, def_id.to_def_id())
|
||||
.into_engine(tcx, &body, def.did.to_def_id())
|
||||
.iterate_to_fixpoint();
|
||||
|
||||
let movable_generator = match tcx.hir().get(id) {
|
||||
@ -274,7 +288,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
let mut promoted_mbcx = MirBorrowckCtxt {
|
||||
infcx,
|
||||
body: promoted_body,
|
||||
mir_def_id: def_id,
|
||||
mir_def_id: def.did,
|
||||
move_data: &move_data,
|
||||
location_table: &LocationTable::new(promoted_body),
|
||||
movable_generator,
|
||||
@ -307,7 +321,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
let mut mbcx = MirBorrowckCtxt {
|
||||
infcx,
|
||||
body,
|
||||
mir_def_id: def_id,
|
||||
mir_def_id: def.did,
|
||||
move_data: &mdpe.move_data,
|
||||
location_table,
|
||||
movable_generator,
|
||||
|
@ -9,7 +9,7 @@ use rustc_middle::mir::{
|
||||
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
|
||||
Promoted,
|
||||
};
|
||||
use rustc_middle::ty::{self, RegionKind, RegionVid};
|
||||
use rustc_middle::ty::{self, InstanceDef, RegionKind, RegionVid};
|
||||
use rustc_span::symbol::sym;
|
||||
use std::env;
|
||||
use std::fmt::Debug;
|
||||
@ -59,20 +59,20 @@ crate struct NllOutput<'tcx> {
|
||||
/// `compute_regions`.
|
||||
pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
|
||||
infcx: &InferCtxt<'cx, 'tcx>,
|
||||
def_id: LocalDefId,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
promoted: &mut IndexVec<Promoted, Body<'tcx>>,
|
||||
) -> UniversalRegions<'tcx> {
|
||||
debug!("replace_regions_in_mir(def_id={:?})", def_id);
|
||||
debug!("replace_regions_in_mir(def={:?})", def);
|
||||
|
||||
// Compute named region information. This also renumbers the inputs/outputs.
|
||||
let universal_regions = UniversalRegions::new(infcx, def_id, param_env);
|
||||
let universal_regions = UniversalRegions::new(infcx, def, param_env);
|
||||
|
||||
// Replace all remaining regions with fresh inference variables.
|
||||
renumber::renumber_mir(infcx, body, promoted);
|
||||
|
||||
let source = MirSource::item(def_id.to_def_id());
|
||||
let source = MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None };
|
||||
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
|
||||
|
||||
universal_regions
|
||||
|
@ -321,7 +321,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
let tcx = self.tcx();
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val {
|
||||
if let Some(promoted) = promoted {
|
||||
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
|
||||
promoted: &Body<'tcx>,
|
||||
@ -357,7 +357,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||
ConstraintCategory::Boring,
|
||||
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
|
||||
constant.literal.ty,
|
||||
def_id,
|
||||
def.did,
|
||||
UserSubsts { substs, user_self_ty: None },
|
||||
)),
|
||||
) {
|
||||
|
@ -227,12 +227,12 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
/// known between those regions.
|
||||
pub fn new(
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
mir_def_id: LocalDefId,
|
||||
mir_def: ty::WithOptConstParam<LocalDefId>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
let tcx = infcx.tcx;
|
||||
let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id);
|
||||
UniversalRegionsBuilder { infcx, mir_def_id, mir_hir_id, param_env }.build()
|
||||
let mir_hir_id = tcx.hir().as_local_hir_id(mir_def.did);
|
||||
UniversalRegionsBuilder { infcx, mir_def, mir_hir_id, param_env }.build()
|
||||
}
|
||||
|
||||
/// Given a reference to a closure type, extracts all the values
|
||||
@ -388,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
||||
|
||||
struct UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
mir_def_id: LocalDefId,
|
||||
mir_def: ty::WithOptConstParam<LocalDefId>,
|
||||
mir_hir_id: HirId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
@ -397,7 +397,7 @@ const FR: NLLRegionVariableOrigin = NLLRegionVariableOrigin::FreeRegion;
|
||||
|
||||
impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
fn build(self) -> UniversalRegions<'tcx> {
|
||||
debug!("build(mir_def_id={:?})", self.mir_def_id);
|
||||
debug!("build(mir_def={:?})", self.mir_def);
|
||||
|
||||
let param_env = self.param_env;
|
||||
debug!("build: param_env={:?}", param_env);
|
||||
@ -417,7 +417,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let mut indices = self.compute_indices(fr_static, defining_ty);
|
||||
debug!("build: indices={:?}", indices);
|
||||
|
||||
let closure_base_def_id = self.infcx.tcx.closure_base_def_id(self.mir_def_id.to_def_id());
|
||||
let closure_base_def_id = self.infcx.tcx.closure_base_def_id(self.mir_def.did.to_def_id());
|
||||
|
||||
// If this is a closure or generator, then the late-bound regions from the enclosing
|
||||
// function are actually external regions to us. For example, here, 'a is not local
|
||||
@ -425,8 +425,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
// fn foo<'a>() {
|
||||
// let c = || { let x: &'a u32 = ...; }
|
||||
// }
|
||||
if self.mir_def_id.to_def_id() != closure_base_def_id {
|
||||
self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices)
|
||||
if self.mir_def.did.to_def_id() != closure_base_def_id {
|
||||
self.infcx
|
||||
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices)
|
||||
}
|
||||
|
||||
let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
|
||||
@ -436,15 +437,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let first_local_index = self.infcx.num_region_vars();
|
||||
let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
|
||||
FR,
|
||||
self.mir_def_id,
|
||||
self.mir_def.did,
|
||||
&bound_inputs_and_output,
|
||||
&mut indices,
|
||||
);
|
||||
// Converse of above, if this is a function then the late-bound regions declared on its
|
||||
// signature are local to the fn.
|
||||
if self.mir_def_id.to_def_id() == closure_base_def_id {
|
||||
if self.mir_def.did.to_def_id() == closure_base_def_id {
|
||||
self.infcx
|
||||
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices);
|
||||
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
|
||||
}
|
||||
|
||||
let (unnormalized_output_ty, mut unnormalized_input_tys) =
|
||||
@ -456,7 +457,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
if self.infcx.tcx.fn_sig(def_id).c_variadic() {
|
||||
let va_list_did = self.infcx.tcx.require_lang_item(
|
||||
lang_items::VaListTypeLangItem,
|
||||
Some(self.infcx.tcx.def_span(self.mir_def_id)),
|
||||
Some(self.infcx.tcx.def_span(self.mir_def.did)),
|
||||
);
|
||||
let region = self
|
||||
.infcx
|
||||
@ -507,14 +508,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
/// see `DefiningTy` for details.
|
||||
fn defining_ty(&self) -> DefiningTy<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id.to_def_id());
|
||||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did.to_def_id());
|
||||
|
||||
match tcx.hir().body_owner_kind(self.mir_hir_id) {
|
||||
BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
|
||||
let defining_ty = if self.mir_def_id.to_def_id() == closure_base_def_id {
|
||||
let defining_ty = if self.mir_def.did.to_def_id() == closure_base_def_id {
|
||||
tcx.type_of(closure_base_def_id)
|
||||
} else {
|
||||
let tables = tcx.typeck_tables_of(self.mir_def_id);
|
||||
let tables = tcx.typeck_tables_of(self.mir_def.did);
|
||||
tables.node_type(self.mir_hir_id)
|
||||
};
|
||||
|
||||
@ -530,20 +531,20 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
}
|
||||
ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
|
||||
_ => span_bug!(
|
||||
tcx.def_span(self.mir_def_id),
|
||||
tcx.def_span(self.mir_def.did),
|
||||
"expected defining type for `{:?}`: `{:?}`",
|
||||
self.mir_def_id,
|
||||
self.mir_def.did,
|
||||
defining_ty
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
BodyOwnerKind::Const | BodyOwnerKind::Static(..) => {
|
||||
assert_eq!(self.mir_def_id.to_def_id(), closure_base_def_id);
|
||||
assert_eq!(self.mir_def.did.to_def_id(), closure_base_def_id);
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id);
|
||||
let substs =
|
||||
self.infcx.replace_free_regions_with_nll_infer_vars(FR, &identity_substs);
|
||||
DefiningTy::Const(self.mir_def_id.to_def_id(), substs)
|
||||
DefiningTy::Const(self.mir_def.did.to_def_id(), substs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -558,7 +559,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
defining_ty: DefiningTy<'tcx>,
|
||||
) -> UniversalRegionIndices<'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id.to_def_id());
|
||||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def.did.to_def_id());
|
||||
let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id);
|
||||
let fr_substs = match defining_ty {
|
||||
DefiningTy::Closure(_, ref substs) | DefiningTy::Generator(_, ref substs, _) => {
|
||||
@ -592,7 +593,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
match defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
assert_eq!(self.mir_def_id.to_def_id(), def_id);
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let closure_sig = substs.as_closure().sig();
|
||||
let inputs_and_output = closure_sig.inputs_and_output();
|
||||
let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
@ -616,7 +617,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
assert_eq!(self.mir_def_id.to_def_id(), def_id);
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let resume_ty = substs.as_generator().resume_ty();
|
||||
let output = substs.as_generator().return_ty();
|
||||
let generator_ty = tcx.mk_generator(def_id, substs, movability);
|
||||
@ -634,8 +635,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
DefiningTy::Const(def_id, _) => {
|
||||
// For a constant body, there are no inputs, and one
|
||||
// "output" (the type of the constant).
|
||||
assert_eq!(self.mir_def_id.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(def_id);
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let ty = tcx.type_of(self.mir_def.def_id_for_type_of());
|
||||
let ty = indices.fold_to_region_vids(tcx, &ty);
|
||||
ty::Binder::dummy(tcx.intern_type_list(&[ty]))
|
||||
}
|
||||
|
@ -288,21 +288,22 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
}
|
||||
|
||||
let cid = key.value;
|
||||
let def_id = cid.instance.def.def_id();
|
||||
let def = cid.instance.def.with_opt_param();
|
||||
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
if tcx.has_typeck_tables(def_id) {
|
||||
if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors {
|
||||
if let Some(def) = def.as_local() {
|
||||
if tcx.has_typeck_tables(def.did) {
|
||||
if let Some(error_reported) = tcx.typeck_tables_of_opt_const_arg(def).tainted_by_errors
|
||||
{
|
||||
return Err(ErrorHandled::Reported(error_reported));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let is_static = tcx.is_static(def_id);
|
||||
let is_static = tcx.is_static(def.did);
|
||||
|
||||
let mut ecx = InterpCx::new(
|
||||
tcx,
|
||||
tcx.def_span(cid.instance.def_id()),
|
||||
tcx.def_span(def.did),
|
||||
key.param_env,
|
||||
CompileTimeInterpreter::new(tcx.sess.const_eval_limit()),
|
||||
MemoryExtra { can_access_statics: is_static },
|
||||
@ -334,9 +335,9 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
}
|
||||
|
||||
v
|
||||
} else if let Some(def_id) = def_id.as_local() {
|
||||
} else if let Some(def) = def.as_local() {
|
||||
// constant defined in this crate, we can figure out a lint level!
|
||||
match tcx.def_kind(def_id.to_def_id()) {
|
||||
match tcx.def_kind(def.did.to_def_id()) {
|
||||
// constants never produce a hard error at the definition site. Anything else is
|
||||
// a backwards compatibility hazard (and will break old versions of winapi for
|
||||
// sure)
|
||||
@ -346,9 +347,9 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
// validation thus preventing such a hard error from being a backwards
|
||||
// compatibility hazard
|
||||
DefKind::Const | DefKind::AssocConst => {
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id);
|
||||
let hir_id = tcx.hir().as_local_hir_id(def.did);
|
||||
err.report_as_lint(
|
||||
tcx.at(tcx.def_span(def_id)),
|
||||
tcx.at(tcx.def_span(def.did)),
|
||||
"any use of this value will cause an error",
|
||||
hir_id,
|
||||
Some(err.span),
|
||||
@ -359,7 +360,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
// deny-by-default lint
|
||||
_ => {
|
||||
if let Some(p) = cid.promoted {
|
||||
let span = tcx.promoted_mir(def_id)[p].span;
|
||||
let span = tcx.promoted_mir_of_opt_const_arg(def.to_global())[p].span;
|
||||
if let err_inval!(ReferencedConstant) = err.error {
|
||||
err.report_as_error(
|
||||
tcx.at(span),
|
||||
@ -369,7 +370,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
err.report_as_lint(
|
||||
tcx.at(span),
|
||||
"reaching this expression at runtime will panic or abort",
|
||||
tcx.hir().as_local_hir_id(def_id),
|
||||
tcx.hir().as_local_hir_id(def.did),
|
||||
Some(err.span),
|
||||
)
|
||||
}
|
||||
|
@ -191,11 +191,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
debug!("find_mir_or_eval_fn: {:?}", instance);
|
||||
|
||||
// Only check non-glue functions
|
||||
if let ty::InstanceDef::Item(def_id) = instance.def {
|
||||
if let ty::InstanceDef::Item(def) = instance.def {
|
||||
// Execution might have wandered off into other crates, so we cannot do a stability-
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if ecx.tcx.is_const_fn_raw(def_id) {
|
||||
if ecx.tcx.is_const_fn_raw(def.did) {
|
||||
// If this function is a `const fn` then under certain circumstances we
|
||||
// can evaluate call via the query system, thus memoizing all future calls.
|
||||
if ecx.try_eval_const_fn_call(instance, ret, args)? {
|
||||
|
@ -394,24 +394,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
promoted: Option<mir::Promoted>,
|
||||
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
|
||||
// do not continue if typeck errors occurred (can only occur in local crate)
|
||||
let did = instance.def_id();
|
||||
if let Some(did) = did.as_local() {
|
||||
if self.tcx.has_typeck_tables(did) {
|
||||
if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors {
|
||||
let def = instance.with_opt_param();
|
||||
if let Some(def) = def.as_local() {
|
||||
if self.tcx.has_typeck_tables(def.did) {
|
||||
if let Some(error_reported) =
|
||||
self.tcx.typeck_tables_of_opt_const_arg(def).tainted_by_errors
|
||||
{
|
||||
throw_inval!(TypeckError(error_reported))
|
||||
}
|
||||
}
|
||||
}
|
||||
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
|
||||
if let Some(promoted) = promoted {
|
||||
return Ok(&self.tcx.promoted_mir(did)[promoted]);
|
||||
return Ok(&self.tcx.promoted_mir_of_opt_const_arg(def)[promoted]);
|
||||
}
|
||||
match instance {
|
||||
ty::InstanceDef::Item(def_id) => {
|
||||
if self.tcx.is_mir_available(did) {
|
||||
Ok(self.tcx.optimized_mir(did))
|
||||
ty::InstanceDef::Item(def) => {
|
||||
if self.tcx.is_mir_available(def.did) {
|
||||
if let Some((did, param_did)) = def.as_const_arg() {
|
||||
Ok(self.tcx.optimized_mir_of_const_arg((did, param_did)))
|
||||
} else {
|
||||
Ok(self.tcx.optimized_mir(def.did))
|
||||
}
|
||||
} else {
|
||||
throw_unsup!(NoMirFor(def_id))
|
||||
throw_unsup!(NoMirFor(def.did))
|
||||
}
|
||||
}
|
||||
_ => Ok(self.tcx.instance_mir(instance)),
|
||||
|
@ -549,8 +549,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let val_val = match val.val {
|
||||
ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
|
||||
ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)),
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
let instance = self.resolve(def.did, substs)?;
|
||||
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
|
||||
// The reason we use `const_eval_raw` everywhere else is to prevent cycles during
|
||||
// validation, because validation automatically reads through any references, thus
|
||||
|
@ -622,12 +622,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
|
||||
match substituted_constant.val {
|
||||
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
|
||||
Ok(val) => collect_const_value(self.tcx, val, self.output),
|
||||
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
|
||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||
self.tcx.def_span(def_id),
|
||||
self.tcx.def_span(def.did),
|
||||
"collection encountered polymorphic constant",
|
||||
),
|
||||
}
|
||||
@ -768,8 +768,8 @@ fn visit_instance_use<'tcx>(
|
||||
// need a mono item.
|
||||
fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
|
||||
let def_id = match instance.def {
|
||||
ty::InstanceDef::Item(def_id) | ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
|
||||
ty::InstanceDef::Item(def) => def.did,
|
||||
ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
ty::InstanceDef::VtableShim(..)
|
||||
| ty::InstanceDef::ReifyShim(..)
|
||||
| ty::InstanceDef::ClosureOnceShim { .. }
|
||||
|
@ -314,7 +314,8 @@ fn mono_item_visibility(
|
||||
};
|
||||
|
||||
let def_id = match instance.def {
|
||||
InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
InstanceDef::Item(def) => def.did,
|
||||
InstanceDef::DropGlue(def_id, Some(_)) => def_id,
|
||||
|
||||
// These are all compiler glue and such, never exported, always hidden.
|
||||
InstanceDef::VtableShim(..)
|
||||
@ -704,7 +705,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
|
||||
match mono_item {
|
||||
MonoItem::Fn(instance) => {
|
||||
let def_id = match instance.def {
|
||||
ty::InstanceDef::Item(def_id) => def_id,
|
||||
ty::InstanceDef::Item(def) => def.did,
|
||||
ty::InstanceDef::VtableShim(..)
|
||||
| ty::InstanceDef::ReifyShim(..)
|
||||
| ty::InstanceDef::FnPtrShim(..)
|
||||
|
@ -244,11 +244,16 @@ where
|
||||
};
|
||||
|
||||
// Check the qualifs of the value of `const` items.
|
||||
if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val {
|
||||
if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val {
|
||||
assert!(promoted.is_none());
|
||||
// Don't peek inside trait associated constants.
|
||||
if cx.tcx.trait_of_item(def_id).is_none() {
|
||||
let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id);
|
||||
if cx.tcx.trait_of_item(def.did).is_none() {
|
||||
let qualifs = if let Some((did, param_did)) = def.as_const_arg() {
|
||||
cx.tcx.at(constant.span).mir_const_qualif_const_arg((did, param_did))
|
||||
} else {
|
||||
cx.tcx.at(constant.span).mir_const_qualif(def.did)
|
||||
};
|
||||
|
||||
if !Q::in_qualifs(&qualifs) {
|
||||
return false;
|
||||
}
|
||||
|
@ -520,8 +520,8 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
let instance = Instance::resolve(self.tcx, self.param_env, def_id, substs);
|
||||
debug!("Resolving ({:?}) -> {:?}", def_id, instance);
|
||||
if let Ok(Some(func)) = instance {
|
||||
if let InstanceDef::Item(def_id) = func.def {
|
||||
if is_const_fn(self.tcx, def_id) {
|
||||
if let InstanceDef::Item(def) = func.def {
|
||||
if is_const_fn(self.tcx, def.did) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -489,7 +489,19 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { unsafety_check_result, unsafe_derive_on_repr_packed, ..*providers };
|
||||
*providers = Providers {
|
||||
unsafety_check_result: |tcx, def_id| {
|
||||
unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
},
|
||||
unsafety_check_result_for_const_arg: |tcx, (did, param_did)| {
|
||||
unsafety_check_result(
|
||||
tcx,
|
||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||
)
|
||||
},
|
||||
unsafe_derive_on_repr_packed,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
||||
struct UnusedUnsafeVisitor<'a> {
|
||||
@ -535,32 +547,42 @@ fn check_unused_unsafe(
|
||||
intravisit::Visitor::visit_body(&mut visitor, body);
|
||||
}
|
||||
|
||||
fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: LocalDefId) -> UnsafetyCheckResult {
|
||||
debug!("unsafety_violations({:?})", def_id);
|
||||
fn unsafety_check_result<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx UnsafetyCheckResult {
|
||||
if def.const_param_did.is_none() {
|
||||
if let Some(param_did) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.unsafety_check_result_for_const_arg((def.did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
debug!("unsafety_violations({:?})", def);
|
||||
|
||||
// N.B., this borrow is valid because all the consumers of
|
||||
// `mir_built` force this.
|
||||
let body = &tcx.mir_built(def_id).borrow();
|
||||
let body = &tcx.mir_built(def).borrow();
|
||||
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let param_env = tcx.param_env(def.did);
|
||||
|
||||
let id = tcx.hir().as_local_hir_id(def_id);
|
||||
let id = tcx.hir().as_local_hir_id(def.did);
|
||||
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
|
||||
hir::BodyOwnerKind::Closure => (false, false),
|
||||
hir::BodyOwnerKind::Fn => {
|
||||
(tcx.is_const_fn_raw(def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id()))
|
||||
(tcx.is_const_fn_raw(def.did.to_def_id()), is_min_const_fn(tcx, def.did.to_def_id()))
|
||||
}
|
||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
|
||||
};
|
||||
let mut checker =
|
||||
UnsafetyChecker::new(const_context, min_const_fn, body, def_id, tcx, param_env);
|
||||
UnsafetyChecker::new(const_context, min_const_fn, body, def.did, tcx, param_env);
|
||||
checker.visit_body(&body);
|
||||
|
||||
check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks);
|
||||
UnsafetyCheckResult {
|
||||
check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks);
|
||||
|
||||
tcx.arena.alloc(UnsafetyCheckResult {
|
||||
violations: checker.violations.into(),
|
||||
unsafe_blocks: checker.inherited_blocks.into(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
|
@ -9,7 +9,7 @@ use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::steal::Steal;
|
||||
use rustc_middle::ty::{InstanceDef, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{self, InstanceDef, TyCtxt, TypeFoldable};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use std::borrow::Cow;
|
||||
|
||||
@ -48,12 +48,23 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
mir_keys,
|
||||
mir_const,
|
||||
mir_const_qualif,
|
||||
mir_const_qualif: |tcx, did| {
|
||||
mir_const_qualif(tcx, ty::WithOptConstParam::unknown(did.expect_local()))
|
||||
},
|
||||
mir_const_qualif_const_arg: |tcx, (did, param_did)| {
|
||||
mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
mir_validated,
|
||||
mir_drops_elaborated_and_const_checked,
|
||||
optimized_mir,
|
||||
optimized_mir_of_const_arg,
|
||||
is_mir_available,
|
||||
promoted_mir,
|
||||
promoted_mir: |tcx, def_id| {
|
||||
promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id.expect_local()))
|
||||
},
|
||||
promoted_mir_of_const_arg: |tcx, (did, param_did)| {
|
||||
promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
},
|
||||
..*providers
|
||||
};
|
||||
instrument_coverage::provide(providers);
|
||||
@ -116,7 +127,14 @@ pub struct MirSource<'tcx> {
|
||||
|
||||
impl<'tcx> MirSource<'tcx> {
|
||||
pub fn item(def_id: DefId) -> Self {
|
||||
MirSource { instance: InstanceDef::Item(def_id), promoted: None }
|
||||
MirSource {
|
||||
instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
promoted: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
|
||||
self.instance.with_opt_param()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -202,9 +220,14 @@ pub fn run_passes(
|
||||
}
|
||||
}
|
||||
|
||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
|
||||
let def_id = def_id.expect_local();
|
||||
let const_kind = tcx.hir().body_const_context(def_id);
|
||||
fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs {
|
||||
if def.const_param_did.is_none() {
|
||||
if let Some(param_did) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_const_qualif_const_arg((def.did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
let const_kind = tcx.hir().body_const_context(def.did);
|
||||
|
||||
// No need to const-check a non-const `fn`.
|
||||
if const_kind.is_none() {
|
||||
@ -215,15 +238,20 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
|
||||
// cannot yet be stolen), because `mir_validated()`, which steals
|
||||
// from `mir_const(), forces this query to execute before
|
||||
// performing the steal.
|
||||
let body = &tcx.mir_const(def_id.to_def_id()).borrow();
|
||||
let body = &tcx.mir_const(def).borrow();
|
||||
|
||||
if body.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
let ccx =
|
||||
check_consts::ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) };
|
||||
let ccx = check_consts::ConstCx {
|
||||
body,
|
||||
tcx,
|
||||
def_id: def.did,
|
||||
const_kind,
|
||||
param_env: tcx.param_env(def.did),
|
||||
};
|
||||
|
||||
let mut validator = check_consts::validation::Validator::new(&ccx);
|
||||
validator.check_body();
|
||||
@ -234,22 +262,39 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
|
||||
}
|
||||
|
||||
/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
|
||||
fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal<Body<'_>> {
|
||||
let def_id = def_id.expect_local();
|
||||
fn mir_const<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx Steal<Body<'tcx>> {
|
||||
if def.const_param_did.is_none() {
|
||||
if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_const(ty::WithOptConstParam { const_param_did, ..def });
|
||||
}
|
||||
}
|
||||
|
||||
// Unsafety check uses the raw mir, so make sure it is run.
|
||||
let _ = tcx.unsafety_check_result(def_id);
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
tcx.ensure().unsafety_check_result_for_const_arg((def.did, param_did));
|
||||
} else {
|
||||
tcx.ensure().unsafety_check_result(def.did);
|
||||
}
|
||||
|
||||
let mut body = tcx.mir_built(def_id).steal();
|
||||
let mut body = tcx.mir_built(def).steal();
|
||||
|
||||
util::dump_mir(tcx, None, "mir_map", &0, MirSource::item(def_id.to_def_id()), &body, |_, _| {
|
||||
Ok(())
|
||||
});
|
||||
util::dump_mir(
|
||||
tcx,
|
||||
None,
|
||||
"mir_map",
|
||||
&0,
|
||||
MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None },
|
||||
&body,
|
||||
|_, _| Ok(()),
|
||||
);
|
||||
|
||||
run_passes(
|
||||
tcx,
|
||||
&mut body,
|
||||
InstanceDef::Item(def_id.to_def_id()),
|
||||
InstanceDef::Item(def.to_global()),
|
||||
None,
|
||||
MirPhase::Const,
|
||||
&[&[
|
||||
@ -265,13 +310,19 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal<Body<'_>> {
|
||||
|
||||
fn mir_validated(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> (Steal<Body<'tcx>>, Steal<IndexVec<Promoted, Body<'tcx>>>) {
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> (&'tcx Steal<Body<'tcx>>, &'tcx Steal<IndexVec<Promoted, Body<'tcx>>>) {
|
||||
if def.const_param_did.is_none() {
|
||||
if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_validated(ty::WithOptConstParam { const_param_did, ..def });
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we compute the `mir_const_qualif` for constants at
|
||||
// this point, before we steal the mir-const result.
|
||||
let _ = tcx.mir_const_qualif(def_id.to_def_id());
|
||||
let _ = tcx.mir_const_qualif_opt_const_arg(def);
|
||||
|
||||
let mut body = tcx.mir_const(def_id.to_def_id()).steal();
|
||||
let mut body = tcx.mir_const(def).steal();
|
||||
|
||||
let mut required_consts = Vec::new();
|
||||
let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts);
|
||||
@ -284,7 +335,7 @@ fn mir_validated(
|
||||
run_passes(
|
||||
tcx,
|
||||
&mut body,
|
||||
InstanceDef::Item(def_id.to_def_id()),
|
||||
InstanceDef::Item(def.to_global()),
|
||||
None,
|
||||
MirPhase::Validated,
|
||||
&[&[
|
||||
@ -304,17 +355,30 @@ fn mir_validated(
|
||||
|
||||
fn mir_drops_elaborated_and_const_checked<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> Steal<Body<'tcx>> {
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx Steal<Body<'tcx>> {
|
||||
if def.const_param_did.is_none() {
|
||||
if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam {
|
||||
const_param_did,
|
||||
..def
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
|
||||
// execute before we can steal.
|
||||
tcx.ensure().mir_borrowck(def_id);
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
tcx.ensure().mir_borrowck_const_arg((def.did, param_did));
|
||||
} else {
|
||||
tcx.ensure().mir_borrowck(def.did);
|
||||
}
|
||||
|
||||
let (body, _) = tcx.mir_validated(def_id);
|
||||
let (body, _) = tcx.mir_validated(def);
|
||||
let mut body = body.steal();
|
||||
|
||||
run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, None);
|
||||
check_consts::post_drop_elaboration::check_live_drops(tcx, def_id, &body);
|
||||
run_post_borrowck_cleanup_passes(tcx, &mut body, def.did, None);
|
||||
check_consts::post_drop_elaboration::check_live_drops(tcx, def.did, &body);
|
||||
tcx.alloc_steal_mir(body)
|
||||
}
|
||||
|
||||
@ -350,7 +414,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(
|
||||
run_passes(
|
||||
tcx,
|
||||
body,
|
||||
InstanceDef::Item(def_id.to_def_id()),
|
||||
InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id())),
|
||||
promoted,
|
||||
MirPhase::DropElab,
|
||||
&[post_borrowck_cleanup],
|
||||
@ -414,7 +478,7 @@ fn run_optimization_passes<'tcx>(
|
||||
run_passes(
|
||||
tcx,
|
||||
body,
|
||||
InstanceDef::Item(def_id.to_def_id()),
|
||||
InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id())),
|
||||
promoted,
|
||||
MirPhase::Optimized,
|
||||
&[
|
||||
@ -424,42 +488,70 @@ fn run_optimization_passes<'tcx>(
|
||||
);
|
||||
}
|
||||
|
||||
fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
|
||||
if tcx.is_constructor(def_id) {
|
||||
fn optimized_mir<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx Body<'tcx> {
|
||||
let did = did.expect_local();
|
||||
if let Some(param_did) = tcx.opt_const_param_of(did) {
|
||||
tcx.optimized_mir_of_const_arg((did, param_did))
|
||||
} else {
|
||||
tcx.arena.alloc(inner_optimized_mir(tcx, ty::WithOptConstParam::unknown(did)))
|
||||
}
|
||||
}
|
||||
|
||||
fn optimized_mir_of_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) -> &'tcx Body<'tcx> {
|
||||
tcx.arena.alloc(inner_optimized_mir(
|
||||
tcx,
|
||||
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||
))
|
||||
}
|
||||
|
||||
fn inner_optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||
if tcx.is_constructor(def.did.to_def_id()) {
|
||||
// There's no reason to run all of the MIR passes on constructors when
|
||||
// we can just output the MIR we want directly. This also saves const
|
||||
// qualification and borrow checking the trouble of special casing
|
||||
// constructors.
|
||||
return shim::build_adt_ctor(tcx, def_id);
|
||||
return shim::build_adt_ctor(tcx, def.did.to_def_id());
|
||||
}
|
||||
|
||||
let def_id = def_id.expect_local();
|
||||
|
||||
let mut body = tcx.mir_drops_elaborated_and_const_checked(def_id).steal();
|
||||
run_optimization_passes(tcx, &mut body, def_id, None);
|
||||
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).steal();
|
||||
run_optimization_passes(tcx, &mut body, def.did, None);
|
||||
|
||||
debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> IndexVec<Promoted, Body<'_>> {
|
||||
if tcx.is_constructor(def_id) {
|
||||
return IndexVec::new();
|
||||
fn promoted_mir<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
|
||||
if def.const_param_did.is_none() {
|
||||
if let Some(param_did) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.promoted_mir_of_const_arg((def.did, param_did));
|
||||
}
|
||||
}
|
||||
|
||||
let def_id = def_id.expect_local();
|
||||
if tcx.is_constructor(def.did.to_def_id()) {
|
||||
return tcx.arena.alloc(IndexVec::new());
|
||||
}
|
||||
|
||||
tcx.ensure().mir_borrowck(def_id);
|
||||
let (_, promoted) = tcx.mir_validated(def_id);
|
||||
if let Some(param_did) = def.const_param_did {
|
||||
tcx.ensure().mir_borrowck_const_arg((def.did, param_did));
|
||||
} else {
|
||||
tcx.ensure().mir_borrowck(def.did);
|
||||
}
|
||||
let (_, promoted) = tcx.mir_validated(def);
|
||||
let mut promoted = promoted.steal();
|
||||
|
||||
for (p, mut body) in promoted.iter_enumerated_mut() {
|
||||
run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, Some(p));
|
||||
run_optimization_passes(tcx, &mut body, def_id, Some(p));
|
||||
run_post_borrowck_cleanup_passes(tcx, &mut body, def.did, Some(p));
|
||||
run_optimization_passes(tcx, &mut body, def.did, Some(p));
|
||||
}
|
||||
|
||||
debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR");
|
||||
|
||||
promoted
|
||||
tcx.arena.alloc(promoted)
|
||||
}
|
||||
|
@ -60,16 +60,15 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
let def_id = src.def_id().expect_local();
|
||||
let def = src.with_opt_param().expect_local();
|
||||
|
||||
let mut rpo = traversal::reverse_postorder(body);
|
||||
let ccx = ConstCx::new(tcx, def_id, body);
|
||||
let ccx = ConstCx::new(tcx, def.did, body);
|
||||
let (temps, all_candidates) = collect_temps_and_candidates(&ccx, &mut rpo);
|
||||
|
||||
let promotable_candidates = validate_candidates(&ccx, &temps, &all_candidates);
|
||||
|
||||
let promoted =
|
||||
promote_candidates(def_id.to_def_id(), body, tcx, temps, promotable_candidates);
|
||||
let promoted = promote_candidates(def.to_global(), body, tcx, temps, promotable_candidates);
|
||||
self.promoted_fragments.set(promoted);
|
||||
}
|
||||
}
|
||||
@ -937,7 +936,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
|
||||
fn promote_candidate(
|
||||
mut self,
|
||||
def_id: DefId,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
candidate: Candidate,
|
||||
next_promoted_id: usize,
|
||||
) -> Option<Body<'tcx>> {
|
||||
@ -955,8 +954,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
literal: tcx.mk_const(ty::Const {
|
||||
ty,
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
def_id,
|
||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||
def,
|
||||
InternalSubsts::for_item(tcx, def.did, |param, _| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
tcx.lifetimes.re_erased.into()
|
||||
} else {
|
||||
@ -1100,7 +1099,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn promote_candidates<'tcx>(
|
||||
def_id: DefId,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
body: &mut Body<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mut temps: IndexVec<Local, TempState>,
|
||||
@ -1157,7 +1156,7 @@ pub fn promote_candidates<'tcx>(
|
||||
};
|
||||
|
||||
//FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice
|
||||
if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) {
|
||||
if let Some(promoted) = promoter.promote_candidate(def, candidate, promotions.len()) {
|
||||
promotions.push(promoted);
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +248,10 @@ pub fn write_mir_pretty<'tcx>(
|
||||
|
||||
for (i, body) in tcx.promoted_mir(def_id).iter_enumerated() {
|
||||
writeln!(w)?;
|
||||
let src = MirSource { instance: ty::InstanceDef::Item(def_id), promoted: Some(i) };
|
||||
let src = MirSource {
|
||||
instance: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
promoted: Some(i),
|
||||
};
|
||||
write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?;
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,19 @@ use rustc_target::spec::PanicStrategy;
|
||||
|
||||
use super::lints;
|
||||
|
||||
crate fn mir_built(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::steal::Steal<Body<'_>> {
|
||||
tcx.alloc_steal_mir(mir_build(tcx, def_id))
|
||||
crate fn mir_built<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> &'tcx ty::steal::Steal<Body<'tcx>> {
|
||||
if def.const_param_did.is_none() {
|
||||
if let const_param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
|
||||
return tcx.mir_built(ty::WithOptConstParam { const_param_did, ..def });
|
||||
}
|
||||
}
|
||||
|
||||
tcx.alloc_steal_mir(mir_build(tcx, def))
|
||||
}
|
||||
|
||||
/// Construct the MIR for a given `DefId`.
|
||||
fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> {
|
||||
let id = tcx.hir().as_local_hir_id(def_id);
|
||||
fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||
let id = tcx.hir().as_local_hir_id(def.did);
|
||||
|
||||
// Figure out what primary body this item has.
|
||||
let (body_id, return_ty_span) = match tcx.hir().get(id) {
|
||||
@ -57,11 +63,11 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> {
|
||||
}) => (*body_id, ty.span),
|
||||
Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => (*body, tcx.hir().span(*hir_id)),
|
||||
|
||||
_ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id),
|
||||
_ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def.did),
|
||||
};
|
||||
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let cx = Cx::new(&infcx, id);
|
||||
let cx = Cx::new(&infcx, def, id);
|
||||
let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors {
|
||||
build::construct_error(cx, body_id)
|
||||
} else if cx.body_owner_kind.is_fn_or_closure() {
|
||||
@ -181,7 +187,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Body<'_> {
|
||||
build::construct_const(cx, body_id, return_ty, return_ty_span)
|
||||
};
|
||||
|
||||
lints::check(tcx, &body, def_id);
|
||||
lints::check(tcx, &body, def.did);
|
||||
|
||||
// The borrow checker will replace all the regions here with its own
|
||||
// inference variables. There's no point having non-erased regions here.
|
||||
|
@ -600,7 +600,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
||||
// and not the beginning of discriminants (which is always `0`)
|
||||
let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
|
||||
let lhs = mk_const(cx.tcx().mk_const(ty::Const {
|
||||
val: ty::ConstKind::Unevaluated(did, substs, None),
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
ty::WithOptConstParam::unknown(did),
|
||||
substs,
|
||||
None,
|
||||
),
|
||||
ty: var_ty,
|
||||
}));
|
||||
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
|
||||
@ -796,7 +800,11 @@ fn convert_path_expr<'a, 'tcx>(
|
||||
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
|
||||
ExprKind::Literal {
|
||||
literal: cx.tcx.mk_const(ty::Const {
|
||||
val: ty::ConstKind::Unevaluated(def_id, substs, None),
|
||||
val: ty::ConstKind::Unevaluated(
|
||||
ty::WithOptConstParam::unknown(def_id),
|
||||
substs,
|
||||
None,
|
||||
),
|
||||
ty: cx.tables().node_type(expr.hir_id),
|
||||
}),
|
||||
user_ty,
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! This module contains the fcuntaiontliy to convert from the wacky tcx data
|
||||
//! This module contains the functionality to convert from the wacky tcx data
|
||||
//! structures into the HAIR. The `builder` is generally ignorant of the tcx,
|
||||
//! etc., and instead goes through the `Cx` for most of its work.
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::hair::*;
|
||||
use rustc_ast::ast;
|
||||
use rustc_ast::attr;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::Node;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
@ -50,10 +50,13 @@ crate struct Cx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
crate fn new(infcx: &'a InferCtxt<'a, 'tcx>, src_id: hir::HirId) -> Cx<'a, 'tcx> {
|
||||
crate fn new(
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
src_id: hir::HirId,
|
||||
) -> Cx<'a, 'tcx> {
|
||||
let tcx = infcx.tcx;
|
||||
let src_def_id = tcx.hir().local_def_id(src_id);
|
||||
let tables = tcx.typeck_tables_of(src_def_id);
|
||||
let tables = tcx.typeck_tables_of_opt_const_arg(def);
|
||||
let body_owner_kind = tcx.hir().body_owner_kind(src_id);
|
||||
|
||||
let constness = match body_owner_kind {
|
||||
@ -78,12 +81,12 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
|
||||
tcx,
|
||||
infcx,
|
||||
root_lint_level: src_id,
|
||||
param_env: tcx.param_env(src_def_id),
|
||||
identity_substs: InternalSubsts::identity_for_item(tcx, src_def_id.to_def_id()),
|
||||
region_scope_tree: tcx.region_scope_tree(src_def_id),
|
||||
param_env: tcx.param_env(def.did),
|
||||
identity_substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
|
||||
region_scope_tree: tcx.region_scope_tree(def.did),
|
||||
tables,
|
||||
constness,
|
||||
body_owner: src_def_id.to_def_id(),
|
||||
body_owner: def.did.to_def_id(),
|
||||
body_owner_kind,
|
||||
check_overflow,
|
||||
}
|
||||
|
@ -524,10 +524,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||
let stalled_on = &mut pending_obligation.stalled_on;
|
||||
|
||||
let mut evaluate = |c: &'tcx Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
|
||||
match self.selcx.infcx().const_eval_resolve(
|
||||
obligation.param_env,
|
||||
def_id,
|
||||
def,
|
||||
substs,
|
||||
promoted,
|
||||
Some(obligation.cause.span),
|
||||
|
@ -507,11 +507,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2);
|
||||
|
||||
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
|
||||
self.infcx
|
||||
.const_eval_resolve(
|
||||
obligation.param_env,
|
||||
def_id,
|
||||
def,
|
||||
substs,
|
||||
promoted,
|
||||
Some(obligation.cause.span),
|
||||
|
@ -116,8 +116,8 @@ pub fn predicate_obligations<'a, 'tcx>(
|
||||
wf.compute(data.skip_binder().a.into()); // (*)
|
||||
wf.compute(data.skip_binder().b.into()); // (*)
|
||||
}
|
||||
&ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
let obligations = wf.nominal_obligations(def_id, substs);
|
||||
&ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
let obligations = wf.nominal_obligations(def.did, substs);
|
||||
wf.out.extend(obligations);
|
||||
|
||||
for arg in substs.iter() {
|
||||
@ -359,13 +359,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
|
||||
GenericArgKind::Const(constant) => {
|
||||
match constant.val {
|
||||
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
|
||||
ty::ConstKind::Unevaluated(def, substs, promoted) => {
|
||||
assert!(promoted.is_none());
|
||||
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
let obligations = self.nominal_obligations(def.did, substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate = ty::PredicateKind::ConstEvaluatable(def_id, substs)
|
||||
let predicate = ty::PredicateKind::ConstEvaluatable(def, substs)
|
||||
.to_predicate(self.tcx());
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
self.out.push(traits::Obligation::new(
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, Instance, TyCtxt, TypeFoldable};
|
||||
@ -14,15 +14,43 @@ fn resolve_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorReported> {
|
||||
let (param_env, (def_id, substs)) = key.into_parts();
|
||||
let (param_env, (did, substs)) = key.into_parts();
|
||||
if let Some(did) = did.as_local() {
|
||||
if let Some(param_did) = tcx.opt_const_param_of(did) {
|
||||
return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs)));
|
||||
}
|
||||
}
|
||||
|
||||
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
||||
let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
|
||||
inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs)))
|
||||
}
|
||||
|
||||
fn resolve_instance_of_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorReported> {
|
||||
let (param_env, (did, const_param_did, substs)) = key.into_parts();
|
||||
inner_resolve_instance(
|
||||
tcx,
|
||||
param_env.and((
|
||||
ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) },
|
||||
substs,
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
fn inner_resolve_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorReported> {
|
||||
let (param_env, (def, substs)) = key.into_parts();
|
||||
|
||||
debug!("resolve(def={:?}, substs={:?})", def.did, substs);
|
||||
let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) {
|
||||
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
|
||||
let item = tcx.associated_item(def_id);
|
||||
let item = tcx.associated_item(def.did);
|
||||
resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
|
||||
} else {
|
||||
let ty = tcx.type_of(def_id);
|
||||
let ty = tcx.type_of(def.def_id_for_type_of());
|
||||
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty);
|
||||
|
||||
let def = match item_type.kind {
|
||||
@ -33,7 +61,7 @@ fn resolve_instance<'tcx>(
|
||||
} =>
|
||||
{
|
||||
debug!(" => intrinsic");
|
||||
ty::InstanceDef::Intrinsic(def_id)
|
||||
ty::InstanceDef::Intrinsic(def.did)
|
||||
}
|
||||
ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
|
||||
let ty = substs.type_at(0);
|
||||
@ -53,12 +81,12 @@ fn resolve_instance<'tcx>(
|
||||
}
|
||||
_ => {
|
||||
debug!(" => free item");
|
||||
ty::InstanceDef::Item(def_id)
|
||||
ty::InstanceDef::Item(def)
|
||||
}
|
||||
};
|
||||
Ok(Some(Instance { def, substs }))
|
||||
};
|
||||
debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
|
||||
debug!("resolve(def.did={:?}, substs={:?}) = {:?}", def.did, substs, result);
|
||||
result
|
||||
}
|
||||
|
||||
@ -182,7 +210,9 @@ fn resolve_associated_item<'tcx>(
|
||||
Some(ty::Instance::new(leaf_def.item.def_id, substs))
|
||||
}
|
||||
traits::ImplSourceGenerator(generator_data) => Some(Instance {
|
||||
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
||||
def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
|
||||
generator_data.generator_def_id,
|
||||
)),
|
||||
substs: generator_data.substs,
|
||||
}),
|
||||
traits::ImplSourceClosure(closure_data) => {
|
||||
@ -244,5 +274,6 @@ fn resolve_associated_item<'tcx>(
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers { resolve_instance, ..*providers };
|
||||
*providers =
|
||||
ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers };
|
||||
}
|
||||
|
@ -886,8 +886,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
let ct_def_id = tcx.hir().local_def_id(ct.value.hir_id);
|
||||
ty::Const::from_anon_const(tcx, ct_def_id).into()
|
||||
ty::Const::from_opt_const_arg_anon_const(
|
||||
tcx,
|
||||
ty::WithOptConstParam {
|
||||
did: tcx.hir().local_def_id(ct.value.hir_id),
|
||||
const_param_did: Some(param.def_id),
|
||||
},
|
||||
)
|
||||
.into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|
@ -325,7 +325,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => self.to_ty(ty).into(),
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.to_const(&ct.value).into()
|
||||
self.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|
@ -764,6 +764,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
method::provide(providers);
|
||||
*providers = Providers {
|
||||
typeck_item_bodies,
|
||||
typeck_tables_of_const_arg,
|
||||
typeck_tables_of,
|
||||
diagnostic_only_typeck_tables_of,
|
||||
has_typeck_tables,
|
||||
@ -955,9 +956,21 @@ where
|
||||
val.fold_with(&mut FixupFolder { tcx })
|
||||
}
|
||||
|
||||
fn typeck_tables_of_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) -> &ty::TypeckTables<'tcx> {
|
||||
let fallback = move || tcx.type_of(param_did);
|
||||
typeck_tables_of_with_fallback(tcx, did, fallback)
|
||||
}
|
||||
|
||||
fn typeck_tables_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckTables<'tcx> {
|
||||
let fallback = move || tcx.type_of(def_id.to_def_id());
|
||||
typeck_tables_of_with_fallback(tcx, def_id, fallback)
|
||||
if let Some(param_did) = tcx.opt_const_param_of(def_id) {
|
||||
tcx.typeck_tables_of_const_arg((def_id, param_did))
|
||||
} else {
|
||||
let fallback = move || tcx.type_of(def_id.to_def_id());
|
||||
typeck_tables_of_with_fallback(tcx, def_id, fallback)
|
||||
}
|
||||
}
|
||||
|
||||
/// Used only to get `TypeckTables` for type inference during error recovery.
|
||||
@ -3542,6 +3555,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
c
|
||||
}
|
||||
|
||||
pub fn const_arg_to_const(
|
||||
&self,
|
||||
ast_c: &hir::AnonConst,
|
||||
param_def_id: DefId,
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
let const_def = ty::WithOptConstParam {
|
||||
did: self.tcx.hir().local_def_id(ast_c.hir_id),
|
||||
const_param_did: Some(param_def_id),
|
||||
};
|
||||
let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
|
||||
self.register_wf_obligation(
|
||||
c.into(),
|
||||
self.tcx.hir().span(ast_c.hir_id),
|
||||
ObligationCauseCode::MiscObligation,
|
||||
);
|
||||
c
|
||||
}
|
||||
|
||||
// If the type given by the user has free regions, save it for later, since
|
||||
// NLL would like to enforce those. Also pass in types that involve
|
||||
// projections, since those can resolve to `'static` bounds (modulo #54940,
|
||||
@ -5655,7 +5686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.to_ty(ty).into()
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.to_const(&ct.value).into()
|
||||
self.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|
@ -423,8 +423,11 @@ fn check_type_defn<'tcx, F>(
|
||||
fcx.register_predicate(traits::Obligation::new(
|
||||
cause,
|
||||
fcx.param_env,
|
||||
ty::PredicateKind::ConstEvaluatable(discr_def_id.to_def_id(), discr_substs)
|
||||
.to_predicate(fcx.tcx),
|
||||
ty::PredicateKind::ConstEvaluatable(
|
||||
ty::WithOptConstParam::unknown(discr_def_id.to_def_id()),
|
||||
discr_substs,
|
||||
)
|
||||
.to_predicate(fcx.tcx),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
opt_const_param_of: type_of::opt_const_param_of,
|
||||
type_of: type_of::type_of,
|
||||
generics_of,
|
||||
predicates_of,
|
||||
|
@ -17,29 +17,141 @@ use rustc_trait_selection::traits;
|
||||
use super::ItemCtxt;
|
||||
use super::{bad_placeholder_type, is_suggestable_infer_ty};
|
||||
|
||||
/// Computes the relevant generic parameter for a potential generic const argument.
|
||||
///
|
||||
/// This should be called using the query `tcx.opt_const_param_of`.
|
||||
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
|
||||
use hir::*;
|
||||
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id);
|
||||
|
||||
if let Node::AnonConst(_) = tcx.hir().get(hir_id) {
|
||||
let parent_node_id = tcx.hir().get_parent_node(hir_id);
|
||||
let parent_node = tcx.hir().get(parent_node_id);
|
||||
|
||||
match parent_node {
|
||||
Node::Expr(&Expr {
|
||||
kind:
|
||||
ExprKind::MethodCall(segment, ..) | ExprKind::Path(QPath::TypeRelative(_, segment)),
|
||||
..
|
||||
}) => {
|
||||
let body_owner = tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id));
|
||||
let tables = tcx.typeck_tables_of(body_owner);
|
||||
// This may fail in case the method/path does not actually exist.
|
||||
// As there is no relevant param for `def_id`, we simply return
|
||||
// `None` here.
|
||||
let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?;
|
||||
let idx = segment
|
||||
.args
|
||||
.and_then(|args| {
|
||||
args.args
|
||||
.iter()
|
||||
.filter(|arg| arg.is_const())
|
||||
.position(|arg| arg.id() == hir_id)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
bug!("no arg matching AnonConst in segment");
|
||||
});
|
||||
|
||||
tcx.generics_of(type_dependent_def)
|
||||
.params
|
||||
.iter()
|
||||
.filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const))
|
||||
.nth(idx)
|
||||
.map(|param| param.def_id)
|
||||
}
|
||||
|
||||
Node::Ty(&Ty { kind: TyKind::Path(_), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Struct(..), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Path(_), .. })
|
||||
| Node::TraitRef(..) => {
|
||||
let path = match parent_node {
|
||||
Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. })
|
||||
| Node::TraitRef(&TraitRef { path, .. }) => &*path,
|
||||
Node::Expr(&Expr {
|
||||
kind:
|
||||
ExprKind::Path(QPath::Resolved(_, path))
|
||||
| ExprKind::Struct(&QPath::Resolved(_, path), ..),
|
||||
..
|
||||
}) => {
|
||||
let body_owner =
|
||||
tcx.hir().local_def_id(tcx.hir().enclosing_body_owner(hir_id));
|
||||
let _tables = tcx.typeck_tables_of(body_owner);
|
||||
&*path
|
||||
}
|
||||
_ => span_bug!(DUMMY_SP, "unexpected const parent path {:?}", parent_node),
|
||||
};
|
||||
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
|
||||
let (arg_index, segment) = path
|
||||
.segments
|
||||
.iter()
|
||||
.filter_map(|seg| seg.args.map(|args| (args.args, seg)))
|
||||
.find_map(|(args, seg)| {
|
||||
args.iter()
|
||||
.filter(|arg| arg.is_const())
|
||||
.position(|arg| arg.id() == hir_id)
|
||||
.map(|index| (index, seg))
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
bug!("no arg matching AnonConst in path");
|
||||
});
|
||||
|
||||
// Try to use the segment resolution if it is valid, otherwise we
|
||||
// default to the path resolution.
|
||||
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
|
||||
let generics = match res {
|
||||
Res::Def(DefKind::Ctor(..), def_id) => {
|
||||
tcx.generics_of(tcx.parent(def_id).unwrap())
|
||||
}
|
||||
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
||||
Res::Err => {
|
||||
tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
|
||||
return None;
|
||||
}
|
||||
_ => span_bug!(
|
||||
DUMMY_SP,
|
||||
"unexpected anon const res {:?} in path: {:?}",
|
||||
res,
|
||||
path,
|
||||
),
|
||||
};
|
||||
|
||||
generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const))
|
||||
.nth(arg_index)
|
||||
.map(|param| param.def_id)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
let def_id = def_id.expect_local();
|
||||
use rustc_hir::*;
|
||||
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id);
|
||||
|
||||
let icx = ItemCtxt::new(tcx, def_id);
|
||||
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
|
||||
|
||||
match tcx.hir().get(hir_id) {
|
||||
Node::TraitItem(item) => match item.kind {
|
||||
TraitItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_fn_def(def_id.to_def_id(), substs)
|
||||
}
|
||||
TraitItemKind::Const(ref ty, body_id) => body_id
|
||||
.and_then(|body_id| {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
Some(infer_placeholder_type(
|
||||
tcx,
|
||||
def_id.expect_local(),
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
))
|
||||
Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -53,12 +165,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
|
||||
Node::ImplItem(item) => match item.kind {
|
||||
ImplItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_fn_def(def_id.to_def_id(), substs)
|
||||
}
|
||||
ImplItemKind::Const(ref ty, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(tcx, def_id.expect_local(), body_id, ty.span, item.ident)
|
||||
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
@ -76,13 +188,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
match item.kind {
|
||||
ItemKind::Static(ref ty, .., body_id) | ItemKind::Const(ref ty, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id.expect_local(),
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
)
|
||||
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
@ -91,26 +197,26 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
icx.to_ty(self_ty)
|
||||
}
|
||||
ItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_fn_def(def_id.to_def_id(), substs)
|
||||
}
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
let def = tcx.adt_def(def_id);
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_adt(def, substs)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => {
|
||||
let_position_impl_trait_type(tcx, def_id.expect_local())
|
||||
let_position_impl_trait_type(tcx, def_id)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
|
||||
find_opaque_ty_constraints(tcx, def_id.expect_local())
|
||||
find_opaque_ty_constraints(tcx, def_id)
|
||||
}
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
|
||||
let concrete_ty = tcx
|
||||
.mir_borrowck(owner.expect_local())
|
||||
.concrete_opaque_types
|
||||
.get(&def_id)
|
||||
.get(&def_id.to_def_id())
|
||||
.map(|opaque| opaque.concrete_type)
|
||||
.unwrap_or_else(|| {
|
||||
tcx.sess.delay_span_bug(
|
||||
@ -132,8 +238,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
// resolves to itself. Return the non-revealed
|
||||
// type, which should result in E0720.
|
||||
tcx.mk_opaque(
|
||||
def_id,
|
||||
InternalSubsts::identity_for_item(tcx, def_id),
|
||||
def_id.to_def_id(),
|
||||
InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
|
||||
)
|
||||
}
|
||||
});
|
||||
@ -158,11 +264,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
|
||||
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_fn_def(def_id.to_def_id(), substs)
|
||||
}
|
||||
ForeignItemKind::Static(ref t, _) => icx.to_ty(t),
|
||||
ForeignItemKind::Type => tcx.mk_foreign(def_id),
|
||||
ForeignItemKind::Type => tcx.mk_foreign(def_id.to_def_id()),
|
||||
},
|
||||
|
||||
Node::Ctor(&ref def) | Node::Variant(Variant { data: ref def, .. }) => match *def {
|
||||
@ -170,23 +276,29 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id())
|
||||
}
|
||||
VariantData::Tuple(..) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_fn_def(def_id, substs)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
tcx.mk_fn_def(def_id.to_def_id(), substs)
|
||||
}
|
||||
},
|
||||
|
||||
Node::Field(field) => icx.to_ty(&field.ty),
|
||||
|
||||
Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
if let Some(movability) = gen {
|
||||
tcx.mk_generator(def_id, substs, movability)
|
||||
tcx.mk_generator(def_id.to_def_id(), substs, movability)
|
||||
} else {
|
||||
tcx.mk_closure(def_id, substs)
|
||||
tcx.mk_closure(def_id.to_def_id(), substs)
|
||||
}
|
||||
}
|
||||
|
||||
Node::AnonConst(_) => {
|
||||
if let Some(param) = tcx.opt_const_param_of(def_id) {
|
||||
// We defer to `type_of` of the corresponding parameter
|
||||
// for generic arguments.
|
||||
return tcx.type_of(param);
|
||||
}
|
||||
|
||||
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
|
||||
match parent_node {
|
||||
Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
|
||||
@ -203,94 +315,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
.discr_type()
|
||||
.to_ty(tcx),
|
||||
|
||||
Node::Ty(&Ty { kind: TyKind::Path(_), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Struct(..) | ExprKind::Path(_), .. })
|
||||
| Node::TraitRef(..) => {
|
||||
let path = match parent_node {
|
||||
Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. })
|
||||
| Node::Expr(&Expr {
|
||||
kind:
|
||||
ExprKind::Path(QPath::Resolved(_, path))
|
||||
| ExprKind::Struct(&QPath::Resolved(_, path), ..),
|
||||
..
|
||||
})
|
||||
| Node::TraitRef(&TraitRef { path, .. }) => &*path,
|
||||
_ => {
|
||||
return tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
&format!("unexpected const parent path {:?}", parent_node),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
|
||||
let (arg_index, segment) = path
|
||||
.segments
|
||||
.iter()
|
||||
.filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
|
||||
.find_map(|(args, seg)| {
|
||||
args.iter()
|
||||
.filter(|arg| arg.is_const())
|
||||
.enumerate()
|
||||
.filter(|(_, arg)| arg.id() == hir_id)
|
||||
.map(|(index, _)| (index, seg))
|
||||
.next()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
bug!("no arg matching AnonConst in path");
|
||||
});
|
||||
|
||||
// Try to use the segment resolution if it is valid, otherwise we
|
||||
// default to the path resolution.
|
||||
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
|
||||
let generics = match res {
|
||||
Res::Def(DefKind::Ctor(..), def_id) => {
|
||||
tcx.generics_of(tcx.parent(def_id).unwrap())
|
||||
}
|
||||
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
||||
res => {
|
||||
return tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"unexpected anon const res {:?} in path: {:?}",
|
||||
res, path,
|
||||
),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let ty = generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|param| {
|
||||
if let ty::GenericParamDefKind::Const = param.kind {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.nth(arg_index)
|
||||
.map(|param| tcx.type_of(param.def_id));
|
||||
|
||||
if let Some(ty) = ty {
|
||||
ty
|
||||
} else {
|
||||
// This is no generic parameter associated with the arg. This is
|
||||
// probably from an extra arg where one is not needed.
|
||||
tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
&format!(
|
||||
"missing generic parameter for `AnonConst`, \
|
||||
parent: {:?}, res: {:?}",
|
||||
parent_node, res
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
x => tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
&format!("unexpected const parent in type_of_def_id(): {:?}", x),
|
||||
|
@ -466,12 +466,12 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
|
||||
|
||||
pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
|
||||
match n.val {
|
||||
ty::ConstKind::Unevaluated(def_id, _, promoted) => {
|
||||
let mut s = if let Some(def_id) = def_id.as_local() {
|
||||
let hir_id = cx.tcx.hir().as_local_hir_id(def_id);
|
||||
ty::ConstKind::Unevaluated(def, _, promoted) => {
|
||||
let mut s = if let Some(def) = def.as_local() {
|
||||
let hir_id = cx.tcx.hir().as_local_hir_id(def.did);
|
||||
print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id))
|
||||
} else {
|
||||
inline::print_inlined_const(cx, def_id)
|
||||
inline::print_inlined_const(cx, def.did)
|
||||
};
|
||||
if let Some(promoted) = promoted {
|
||||
s.push_str(&format!("::{:?}", promoted))
|
||||
|
@ -25,7 +25,7 @@ pub fn change_callee_function() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_callee_function() {
|
||||
callee2(1, 2)
|
||||
@ -40,7 +40,7 @@ pub fn change_argument_function() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_argument_function() {
|
||||
callee1(1, 3)
|
||||
@ -81,7 +81,7 @@ pub fn change_callee_method() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_callee_method() {
|
||||
let s = Struct;
|
||||
@ -98,7 +98,7 @@ pub fn change_argument_method() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_argument_method() {
|
||||
let s = Struct;
|
||||
@ -115,7 +115,7 @@ pub fn change_ufcs_callee_method() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_ufcs_callee_method() {
|
||||
let s = Struct;
|
||||
@ -132,7 +132,7 @@ pub fn change_argument_method_ufcs() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_argument_method_ufcs() {
|
||||
let s = Struct;
|
||||
@ -149,7 +149,7 @@ pub fn change_to_ufcs() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
// One might think this would be expanded in the hir_owner_nodes/Mir, but it actually
|
||||
// results in slightly different hir_owner/Mir.
|
||||
@ -171,7 +171,7 @@ pub mod change_ufcs_callee_indirectly {
|
||||
#[cfg(not(cfail1))]
|
||||
use super::Struct2 as Struct;
|
||||
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ pub fn add_parameter() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_parameter() {
|
||||
let x = 0u32;
|
||||
@ -53,7 +53,7 @@ pub fn change_parameter_pattern() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_parameter_pattern() {
|
||||
let _ = |(x,): (u32,)| x;
|
||||
@ -101,7 +101,7 @@ pub fn change_parameter_type() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_parameter_type() {
|
||||
let closure = |x: u16| (x as u64) + 1;
|
||||
|
@ -34,7 +34,7 @@ pub fn change_field_value_struct_like() -> Enum {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_field_value_struct_like() -> Enum {
|
||||
Enum::Struct {
|
||||
@ -96,7 +96,7 @@ pub fn change_constructor_path_struct_like() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_path_struct_like() {
|
||||
let _ = Enum2::Struct {
|
||||
@ -119,7 +119,7 @@ pub fn change_constructor_variant_struct_like() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_variant_struct_like() {
|
||||
let _ = Enum2::Struct2 {
|
||||
@ -139,7 +139,7 @@ pub mod change_constructor_path_indirectly_struct_like {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,mir_built,\
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
|
||||
typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
@ -161,7 +161,7 @@ pub mod change_constructor_variant_indirectly_struct_like {
|
||||
#[cfg(not(cfail1))]
|
||||
use super::Enum2::Struct2 as Variant;
|
||||
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn function() -> Enum2 {
|
||||
Variant {
|
||||
@ -180,7 +180,7 @@ pub fn change_field_value_tuple_like() -> Enum {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_field_value_tuple_like() -> Enum {
|
||||
Enum::Tuple(0, 1, 3)
|
||||
@ -197,7 +197,7 @@ pub fn change_constructor_path_tuple_like() {
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of"
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_path_tuple_like() {
|
||||
@ -215,7 +215,7 @@ pub fn change_constructor_variant_tuple_like() {
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of"
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_variant_tuple_like() {
|
||||
@ -232,7 +232,7 @@ pub mod change_constructor_path_indirectly_tuple_like {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,mir_built,\
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
|
||||
typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
@ -251,7 +251,7 @@ pub mod change_constructor_variant_indirectly_tuple_like {
|
||||
#[cfg(not(cfail1))]
|
||||
use super::Enum2::Tuple2 as Variant;
|
||||
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn function() -> Enum2 {
|
||||
Variant(0, 1, 2)
|
||||
@ -278,7 +278,7 @@ pub fn change_constructor_path_c_like() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_path_c_like() {
|
||||
let _x = Clike2::B;
|
||||
@ -293,7 +293,7 @@ pub fn change_constructor_variant_c_like() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_variant_c_like() {
|
||||
let _x = Clike::C;
|
||||
@ -309,7 +309,7 @@ pub mod change_constructor_path_indirectly_c_like {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,mir_built,\
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
|
||||
typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
@ -328,7 +328,7 @@ pub mod change_constructor_variant_indirectly_c_like {
|
||||
#[cfg(not(cfail1))]
|
||||
use super::Clike::B as Variant;
|
||||
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn function() -> Clike {
|
||||
Variant
|
||||
|
@ -16,7 +16,7 @@ pub fn body_not_exported_to_metadata() -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn body_not_exported_to_metadata() -> u32 {
|
||||
2
|
||||
@ -35,7 +35,7 @@ pub fn body_exported_to_metadata_because_of_inline() -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[inline]
|
||||
pub fn body_exported_to_metadata_because_of_inline() -> u32 {
|
||||
@ -55,7 +55,7 @@ pub fn body_exported_to_metadata_because_of_generic() -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[inline]
|
||||
pub fn body_exported_to_metadata_because_of_generic() -> u32 {
|
||||
|
@ -25,7 +25,7 @@ pub fn change_loop_body() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_body() {
|
||||
let mut _x = 0;
|
||||
@ -48,7 +48,7 @@ pub fn change_iteration_variable_name() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_iteration_variable_name() {
|
||||
let mut _x = 0;
|
||||
@ -71,7 +71,7 @@ pub fn change_iteration_variable_pattern() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_iteration_variable_pattern() {
|
||||
let mut _x = 0;
|
||||
@ -94,7 +94,7 @@ pub fn change_iterable() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, promoted_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, promoted_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_iterable() {
|
||||
let mut _x = 0;
|
||||
@ -116,7 +116,7 @@ pub fn add_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_break() {
|
||||
let mut _x = 0;
|
||||
@ -187,7 +187,7 @@ pub fn change_break_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_break_label() {
|
||||
let mut _x = 0;
|
||||
@ -237,7 +237,7 @@ pub fn change_continue_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_label() {
|
||||
let mut _x = 0;
|
||||
@ -262,7 +262,7 @@ pub fn change_continue_to_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_to_break() {
|
||||
let mut _x = 0;
|
||||
|
@ -22,7 +22,7 @@ pub fn add_parameter() {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn add_parameter(p: i32) {}
|
||||
@ -45,7 +45,7 @@ pub fn type_of_parameter(p: i32) {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn type_of_parameter(p: i64) {}
|
||||
@ -58,7 +58,7 @@ pub fn type_of_parameter_ref(p: &i32) {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn type_of_parameter_ref(p: &mut i32) {}
|
||||
@ -71,7 +71,7 @@ pub fn order_of_parameters(p1: i32, p2: i64) {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn order_of_parameters(p2: i64, p1: i32) {}
|
||||
@ -84,7 +84,7 @@ pub fn make_unsafe() {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub unsafe fn make_unsafe() {}
|
||||
@ -274,7 +274,7 @@ pub mod change_return_type_indirectly {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn indirect_return_type() -> ReturnType {
|
||||
@ -292,7 +292,7 @@ pub mod change_parameter_type_indirectly {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of, fn_sig"
|
||||
except = "hir_owner, hir_owner_nodes, optimized_mir, typeck_tables_of, fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn indirect_parameter_type(p: ParameterType) {}
|
||||
|
@ -25,7 +25,7 @@ pub fn change_condition(x: bool) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_condition(x: bool) -> u32 {
|
||||
if !x {
|
||||
@ -46,7 +46,7 @@ pub fn change_then_branch(x: bool) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_then_branch(x: bool) -> u32 {
|
||||
if x {
|
||||
@ -69,7 +69,7 @@ pub fn change_else_branch(x: bool) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_else_branch(x: bool) -> u32 {
|
||||
if x {
|
||||
@ -120,7 +120,7 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_condition_if_let(x: Option<u32>) -> u32 {
|
||||
if let Some(_) = x {
|
||||
@ -143,7 +143,7 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
|
||||
if let Some(x) = x {
|
||||
@ -166,7 +166,7 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
|
||||
if let Some(x) = x {
|
||||
|
@ -44,7 +44,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner_nodes,optimized_mir,promoted_mir,mir_built,typeck_tables_of"
|
||||
except="hir_owner_nodes,optimized_mir,promoted_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn method_body() {
|
||||
@ -68,7 +68,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner_nodes,optimized_mir,promoted_mir,mir_built,typeck_tables_of"
|
||||
except="hir_owner_nodes,optimized_mir,promoted_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[inline]
|
||||
@ -120,7 +120,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir,mir_built"
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn method_selfmutness(&mut self) { }
|
||||
@ -160,7 +160,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir,mir_built"
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_method_parameter(&self, _: i32) { }
|
||||
@ -178,7 +178,7 @@ impl Foo {
|
||||
#[rustc_clean(cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_method_parameter_name(&self, b: i64) { }
|
||||
}
|
||||
@ -197,7 +197,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,mir_built,typeck_tables_of")]
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_method_return_type(&self) -> u8 { 0 }
|
||||
}
|
||||
@ -232,7 +232,7 @@ impl Foo {
|
||||
#[rustc_clean(cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
impl Foo {
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
|
||||
}
|
||||
@ -251,7 +251,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir,mir_built"
|
||||
except="hir_owner,hir_owner_nodes,fn_sig,typeck_tables_of,optimized_mir"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub unsafe fn make_method_unsafe(&self) { }
|
||||
@ -453,7 +453,7 @@ impl Bar<u32> {
|
||||
impl<T> Bar<T> {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="generics_of,fn_sig,typeck_tables_of,type_of,optimized_mir,mir_built"
|
||||
except="generics_of,fn_sig,typeck_tables_of,type_of,optimized_mir"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_type_parameter_to_impl(&self) { }
|
||||
@ -471,7 +471,7 @@ impl Bar<u32> {
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
impl Bar<u64> {
|
||||
#[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_impl_self_type(&self) { }
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ pub fn change_template(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_template(a: i32) -> i32 {
|
||||
@ -69,7 +69,7 @@ pub fn change_output(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_output(a: i32) -> i32 {
|
||||
@ -105,7 +105,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_input(_a: i32, _b: i32) -> i32 {
|
||||
@ -140,7 +140,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
|
||||
@ -175,7 +175,7 @@ pub fn change_clobber(_a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_clobber(_a: i32) -> i32 {
|
||||
@ -210,7 +210,7 @@ pub fn change_options(_a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn change_options(_a: i32) -> i32 {
|
||||
|
@ -22,7 +22,7 @@ pub fn change_name() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_name() {
|
||||
let _y = 2u64;
|
||||
@ -38,7 +38,7 @@ pub fn add_type() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built")]
|
||||
except="hir_owner_nodes,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_type() {
|
||||
let _x: u32 = 2u32;
|
||||
@ -54,7 +54,7 @@ pub fn change_type() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_type() {
|
||||
let _x: u8 = 2;
|
||||
@ -70,7 +70,7 @@ pub fn change_mutability_of_reference_type() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_mutability_of_reference_type() {
|
||||
let _x: &mut u64;
|
||||
@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_mutability_of_slot() {
|
||||
let _x: u64 = 0;
|
||||
@ -102,7 +102,7 @@ pub fn change_simple_binding_to_pattern() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_simple_binding_to_pattern() {
|
||||
let (_a, _b) = (0u8, 'x');
|
||||
@ -118,7 +118,7 @@ pub fn change_name_in_pattern() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_name_in_pattern() {
|
||||
let (_a, _c) = (1u8, 'y');
|
||||
@ -134,7 +134,7 @@ pub fn add_ref_in_pattern() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_ref_in_pattern() {
|
||||
let (ref _a, _b) = (1u8, 'y');
|
||||
@ -150,7 +150,7 @@ pub fn add_amp_in_pattern() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_amp_in_pattern() {
|
||||
let (&_a, _b) = (&1u8, 'y');
|
||||
@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_mutability_of_binding_in_pattern() {
|
||||
let (mut _a, _b) = (99u8, 'q');
|
||||
@ -182,7 +182,7 @@ pub fn add_initializer() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,typeck_tables_of,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,typeck_tables_of,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_initializer() {
|
||||
let _x: i16 = 3i16;
|
||||
@ -198,7 +198,7 @@ pub fn change_initializer() {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_initializer() {
|
||||
let _x = 5u16;
|
||||
|
@ -25,7 +25,7 @@ pub fn change_loop_body() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_body() {
|
||||
let mut _x = 0;
|
||||
@ -47,7 +47,7 @@ pub fn add_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_break() {
|
||||
let mut _x = 0;
|
||||
@ -118,7 +118,7 @@ pub fn change_break_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_break_label() {
|
||||
let mut _x = 0;
|
||||
@ -168,7 +168,7 @@ pub fn change_continue_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_label() {
|
||||
let mut _x = 0;
|
||||
@ -193,7 +193,7 @@ pub fn change_continue_to_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_to_break() {
|
||||
let mut _x = 0;
|
||||
|
@ -26,7 +26,7 @@ pub fn add_arm(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_arm(x: u32) -> u32 {
|
||||
match x {
|
||||
@ -51,7 +51,7 @@ pub fn change_order_of_arms(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_order_of_arms(x: u32) -> u32 {
|
||||
match x {
|
||||
@ -75,7 +75,7 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_guard_clause(x: u32, y: bool) -> u32 {
|
||||
match x {
|
||||
@ -99,7 +99,7 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_guard_clause(x: u32, y: bool) -> u32 {
|
||||
match x {
|
||||
@ -123,7 +123,7 @@ pub fn add_at_binding(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_at_binding(x: u32) -> u32 {
|
||||
match x {
|
||||
@ -147,7 +147,7 @@ pub fn change_name_of_at_binding(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_name_of_at_binding(x: u32) -> u32 {
|
||||
match x {
|
||||
@ -170,7 +170,7 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_simple_name_to_pattern(x: u32) -> u32 {
|
||||
match (x, x & 1) {
|
||||
@ -193,7 +193,7 @@ pub fn change_name_in_pattern(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_name_in_pattern(x: u32) -> u32 {
|
||||
match (x, x & 1) {
|
||||
@ -216,7 +216,7 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
|
||||
match (x, x & 1) {
|
||||
@ -238,7 +238,7 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
|
||||
match (x, x & 1) {
|
||||
@ -260,7 +260,7 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
|
||||
match (&x, x & 1) {
|
||||
@ -283,7 +283,7 @@ pub fn change_rhs_of_arm(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_rhs_of_arm(x: u32) -> u32 {
|
||||
match x {
|
||||
@ -307,7 +307,7 @@ pub fn add_alternative_to_arm(x: u32) -> u32 {
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2",
|
||||
except="hir_owner_nodes,mir_built,optimized_mir,typeck_tables_of")]
|
||||
except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_alternative_to_arm(x: u32) -> u32 {
|
||||
match x {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
// Indexing expression
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn indexing(slice: &[u8]) -> u8 {
|
||||
#[cfg(cfail1)]
|
||||
@ -33,7 +33,7 @@ pub fn indexing(slice: &[u8]) -> u8 {
|
||||
|
||||
|
||||
// Arithmetic overflow plus
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -48,7 +48,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 {
|
||||
|
||||
|
||||
// Arithmetic overflow minus
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -63,7 +63,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 {
|
||||
|
||||
|
||||
// Arithmetic overflow mult
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -78,7 +78,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 {
|
||||
|
||||
|
||||
// Arithmetic overflow negation
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -93,7 +93,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 {
|
||||
|
||||
|
||||
// Division by zero
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn division_by_zero(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -107,7 +107,7 @@ pub fn division_by_zero(val: i32) -> i32 {
|
||||
}
|
||||
|
||||
// Division by zero
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn mod_by_zero(val: i32) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -122,7 +122,7 @@ pub fn mod_by_zero(val: i32) -> i32 {
|
||||
|
||||
|
||||
// shift left
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn shift_left(val: i32, shift: usize) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
@ -137,7 +137,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 {
|
||||
|
||||
|
||||
// shift right
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn shift_right(val: i32, shift: usize) -> i32 {
|
||||
#[cfg(cfail1)]
|
||||
|
@ -31,7 +31,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_field_value_regular_struct() -> RegularStruct {
|
||||
RegularStruct {
|
||||
@ -82,7 +82,7 @@ pub fn add_field_regular_struct() -> RegularStruct {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_field_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
@ -117,7 +117,7 @@ pub fn change_field_label_regular_struct() -> RegularStruct {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_field_label_regular_struct() -> RegularStruct {
|
||||
let struct1 = RegularStruct {
|
||||
@ -152,7 +152,7 @@ pub fn change_constructor_path_regular_struct() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_path_regular_struct() {
|
||||
let _ = RegularStruct2 {
|
||||
@ -173,7 +173,7 @@ pub mod change_constructor_path_indirectly_regular_struct {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of"
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn function() -> Struct {
|
||||
@ -196,7 +196,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_field_value_tuple_struct() -> TupleStruct {
|
||||
TupleStruct(0, 1, 3)
|
||||
@ -213,7 +213,7 @@ pub fn change_constructor_path_tuple_struct() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,mir_built,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_constructor_path_tuple_struct() {
|
||||
let _ = TupleStruct2(0, 1, 2);
|
||||
@ -230,7 +230,7 @@ pub mod change_constructor_path_indirectly_tuple_struct {
|
||||
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of"
|
||||
except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck_tables_of"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn function() -> Struct {
|
||||
|
@ -21,7 +21,7 @@ pub fn const_negation() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn const_negation() -> i32 {
|
||||
-1
|
||||
@ -36,7 +36,7 @@ pub fn const_bitwise_not() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn const_bitwise_not() -> i32 {
|
||||
!99
|
||||
@ -51,7 +51,7 @@ pub fn var_negation(x: i32, y: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn var_negation(x: i32, y: i32) -> i32 {
|
||||
-y
|
||||
@ -66,7 +66,7 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
|
||||
!y
|
||||
@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn var_deref(x: &i32, y: &i32) -> i32 {
|
||||
*y
|
||||
@ -96,7 +96,7 @@ pub fn first_const_add() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn first_const_add() -> i32 {
|
||||
2 + 3
|
||||
@ -111,7 +111,7 @@ pub fn second_const_add() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn second_const_add() -> i32 {
|
||||
1 + 3
|
||||
@ -126,7 +126,7 @@ pub fn first_var_add(a: i32, b: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn first_var_add(a: i32, b: i32) -> i32 {
|
||||
b + 2
|
||||
@ -141,7 +141,7 @@ pub fn second_var_add(a: i32, b: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn second_var_add(a: i32, b: i32) -> i32 {
|
||||
1 + b
|
||||
@ -156,7 +156,7 @@ pub fn plus_to_minus(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn plus_to_minus(a: i32) -> i32 {
|
||||
1 - a
|
||||
@ -171,7 +171,7 @@ pub fn plus_to_mult(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn plus_to_mult(a: i32) -> i32 {
|
||||
1 * a
|
||||
@ -186,7 +186,7 @@ pub fn plus_to_div(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn plus_to_div(a: i32) -> i32 {
|
||||
1 / a
|
||||
@ -201,7 +201,7 @@ pub fn plus_to_mod(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn plus_to_mod(a: i32) -> i32 {
|
||||
1 % a
|
||||
@ -216,7 +216,7 @@ pub fn and_to_or(a: bool, b: bool) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn and_to_or(a: bool, b: bool) -> bool {
|
||||
a || b
|
||||
@ -231,7 +231,7 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
|
||||
1 | a
|
||||
@ -246,7 +246,7 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
|
||||
1 ^ a
|
||||
@ -261,7 +261,7 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn bitwise_and_to_lshift(a: i32) -> i32 {
|
||||
a << 1
|
||||
@ -276,7 +276,7 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn bitwise_and_to_rshift(a: i32) -> i32 {
|
||||
a >> 1
|
||||
@ -291,7 +291,7 @@ pub fn eq_to_uneq(a: i32) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn eq_to_uneq(a: i32) -> bool {
|
||||
a != 1
|
||||
@ -306,7 +306,7 @@ pub fn eq_to_lt(a: i32) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn eq_to_lt(a: i32) -> bool {
|
||||
a < 1
|
||||
@ -321,7 +321,7 @@ pub fn eq_to_gt(a: i32) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn eq_to_gt(a: i32) -> bool {
|
||||
a > 1
|
||||
@ -336,7 +336,7 @@ pub fn eq_to_le(a: i32) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn eq_to_le(a: i32) -> bool {
|
||||
a <= 1
|
||||
@ -351,7 +351,7 @@ pub fn eq_to_ge(a: i32) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn eq_to_ge(a: i32) -> bool {
|
||||
a >= 1
|
||||
@ -368,7 +368,7 @@ pub fn type_cast(a: u8) -> u64 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built,typeck_tables_of", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,typeck_tables_of", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn type_cast(a: u8) -> u64 {
|
||||
let b = a as u32;
|
||||
@ -385,7 +385,7 @@ pub fn value_cast(a: u32) -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn value_cast(a: u32) -> i32 {
|
||||
2 as i32
|
||||
@ -403,7 +403,7 @@ pub fn place() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn place() -> i32 {
|
||||
let mut x = 10;
|
||||
@ -423,7 +423,7 @@ pub fn rvalue() -> i32 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn rvalue() -> i32 {
|
||||
let mut x = 10;
|
||||
@ -440,7 +440,7 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir,mir_built", cfg="cfail2")]
|
||||
#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
|
||||
s[j]
|
||||
|
@ -25,7 +25,7 @@ pub fn change_loop_body() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_body() {
|
||||
let mut _x = 0;
|
||||
@ -48,7 +48,7 @@ pub fn change_loop_condition() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_condition() {
|
||||
let mut _x = 0;
|
||||
@ -70,7 +70,7 @@ pub fn add_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_break() {
|
||||
let mut _x = 0;
|
||||
@ -141,7 +141,7 @@ pub fn change_break_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_break_label() {
|
||||
let mut _x = 0;
|
||||
@ -191,7 +191,7 @@ pub fn change_continue_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_label() {
|
||||
let mut _x = 0;
|
||||
@ -216,7 +216,7 @@ pub fn change_continue_to_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_to_break() {
|
||||
let mut _x = 0;
|
||||
|
@ -25,7 +25,7 @@ pub fn change_loop_body() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_body() {
|
||||
let mut _x = 0;
|
||||
@ -48,7 +48,7 @@ pub fn change_loop_condition() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_loop_condition() {
|
||||
let mut _x = 0;
|
||||
@ -70,7 +70,7 @@ pub fn add_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck_tables_of")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_break() {
|
||||
let mut _x = 0;
|
||||
@ -141,7 +141,7 @@ pub fn change_break_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_break_label() {
|
||||
let mut _x = 0;
|
||||
@ -191,7 +191,7 @@ pub fn change_continue_label() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_label() {
|
||||
let mut _x = 0;
|
||||
@ -216,7 +216,7 @@ pub fn change_continue_to_break() {
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, mir_built, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn change_continue_to_break() {
|
||||
let mut _x = 0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
- // + ty: &i32
|
||||
- // + val: Value(Scalar(alloc0))
|
||||
+ // + ty: &[&i32; 1]
|
||||
+ // + val: Unevaluated(DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), [], Some(promoted[0]))
|
||||
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
|
||||
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) }
|
||||
@ -30,7 +30,7 @@
|
||||
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
|
||||
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
|
||||
+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35
|
||||
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), [], Some(promoted[0])) }
|
||||
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
|
||||
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
|
||||
_0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
|
||||
|
@ -24,7 +24,7 @@
|
||||
- // + ty: &i32
|
||||
- // + val: Value(Scalar(alloc2))
|
||||
+ // + ty: &[&i32; 1]
|
||||
+ // + val: Unevaluated(DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), [], Some(promoted[0]))
|
||||
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
|
||||
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) }
|
||||
@ -32,7 +32,7 @@
|
||||
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||
+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), [], Some(promoted[0])) }
|
||||
+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||
_0 = const core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
|
||||
|
@ -28,10 +28,10 @@
|
||||
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
// ty::Const
|
||||
// + ty: &[i32; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
_2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
_1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
|
@ -28,10 +28,10 @@
|
||||
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
// ty::Const
|
||||
// + ty: &[i32; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
_2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
_1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
|
||||
|
@ -19,10 +19,10 @@
|
||||
_3 = const main::FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), [], None)
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), const_param_did: None }, [], None)
|
||||
// mir::Constant
|
||||
// + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), [], None) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main[0]::FOO[0]), const_param_did: None }, [], None) }
|
||||
_2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
|
||||
_1 = move _2 as usize (Misc); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
|
||||
StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39
|
||||
|
@ -12,11 +12,11 @@
|
||||
+ _1 = const false; // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
|
||||
// ty::Const
|
||||
// + ty: bool
|
||||
- // + val: Unevaluated(DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), [bool], None)
|
||||
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), const_param_did: None }, [bool], None)
|
||||
+ // + val: Value(Scalar(0x00))
|
||||
// mir::Constant
|
||||
// + span: $DIR/control-flow-simplification.rs:12:8: 12:21
|
||||
- // + literal: Const { ty: bool, val: Unevaluated(DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), [bool], None) }
|
||||
- // + literal: Const { ty: bool, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ control_flow_simplification[317d]::NeedsDrop[0]::NEEDS[0]), const_param_did: None }, [bool], None) }
|
||||
- switchInt(_1) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
|
||||
+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
|
||||
+ switchInt(const false) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6
|
||||
|
@ -14,10 +14,10 @@
|
||||
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref_deref.rs:5:6: 5:10
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
|
||||
- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
|
||||
+ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
|
||||
|
@ -18,13 +18,13 @@
|
||||
- // + ty: i32
|
||||
- // + val: Value(Scalar(0x00000004))
|
||||
+ // + ty: &i32
|
||||
+ // + val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0]))
|
||||
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
- // + span: $DIR/ref_deref.rs:5:8: 5:9
|
||||
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
|
||||
- _2 = &_3; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
|
||||
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
|
||||
+ // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) }
|
||||
+ // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
+ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
|
||||
_1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
|
||||
- StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
|
||||
|
@ -14,10 +14,10 @@
|
||||
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
// ty::Const
|
||||
// + ty: &(i32, i32)
|
||||
// + val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
// + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
|
||||
StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
|
||||
|
@ -18,7 +18,7 @@
|
||||
- // + ty: i32
|
||||
- // + val: Value(Scalar(0x00000004))
|
||||
+ // + ty: &(i32, i32)
|
||||
+ // + val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0]))
|
||||
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
- // + span: $DIR/ref_deref_project.rs:5:9: 5:10
|
||||
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) }
|
||||
@ -30,7 +30,7 @@
|
||||
- // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) }
|
||||
- _2 = &(_3.1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) }
|
||||
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
|
||||
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
|
||||
- StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
|
||||
|
@ -21,10 +21,10 @@
|
||||
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
// ty::Const
|
||||
// + ty: &[u32; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/slice_len.rs:5:6: 5:19
|
||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
|
@ -21,10 +21,10 @@
|
||||
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
// ty::Const
|
||||
// + ty: &[u32; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/slice_len.rs:5:6: 5:19
|
||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(DefId(0:3 ~ slice_len[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
|
||||
|
@ -38,10 +38,10 @@ fn bar() -> bool {
|
||||
_10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[1]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), const_param_did: None }, [], Some(promoted[1]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/inline-retag.rs:12:7: 12:9
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[1])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), const_param_did: None }, [], Some(promoted[1])) }
|
||||
Retag(_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
|
||||
_4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
|
||||
Retag(_4); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
|
||||
@ -52,10 +52,10 @@ fn bar() -> bool {
|
||||
_9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/inline-retag.rs:12:11: 12:14
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:4 ~ inline_retag[317d]::bar[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
Retag(_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
|
||||
_7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
|
||||
Retag(_7); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
|
||||
|
@ -96,10 +96,10 @@
|
||||
(_5.1: &i32) = const main::promoted[1]; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) }
|
||||
StorageDead(_6); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
StorageLive(_7); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_7 = (_5.0: &i32); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
@ -140,10 +140,10 @@
|
||||
_15 = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &[&str; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
StorageLive(_18); // scope 4 at $SRC_DIR/libstd/macros.rs:LL:COL
|
||||
StorageLive(_19); // scope 4 at $SRC_DIR/libstd/macros.rs:LL:COL
|
||||
StorageLive(_20); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
|
@ -153,10 +153,10 @@
|
||||
_51 = const main::promoted[1]; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) }
|
||||
_11 = _51; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
(_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
(_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
@ -220,10 +220,10 @@
|
||||
_50 = const main::promoted[0]; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &[&str; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_25 = _50; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_24 = _25; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_23 = move _24 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
|
@ -96,10 +96,10 @@
|
||||
(_5.1: &i32) = const main::promoted[1]; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) }
|
||||
StorageDead(_6); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
StorageLive(_7); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_7 = (_5.0: &i32); // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
@ -140,10 +140,10 @@
|
||||
_15 = const main::promoted[0] as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &[&str; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
StorageLive(_18); // scope 4 at $SRC_DIR/libstd/macros.rs:LL:COL
|
||||
StorageLive(_19); // scope 4 at $SRC_DIR/libstd/macros.rs:LL:COL
|
||||
StorageLive(_20); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
|
@ -153,10 +153,10 @@
|
||||
_51 = const main::promoted[1]; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[1])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[1])) }
|
||||
_11 = _51; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
(_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
(_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
@ -220,10 +220,10 @@
|
||||
_50 = const main::promoted[0]; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// ty::Const
|
||||
// + ty: &[&str; 3]
|
||||
// + val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(DefId(0:3 ~ issue_73223[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &[&str; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_25 = _50; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_24 = _25; // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
_23 = move _24 as &[&str] (Pointer(Unsize)); // scope 4 at $SRC_DIR/libcore/macros/mod.rs:LL:COL
|
||||
|
@ -76,10 +76,10 @@ fn full_tested_match() -> () {
|
||||
_11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
|
||||
// ty::Const
|
||||
// + ty: &std::option::Option<i32>
|
||||
// + val: Unevaluated(DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/match_false_edges.rs:16:14: 16:15
|
||||
// + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
_6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
|
||||
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
|
||||
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
|
||||
|
@ -184,10 +184,10 @@ fn main() -> () {
|
||||
_27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23
|
||||
// ty::Const
|
||||
// + ty: &i32
|
||||
// + val: Unevaluated(DefId(0:13 ~ retag[317d]::main[0]), [], Some(promoted[0]))
|
||||
// + val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main[0]), const_param_did: None }, [], Some(promoted[0]))
|
||||
// mir::Constant
|
||||
// + span: $DIR/retag.rs:47:21: 47:23
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(DefId(0:13 ~ retag[317d]::main[0]), [], Some(promoted[0])) }
|
||||
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main[0]), const_param_did: None }, [], Some(promoted[0])) }
|
||||
Retag(_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
|
||||
_23 = &(*_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
|
||||
Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23
|
||||
|
@ -0,0 +1,36 @@
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub struct Struct<const N: usize>(());
|
||||
|
||||
impl<const N: usize> Struct<N> {
|
||||
pub fn new() -> Self {
|
||||
Struct(())
|
||||
}
|
||||
|
||||
pub fn same_ty<const M: usize>(&self) -> (usize, usize) {
|
||||
(N, M)
|
||||
}
|
||||
|
||||
pub fn different_ty<const M: u8>(&self) -> (usize, u8) {
|
||||
(N, M)
|
||||
}
|
||||
|
||||
pub fn containing_ty<T, const M: u8>(&self) -> (usize, u8) {
|
||||
(std::mem::size_of::<T>() + N, M)
|
||||
}
|
||||
|
||||
pub fn we_have_to_go_deeper<const M: usize>(&self) -> Struct<M> {
|
||||
Struct(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Foo {
|
||||
fn foo<const M: usize>(&self) -> usize;
|
||||
}
|
||||
|
||||
impl Foo for Struct<7> {
|
||||
fn foo<const M: usize>(&self) -> usize {
|
||||
M
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo<const N: usize>(&self) -> usize {
|
||||
let f = self;
|
||||
f.bar::<{
|
||||
let f = Foo;
|
||||
f.bar::<7>()
|
||||
}>() + N
|
||||
}
|
||||
|
||||
const fn bar<const M: usize>(&self) -> usize {
|
||||
M
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = Foo;
|
||||
|
||||
assert_eq!(f.foo::<13>(), 20)
|
||||
}
|
49
src/test/ui/const-generics/type-dependent/issue-61936.rs
Normal file
49
src/test/ui/const-generics/type-dependent/issue-61936.rs
Normal file
@ -0,0 +1,49 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait SliceExt<T: Clone> {
|
||||
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
|
||||
}
|
||||
|
||||
impl <T: Clone> SliceExt<T> for [T] {
|
||||
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
|
||||
ArrayWindows{ idx: 0, slice: &self }
|
||||
}
|
||||
}
|
||||
|
||||
struct ArrayWindows<'a, T, const N: usize> {
|
||||
slice: &'a [T],
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> {
|
||||
type Item = [T; N];
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// Note: this is unsound for some `T` and not meant as an example
|
||||
// on how to implement `ArrayWindows`.
|
||||
let mut res = unsafe{ std::mem::zeroed() };
|
||||
let mut ptr = &mut res as *mut [T; N] as *mut T;
|
||||
|
||||
for i in 0..N {
|
||||
match self.slice[self.idx..].get(i) {
|
||||
None => return None,
|
||||
Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())},
|
||||
};
|
||||
ptr = ptr.wrapping_add(1);
|
||||
self.idx += 1;
|
||||
}
|
||||
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
const FOUR: usize = 4;
|
||||
|
||||
fn main() {
|
||||
let v: Vec<usize> = vec![0; 100];
|
||||
|
||||
for array in v.as_slice().array_windows::<FOUR>() {
|
||||
assert_eq!(array, [0, 0, 0, 0])
|
||||
}
|
||||
}
|
17
src/test/ui/const-generics/type-dependent/issue-63695.rs
Normal file
17
src/test/ui/const-generics/type-dependent/issue-63695.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait T {
|
||||
fn test<const A: i32>(&self) -> i32 { A }
|
||||
}
|
||||
|
||||
struct S();
|
||||
|
||||
impl T for S {}
|
||||
|
||||
fn main() {
|
||||
let foo = S();
|
||||
assert_eq!(foo.test::<8i32>(), 8);
|
||||
assert_eq!(foo.test::<16i32>(), 16);
|
||||
}
|
20
src/test/ui/const-generics/type-dependent/issue-69816.rs
Normal file
20
src/test/ui/const-generics/type-dependent/issue-69816.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait IterExt: Sized + Iterator {
|
||||
fn default_for_size<const N: usize>(self) -> [Self::Item; N]
|
||||
where
|
||||
[Self::Item; N]: Default,
|
||||
{
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Iterator> IterExt for T {}
|
||||
|
||||
fn main(){
|
||||
const N: usize = 10;
|
||||
let arr = (0u32..10).default_for_size::<N>();
|
||||
assert_eq!(arr, [0; 10]);
|
||||
}
|
47
src/test/ui/const-generics/type-dependent/issue-70507.rs
Normal file
47
src/test/ui/const-generics/type-dependent/issue-70507.rs
Normal file
@ -0,0 +1,47 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait ConstChunksExactTrait<T> {
|
||||
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}>;
|
||||
}
|
||||
|
||||
impl <T> ConstChunksExactTrait<T> for [T] {
|
||||
fn const_chunks_exact<const N: usize>(&self) -> ConstChunksExact<'_, T, {N}> {
|
||||
assert!(N != 0);
|
||||
let rem = self.len() % N;
|
||||
let len = self.len() - rem;
|
||||
let (fst, _) = self.split_at(len);
|
||||
ConstChunksExact { v: fst, }
|
||||
}
|
||||
}
|
||||
|
||||
struct ConstChunksExact<'a, T: 'a, const N: usize> {
|
||||
v: &'a [T],
|
||||
}
|
||||
|
||||
impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> {
|
||||
type Item = &'a [T; N];
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.v.len() < N {
|
||||
None
|
||||
} else {
|
||||
let (fst, snd) = self.v.split_at(N);
|
||||
|
||||
self.v = snd;
|
||||
let ptr = fst.as_ptr() as *const _;
|
||||
Some(unsafe { &*ptr})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter();
|
||||
|
||||
for a in slice.const_chunks_exact::<3>() {
|
||||
assert_eq!(a, iter.next().unwrap());
|
||||
}
|
||||
}
|
24
src/test/ui/const-generics/type-dependent/issue-71382.rs
Normal file
24
src/test/ui/const-generics/type-dependent/issue-71382.rs
Normal file
@ -0,0 +1,24 @@
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
struct Test;
|
||||
|
||||
fn pass() -> u8 {
|
||||
42
|
||||
}
|
||||
|
||||
impl Test {
|
||||
pub fn call_me(&self) -> u8 {
|
||||
self.test::<pass>()
|
||||
}
|
||||
|
||||
fn test<const FN: fn() -> u8>(&self) -> u8 {
|
||||
//~^ ERROR using function pointers as const generic parameters is forbidden
|
||||
FN()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Test;
|
||||
assert_eq!(x.call_me(), 42);
|
||||
}
|
17
src/test/ui/const-generics/type-dependent/issue-71382.stderr
Normal file
17
src/test/ui/const-generics/type-dependent/issue-71382.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-71382.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error: using function pointers as const generic parameters is forbidden
|
||||
--> $DIR/issue-71382.rs:15:23
|
||||
|
|
||||
LL | fn test<const FN: fn() -> u8>(&self) -> u8 {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
24
src/test/ui/const-generics/type-dependent/non-local.rs
Normal file
24
src/test/ui/const-generics/type-dependent/non-local.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// aux-build:type_dependent_lib.rs
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
extern crate type_dependent_lib;
|
||||
|
||||
use type_dependent_lib::*;
|
||||
|
||||
fn main() {
|
||||
let s = Struct::<42>::new();
|
||||
assert_eq!(s.same_ty::<7>(), (42, 7));
|
||||
assert_eq!(s.different_ty::<19>(), (42, 19));
|
||||
assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96));
|
||||
assert_eq!(
|
||||
Struct::<18>::new()
|
||||
.we_have_to_go_deeper::<19>()
|
||||
.containing_ty::<Option<u32>, 3>(),
|
||||
(27, 3),
|
||||
);
|
||||
|
||||
let s = Struct::<7>::new();
|
||||
assert_eq!(s.foo::<18>(), 18);
|
||||
}
|
12
src/test/ui/const-generics/type-dependent/qpath.rs
Normal file
12
src/test/ui/const-generics/type-dependent/qpath.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct A;
|
||||
impl A {
|
||||
fn foo<const N: usize>() -> usize { N + 1 }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(A::foo::<7>(), 8);
|
||||
}
|
12
src/test/ui/const-generics/type-dependent/simple.rs
Normal file
12
src/test/ui/const-generics/type-dependent/simple.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct R;
|
||||
|
||||
impl R {
|
||||
fn method<const N: u8>(&self) -> u8 { N }
|
||||
}
|
||||
fn main() {
|
||||
assert_eq!(R.method::<1u8>(), 1);
|
||||
}
|
12
src/test/ui/const-generics/type-dependent/type-mismatch.rs
Normal file
12
src/test/ui/const-generics/type-dependent/type-mismatch.rs
Normal file
@ -0,0 +1,12 @@
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete
|
||||
|
||||
struct R;
|
||||
|
||||
impl R {
|
||||
fn method<const N: u8>(&self) -> u8 { N }
|
||||
}
|
||||
fn main() {
|
||||
assert_eq!(R.method::<1u16>(), 1);
|
||||
//~^ ERROR mismatched types
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/type-mismatch.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch.rs:10:27
|
||||
|
|
||||
LL | assert_eq!(R.method::<1u16>(), 1);
|
||||
| ^^^^ expected `u8`, found `u16`
|
||||
|
|
||||
help: change the type of the numeric literal from `u16` to `u8`
|
||||
|
|
||||
LL | assert_eq!(R.method::<1u8>(), 1);
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
7
src/test/ui/const-generics/unknown_adt.rs
Normal file
7
src/test/ui/const-generics/unknown_adt.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#![feature(const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
let _: UnknownStruct<7>;
|
||||
//~^ ERROR cannot find type `UnknownStruct`
|
||||
}
|
9
src/test/ui/const-generics/unknown_adt.stderr
Normal file
9
src/test/ui/const-generics/unknown_adt.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0412]: cannot find type `UnknownStruct` in this scope
|
||||
--> $DIR/unknown_adt.rs:5:12
|
||||
|
|
||||
LL | let _: UnknownStruct<7>;
|
||||
| ^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user