Keep an unoptimized duplicate of const fn
around
This allows CTFE to reliably detect UB, as otherwise optimizations may hide UB.
This commit is contained in:
parent
8e4fe6647f
commit
cccd40f9b5
25 changed files with 312 additions and 112 deletions
|
@ -1162,6 +1162,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
|
|
||||||
fn is_item_mir_available(&self, id: DefIndex) -> bool {
|
fn is_item_mir_available(&self, id: DefIndex) -> bool {
|
||||||
self.root.tables.mir.get(self, id).is_some()
|
self.root.tables.mir.get(self, id).is_some()
|
||||||
|
|| self.root.tables.mir_for_ctfe.get(self, id).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
|
fn module_expansion(&self, id: DefIndex, sess: &Session) -> ExpnId {
|
||||||
|
@ -1183,6 +1184,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||||
.decode((self, tcx))
|
.decode((self, tcx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_mir_for_ctfe(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
|
||||||
|
self.root
|
||||||
|
.tables
|
||||||
|
.mir_for_ctfe
|
||||||
|
.get(self, id)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
bug!("get_mir_for_ctfe: missing MIR for `{:?}`", self.local_def_id(id))
|
||||||
|
})
|
||||||
|
.decode((self, tcx))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_mir_abstract_const(
|
fn get_mir_abstract_const(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
|
|
@ -115,6 +115,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
|
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
|
||||||
|
mir_for_ctfe => { tcx.arena.alloc(cdata.get_mir_for_ctfe(tcx, def_id.index)) }
|
||||||
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
||||||
mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
|
mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
|
||||||
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
|
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
|
||||||
|
|
|
@ -787,6 +787,7 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
self.encode_generics(def_id);
|
self.encode_generics(def_id);
|
||||||
self.encode_explicit_predicates(def_id);
|
self.encode_explicit_predicates(def_id);
|
||||||
self.encode_inferred_outlives(def_id);
|
self.encode_inferred_outlives(def_id);
|
||||||
|
self.encode_mir_for_ctfe(def_id.expect_local());
|
||||||
self.encode_optimized_mir(def_id.expect_local());
|
self.encode_optimized_mir(def_id.expect_local());
|
||||||
self.encode_promoted_mir(def_id.expect_local());
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
}
|
}
|
||||||
|
@ -895,6 +896,7 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
self.encode_explicit_predicates(def_id);
|
self.encode_explicit_predicates(def_id);
|
||||||
self.encode_inferred_outlives(def_id);
|
self.encode_inferred_outlives(def_id);
|
||||||
self.encode_optimized_mir(def_id.expect_local());
|
self.encode_optimized_mir(def_id.expect_local());
|
||||||
|
self.encode_mir_for_ctfe(def_id.expect_local());
|
||||||
self.encode_promoted_mir(def_id.expect_local());
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,7 +1017,13 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
// This should be kept in sync with `PrefetchVisitor.visit_trait_item`.
|
// This should be kept in sync with `PrefetchVisitor.visit_trait_item`.
|
||||||
match trait_item.kind {
|
match trait_item.kind {
|
||||||
ty::AssocKind::Type => {}
|
ty::AssocKind::Type => {}
|
||||||
ty::AssocKind::Const | ty::AssocKind::Fn => {
|
ty::AssocKind::Const => {
|
||||||
|
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
|
||||||
|
self.encode_mir_for_ctfe(def_id.expect_local());
|
||||||
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::AssocKind::Fn => {
|
||||||
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
|
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
|
||||||
self.encode_optimized_mir(def_id.expect_local());
|
self.encode_optimized_mir(def_id.expect_local());
|
||||||
self.encode_promoted_mir(def_id.expect_local());
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
|
@ -1094,8 +1102,8 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
// The following part should be kept in sync with `PrefetchVisitor.visit_impl_item`.
|
// The following part should be kept in sync with `PrefetchVisitor.visit_impl_item`.
|
||||||
|
|
||||||
let mir = match ast_item.kind {
|
let (mir, mir_const) = match ast_item.kind {
|
||||||
hir::ImplItemKind::Const(..) => true,
|
hir::ImplItemKind::Const(..) => (false, true),
|
||||||
hir::ImplItemKind::Fn(ref sig, _) => {
|
hir::ImplItemKind::Fn(ref sig, _) => {
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
let needs_inline = (generics.requires_monomorphization(self.tcx)
|
let needs_inline = (generics.requires_monomorphization(self.tcx)
|
||||||
|
@ -1103,14 +1111,19 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
&& !self.metadata_output_only();
|
&& !self.metadata_output_only();
|
||||||
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
||||||
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
||||||
needs_inline || is_const_fn || always_encode_mir
|
(needs_inline || always_encode_mir, is_const_fn)
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::TyAlias(..) => false,
|
hir::ImplItemKind::TyAlias(..) => (false, false),
|
||||||
};
|
};
|
||||||
if mir {
|
if mir {
|
||||||
self.encode_optimized_mir(def_id.expect_local());
|
self.encode_optimized_mir(def_id.expect_local());
|
||||||
|
}
|
||||||
|
if mir || mir_const {
|
||||||
self.encode_promoted_mir(def_id.expect_local());
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
}
|
}
|
||||||
|
if mir_const {
|
||||||
|
self.encode_mir_for_ctfe(def_id.expect_local());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Ident]> {
|
fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Ident]> {
|
||||||
|
@ -1121,9 +1134,9 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
self.lazy(param_names.iter())
|
self.lazy(param_names.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_optimized_mir(&mut self, def_id: LocalDefId) {
|
fn encode_mir_for_ctfe(&mut self, def_id: LocalDefId) {
|
||||||
debug!("EntryBuilder::encode_mir({:?})", def_id);
|
debug!("EntryBuilder::encode_mir_for_ctfe({:?})", def_id);
|
||||||
record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
|
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
|
||||||
|
|
||||||
let unused = self.tcx.unused_generic_params(def_id);
|
let unused = self.tcx.unused_generic_params(def_id);
|
||||||
if !unused.is_empty() {
|
if !unused.is_empty() {
|
||||||
|
@ -1136,6 +1149,16 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_optimized_mir(&mut self, def_id: LocalDefId) {
|
||||||
|
debug!("EntryBuilder::encode_optimized_mir({:?})", def_id);
|
||||||
|
record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
|
||||||
|
|
||||||
|
let unused = self.tcx.unused_generic_params(def_id);
|
||||||
|
if !unused.is_empty() {
|
||||||
|
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_promoted_mir(&mut self, def_id: LocalDefId) {
|
fn encode_promoted_mir(&mut self, def_id: LocalDefId) {
|
||||||
debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
|
debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
|
||||||
record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
|
record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
|
||||||
|
@ -1407,8 +1430,8 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
// The following part should be kept in sync with `PrefetchVisitor.visit_item`.
|
// The following part should be kept in sync with `PrefetchVisitor.visit_item`.
|
||||||
|
|
||||||
let mir = match item.kind {
|
let (mir, const_mir) = match item.kind {
|
||||||
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
|
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => (false, true),
|
||||||
hir::ItemKind::Fn(ref sig, ..) => {
|
hir::ItemKind::Fn(ref sig, ..) => {
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
let needs_inline = (generics.requires_monomorphization(tcx)
|
let needs_inline = (generics.requires_monomorphization(tcx)
|
||||||
|
@ -1417,14 +1440,21 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
||||||
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
|
||||||
needs_inline || is_const_fn || always_encode_mir
|
let mir = needs_inline || always_encode_mir;
|
||||||
|
// We don't need the optimized MIR for const fns.
|
||||||
|
(mir, is_const_fn)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => (false, false),
|
||||||
};
|
};
|
||||||
if mir {
|
if mir {
|
||||||
self.encode_optimized_mir(def_id.expect_local());
|
self.encode_optimized_mir(def_id.expect_local());
|
||||||
|
}
|
||||||
|
if mir || const_mir {
|
||||||
self.encode_promoted_mir(def_id.expect_local());
|
self.encode_promoted_mir(def_id.expect_local());
|
||||||
}
|
}
|
||||||
|
if const_mir {
|
||||||
|
self.encode_mir_for_ctfe(def_id.expect_local());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize the text of exported macros
|
/// Serialize the text of exported macros
|
||||||
|
@ -1489,7 +1519,7 @@ impl EncodeContext<'a, 'tcx> {
|
||||||
self.encode_generics(def_id.to_def_id());
|
self.encode_generics(def_id.to_def_id());
|
||||||
self.encode_explicit_predicates(def_id.to_def_id());
|
self.encode_explicit_predicates(def_id.to_def_id());
|
||||||
self.encode_inferred_outlives(def_id.to_def_id());
|
self.encode_inferred_outlives(def_id.to_def_id());
|
||||||
self.encode_optimized_mir(def_id);
|
self.encode_mir_for_ctfe(def_id);
|
||||||
self.encode_promoted_mir(def_id);
|
self.encode_promoted_mir(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1954,6 +1984,12 @@ struct PrefetchVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PrefetchVisitor<'tcx> {
|
impl<'tcx> PrefetchVisitor<'tcx> {
|
||||||
|
fn prefetch_ctfe_mir(&self, def_id: LocalDefId) {
|
||||||
|
if self.mir_keys.contains(&def_id) {
|
||||||
|
self.tcx.ensure().mir_for_ctfe(def_id);
|
||||||
|
self.tcx.ensure().promoted_mir(def_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
fn prefetch_mir(&self, def_id: LocalDefId) {
|
fn prefetch_mir(&self, def_id: LocalDefId) {
|
||||||
if self.mir_keys.contains(&def_id) {
|
if self.mir_keys.contains(&def_id) {
|
||||||
self.tcx.ensure().optimized_mir(def_id);
|
self.tcx.ensure().optimized_mir(def_id);
|
||||||
|
@ -1968,16 +2004,19 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
|
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
|
||||||
self.prefetch_mir(tcx.hir().local_def_id(item.hir_id))
|
self.prefetch_ctfe_mir(tcx.hir().local_def_id(item.hir_id))
|
||||||
}
|
}
|
||||||
hir::ItemKind::Fn(ref sig, ..) => {
|
hir::ItemKind::Fn(ref sig, ..) => {
|
||||||
let def_id = tcx.hir().local_def_id(item.hir_id);
|
let def_id = tcx.hir().local_def_id(item.hir_id);
|
||||||
let generics = tcx.generics_of(def_id.to_def_id());
|
let generics = tcx.generics_of(def_id.to_def_id());
|
||||||
let needs_inline = generics.requires_monomorphization(tcx)
|
let needs_inline = generics.requires_monomorphization(tcx)
|
||||||
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
|
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
|
||||||
if needs_inline || sig.header.constness == hir::Constness::Const {
|
if needs_inline {
|
||||||
self.prefetch_mir(def_id)
|
self.prefetch_mir(def_id)
|
||||||
}
|
}
|
||||||
|
if sig.header.constness == hir::Constness::Const {
|
||||||
|
self.prefetch_ctfe_mir(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -1985,7 +2024,16 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
|
||||||
|
|
||||||
fn visit_trait_item(&self, trait_item: &'v hir::TraitItem<'v>) {
|
fn visit_trait_item(&self, trait_item: &'v hir::TraitItem<'v>) {
|
||||||
// This should be kept in sync with `encode_info_for_trait_item`.
|
// This should be kept in sync with `encode_info_for_trait_item`.
|
||||||
self.prefetch_mir(self.tcx.hir().local_def_id(trait_item.hir_id));
|
let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
|
||||||
|
match trait_item.kind {
|
||||||
|
hir::TraitItemKind::Type(..) => {}
|
||||||
|
hir::TraitItemKind::Const(..) => {
|
||||||
|
self.prefetch_ctfe_mir(def_id);
|
||||||
|
}
|
||||||
|
hir::TraitItemKind::Fn(..) => {
|
||||||
|
self.prefetch_mir(def_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_impl_item(&self, impl_item: &'v hir::ImplItem<'v>) {
|
fn visit_impl_item(&self, impl_item: &'v hir::ImplItem<'v>) {
|
||||||
|
@ -1993,7 +2041,7 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
match impl_item.kind {
|
match impl_item.kind {
|
||||||
hir::ImplItemKind::Const(..) => {
|
hir::ImplItemKind::Const(..) => {
|
||||||
self.prefetch_mir(tcx.hir().local_def_id(impl_item.hir_id))
|
self.prefetch_ctfe_mir(tcx.hir().local_def_id(impl_item.hir_id))
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::Fn(ref sig, _) => {
|
hir::ImplItemKind::Fn(ref sig, _) => {
|
||||||
let def_id = tcx.hir().local_def_id(impl_item.hir_id);
|
let def_id = tcx.hir().local_def_id(impl_item.hir_id);
|
||||||
|
@ -2001,9 +2049,12 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
|
||||||
let needs_inline = generics.requires_monomorphization(tcx)
|
let needs_inline = generics.requires_monomorphization(tcx)
|
||||||
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
|
|| tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
|
||||||
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
let is_const_fn = sig.header.constness == hir::Constness::Const;
|
||||||
if needs_inline || is_const_fn {
|
if needs_inline {
|
||||||
self.prefetch_mir(def_id)
|
self.prefetch_mir(def_id)
|
||||||
}
|
}
|
||||||
|
if is_const_fn {
|
||||||
|
self.prefetch_ctfe_mir(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::TyAlias(..) => (),
|
hir::ImplItemKind::TyAlias(..) => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,7 @@ define_tables! {
|
||||||
// As an optimization, a missing entry indicates an empty `&[]`.
|
// As an optimization, a missing entry indicates an empty `&[]`.
|
||||||
explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
|
explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
|
||||||
mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
|
mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
|
||||||
|
mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
|
||||||
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
|
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
|
||||||
mir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [mir::abstract_const::Node<'tcx>])>,
|
mir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [mir::abstract_const::Node<'tcx>])>,
|
||||||
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
|
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
|
||||||
|
|
|
@ -450,6 +450,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> {
|
||||||
|
if let Some((did, param_did)) = def.as_const_arg() {
|
||||||
|
self.mir_for_ctfe_of_const_arg((did, param_did))
|
||||||
|
} else {
|
||||||
|
self.mir_for_ctfe(def.did)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mir_abstract_const_opt_const_arg(
|
pub fn mir_abstract_const_opt_const_arg(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -312,6 +312,20 @@ rustc_queries! {
|
||||||
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query mir_for_ctfe(
|
||||||
|
key: DefId
|
||||||
|
) -> &'tcx mir::Body<'tcx> {
|
||||||
|
desc { |tcx| "caching mir for `{}` for CTFE", tcx.def_path_str(key) }
|
||||||
|
cache_on_disk_if { key.is_local() }
|
||||||
|
}
|
||||||
|
|
||||||
|
query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
||||||
|
desc {
|
||||||
|
|tcx| "MIR for CTFE of the const argument `{}`",
|
||||||
|
tcx.def_path_str(key.0.to_def_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) ->
|
query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) ->
|
||||||
(
|
(
|
||||||
&'tcx Steal<mir::Body<'tcx>>,
|
&'tcx Steal<mir::Body<'tcx>>,
|
||||||
|
@ -331,6 +345,9 @@ rustc_queries! {
|
||||||
desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "optimizing MIR for `{}`", tcx.def_path_str(key) }
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: now that we have `mir_for_ctfe_of_const_arg` can we get
|
||||||
|
// rid of this query?
|
||||||
query optimized_mir_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
query optimized_mir_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> {
|
||||||
desc {
|
desc {
|
||||||
|tcx| "optimizing MIR for the const argument `{}`",
|
|tcx| "optimizing MIR for the const argument `{}`",
|
||||||
|
|
|
@ -480,7 +480,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
match instance {
|
match instance {
|
||||||
ty::InstanceDef::Item(def) => {
|
ty::InstanceDef::Item(def) => {
|
||||||
if self.tcx.is_mir_available(def.did) {
|
if self.tcx.is_mir_available(def.did) {
|
||||||
Ok(self.tcx.optimized_mir_opt_const_arg(def))
|
Ok(self.tcx.mir_for_ctfe_opt_const_arg(def))
|
||||||
} else {
|
} else {
|
||||||
throw_unsup!(NoMirFor(def.did))
|
throw_unsup!(NoMirFor(def.did))
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,10 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
|
||||||
debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters);
|
debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters);
|
||||||
|
|
||||||
// Visit MIR and accumululate used generic parameters.
|
// Visit MIR and accumululate used generic parameters.
|
||||||
let body = tcx.optimized_mir(def_id);
|
let body = match tcx.hir().body_const_context(def_id.expect_local()) {
|
||||||
|
None => tcx.optimized_mir(def_id),
|
||||||
|
Some(_) => tcx.mir_for_ctfe(def_id),
|
||||||
|
};
|
||||||
let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters };
|
let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters };
|
||||||
vis.visit_body(body);
|
vis.visit_body(body);
|
||||||
debug!("unused_generic_params: (after visitor) unused_parameters={:?}", unused_parameters);
|
debug!("unused_generic_params: (after visitor) unused_parameters={:?}", unused_parameters);
|
||||||
|
|
|
@ -71,6 +71,8 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||||
},
|
},
|
||||||
mir_promoted,
|
mir_promoted,
|
||||||
mir_drops_elaborated_and_const_checked,
|
mir_drops_elaborated_and_const_checked,
|
||||||
|
mir_for_ctfe,
|
||||||
|
mir_for_ctfe_of_const_arg,
|
||||||
optimized_mir,
|
optimized_mir,
|
||||||
optimized_mir_of_const_arg,
|
optimized_mir_of_const_arg,
|
||||||
is_mir_available,
|
is_mir_available,
|
||||||
|
@ -319,6 +321,63 @@ fn mir_promoted(
|
||||||
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
|
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mir_for_ctfe<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Body<'tcx> {
|
||||||
|
let did = def_id.expect_local();
|
||||||
|
if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) {
|
||||||
|
tcx.mir_for_ctfe_of_const_arg(def)
|
||||||
|
} else {
|
||||||
|
tcx.arena.alloc(inner_mir_for_ctfe(tcx, ty::WithOptConstParam::unknown(did)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mir_for_ctfe_of_const_arg<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
(did, param_did): (LocalDefId, DefId),
|
||||||
|
) -> &'tcx Body<'tcx> {
|
||||||
|
tcx.arena.alloc(inner_mir_for_ctfe(
|
||||||
|
tcx,
|
||||||
|
ty::WithOptConstParam { did, const_param_did: Some(param_did) },
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
|
||||||
|
// FIXME: don't duplicate this between the optimized_mir/mir_for_ctfe queries
|
||||||
|
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.did.to_def_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_ne!(
|
||||||
|
tcx.hir().body_const_context(def.did),
|
||||||
|
None,
|
||||||
|
"mir_for_ctfe should not be used for runtime functions"
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let optimizations: &[&dyn MirPass<'_>] = &[
|
||||||
|
&const_prop::ConstProp,
|
||||||
|
];
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
run_passes(
|
||||||
|
tcx,
|
||||||
|
&mut body,
|
||||||
|
MirPhase::Optimization,
|
||||||
|
&[
|
||||||
|
optimizations,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE");
|
||||||
|
|
||||||
|
body
|
||||||
|
}
|
||||||
|
|
||||||
fn mir_drops_elaborated_and_const_checked<'tcx>(
|
fn mir_drops_elaborated_and_const_checked<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def: ty::WithOptConstParam<LocalDefId>,
|
def: ty::WithOptConstParam<LocalDefId>,
|
||||||
|
@ -484,6 +543,17 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>)
|
||||||
return shim::build_adt_ctor(tcx, def.did.to_def_id());
|
return shim::build_adt_ctor(tcx, def.did.to_def_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match tcx.hir().body_const_context(def.did) {
|
||||||
|
Some(hir::ConstContext::ConstFn) => {
|
||||||
|
if let Some((did, param_did)) = def.to_global().as_const_arg() {
|
||||||
|
tcx.ensure().mir_for_ctfe_of_const_arg((did, param_did))
|
||||||
|
} else {
|
||||||
|
tcx.ensure().mir_for_ctfe(def.did)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other),
|
||||||
|
}
|
||||||
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).steal();
|
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).steal();
|
||||||
run_optimization_passes(tcx, &mut body);
|
run_optimization_passes(tcx, &mut body);
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,11 @@ pub fn write_mir_pretty<'tcx>(
|
||||||
|
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for def_id in dump_mir_def_ids(tcx, single) {
|
for def_id in dump_mir_def_ids(tcx, single) {
|
||||||
let body = &tcx.optimized_mir(def_id);
|
let body = match tcx.hir().body_const_context(def_id.expect_local()) {
|
||||||
|
// FIXME: print both MIRs for `const fn`?
|
||||||
|
None | Some(rustc_hir::ConstContext::ConstFn) => tcx.optimized_mir(def_id),
|
||||||
|
Some(_) => tcx.mir_for_ctfe(def_id),
|
||||||
|
};
|
||||||
|
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
|
|
|
@ -152,7 +152,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
if concrete.is_ok() && substs.has_param_types_or_consts() {
|
if concrete.is_ok() && substs.has_param_types_or_consts() {
|
||||||
match infcx.tcx.def_kind(def.did) {
|
match infcx.tcx.def_kind(def.did) {
|
||||||
DefKind::AnonConst => {
|
DefKind::AnonConst => {
|
||||||
let mir_body = infcx.tcx.optimized_mir_opt_const_arg(def);
|
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def);
|
||||||
|
|
||||||
if mir_body.is_polymorphic {
|
if mir_body.is_polymorphic {
|
||||||
future_compat_lint();
|
future_compat_lint();
|
||||||
|
|
|
@ -24,41 +24,41 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc0 (static: FOO, size: 8, align: 4) {
|
alloc0 (static: FOO, size: 8, align: 4) {
|
||||||
╾─alloc23─╼ 03 00 00 00 │ ╾──╼....
|
╾─alloc27─╼ 03 00 00 00 │ ╾──╼....
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc23 (size: 48, align: 4) {
|
alloc27 (size: 48, align: 4) {
|
||||||
0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc8──╼ 00 00 00 00 │ ....░░░░╾──╼....
|
0x00 │ 00 00 00 00 __ __ __ __ ╾─alloc12─╼ 00 00 00 00 │ ....░░░░╾──╼....
|
||||||
0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc13─╼ 02 00 00 00 │ ....░░░░╾──╼....
|
0x10 │ 00 00 00 00 __ __ __ __ ╾─alloc17─╼ 02 00 00 00 │ ....░░░░╾──╼....
|
||||||
0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc21─╼ 03 00 00 00 │ ....*...╾──╼....
|
0x20 │ 01 00 00 00 2a 00 00 00 ╾─alloc25─╼ 03 00 00 00 │ ....*...╾──╼....
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc8 (size: 0, align: 4) {}
|
alloc12 (size: 0, align: 4) {}
|
||||||
|
|
||||||
alloc13 (size: 8, align: 4) {
|
alloc17 (size: 8, align: 4) {
|
||||||
╾─alloc11─╼ ╾─alloc12─╼ │ ╾──╼╾──╼
|
╾─alloc15─╼ ╾─alloc16─╼ │ ╾──╼╾──╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc11 (size: 1, align: 1) {
|
alloc15 (size: 1, align: 1) {
|
||||||
05 │ .
|
05 │ .
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc12 (size: 1, align: 1) {
|
alloc16 (size: 1, align: 1) {
|
||||||
06 │ .
|
06 │ .
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc21 (size: 12, align: 4) {
|
alloc25 (size: 12, align: 4) {
|
||||||
╾─a17+0x3─╼ ╾─alloc18─╼ ╾─a20+0x2─╼ │ ╾──╼╾──╼╾──╼
|
╾─a21+0x3─╼ ╾─alloc22─╼ ╾─a24+0x2─╼ │ ╾──╼╾──╼╾──╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc17 (size: 4, align: 1) {
|
alloc21 (size: 4, align: 1) {
|
||||||
2a 45 15 6f │ *E.o
|
2a 45 15 6f │ *E.o
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc18 (size: 1, align: 1) {
|
alloc22 (size: 1, align: 1) {
|
||||||
2a │ *
|
2a │ *
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc20 (size: 4, align: 1) {
|
alloc24 (size: 4, align: 1) {
|
||||||
2a 45 15 6f │ *E.o
|
2a 45 15 6f │ *E.o
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,44 +24,44 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc0 (static: FOO, size: 16, align: 8) {
|
alloc0 (static: FOO, size: 16, align: 8) {
|
||||||
╾───────alloc23───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
|
╾───────alloc27───────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc23 (size: 72, align: 8) {
|
alloc27 (size: 72, align: 8) {
|
||||||
0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc8────────╼ │ ....░░░░╾──────╼
|
0x00 │ 00 00 00 00 __ __ __ __ ╾───────alloc12───────╼ │ ....░░░░╾──────╼
|
||||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
|
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
|
||||||
0x20 │ ╾───────alloc13───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
|
0x20 │ ╾───────alloc17───────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
|
||||||
0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc21───────╼ │ ....*...╾──────╼
|
0x30 │ 01 00 00 00 2a 00 00 00 ╾───────alloc25───────╼ │ ....*...╾──────╼
|
||||||
0x40 │ 03 00 00 00 00 00 00 00 │ ........
|
0x40 │ 03 00 00 00 00 00 00 00 │ ........
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc8 (size: 0, align: 8) {}
|
alloc12 (size: 0, align: 8) {}
|
||||||
|
|
||||||
alloc13 (size: 16, align: 8) {
|
alloc17 (size: 16, align: 8) {
|
||||||
╾───────alloc11───────╼ ╾───────alloc12───────╼ │ ╾──────╼╾──────╼
|
╾───────alloc15───────╼ ╾───────alloc16───────╼ │ ╾──────╼╾──────╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc11 (size: 1, align: 1) {
|
alloc15 (size: 1, align: 1) {
|
||||||
05 │ .
|
05 │ .
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc12 (size: 1, align: 1) {
|
alloc16 (size: 1, align: 1) {
|
||||||
06 │ .
|
06 │ .
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc21 (size: 24, align: 8) {
|
alloc25 (size: 24, align: 8) {
|
||||||
0x00 │ ╾─────alloc17+0x3─────╼ ╾───────alloc18───────╼ │ ╾──────╼╾──────╼
|
0x00 │ ╾─────alloc21+0x3─────╼ ╾───────alloc22───────╼ │ ╾──────╼╾──────╼
|
||||||
0x10 │ ╾─────alloc20+0x2─────╼ │ ╾──────╼
|
0x10 │ ╾─────alloc24+0x2─────╼ │ ╾──────╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc17 (size: 4, align: 1) {
|
alloc21 (size: 4, align: 1) {
|
||||||
2a 45 15 6f │ *E.o
|
2a 45 15 6f │ *E.o
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc18 (size: 1, align: 1) {
|
alloc22 (size: 1, align: 1) {
|
||||||
2a │ *
|
2a │ *
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc20 (size: 4, align: 1) {
|
alloc24 (size: 4, align: 1) {
|
||||||
2a 45 15 6f │ *E.o
|
2a 45 15 6f │ *E.o
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,30 +24,30 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc0 (static: FOO, size: 4, align: 4) {
|
alloc0 (static: FOO, size: 4, align: 4) {
|
||||||
╾─alloc9──╼ │ ╾──╼
|
╾─alloc10─╼ │ ╾──╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc9 (size: 168, align: 1) {
|
alloc10 (size: 168, align: 1) {
|
||||||
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
||||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc4──╼ │ ............╾──╼
|
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc5──╼ │ ............╾──╼
|
||||||
0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc6──╼ 00 00 │ ..........╾──╼..
|
0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾─alloc7──╼ 00 00 │ ..........╾──╼..
|
||||||
0x90 │ ╾─a7+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............
|
0x90 │ ╾─a8+0x63─╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............
|
||||||
0xa0 │ 00 00 00 00 00 00 00 00 │ ........
|
0xa0 │ 00 00 00 00 00 00 00 00 │ ........
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc4 (size: 4, align: 4) {
|
alloc5 (size: 4, align: 4) {
|
||||||
2a 00 00 00 │ *...
|
2a 00 00 00 │ *...
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc6 (fn: main)
|
alloc7 (fn: main)
|
||||||
|
|
||||||
alloc7 (size: 100, align: 1) {
|
alloc8 (size: 100, align: 1) {
|
||||||
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
|
|
|
@ -24,12 +24,12 @@ fn main() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc0 (static: FOO, size: 8, align: 8) {
|
alloc0 (static: FOO, size: 8, align: 8) {
|
||||||
╾───────alloc9────────╼ │ ╾──────╼
|
╾───────alloc10───────╼ │ ╾──────╼
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc9 (size: 180, align: 1) {
|
alloc10 (size: 180, align: 1) {
|
||||||
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................
|
||||||
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc4── │ ............╾───
|
0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾──alloc5── │ ............╾───
|
||||||
0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............
|
0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............
|
||||||
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
|
@ -37,18 +37,18 @@ alloc9 (size: 180, align: 1) {
|
||||||
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─
|
0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─
|
||||||
0x90 │ ─────alloc6─────╼ 00 00 ╾─────alloc7+0x63─────╼ │ ─────╼..╾──────╼
|
0x90 │ ─────alloc7─────╼ 00 00 ╾─────alloc8+0x63─────╼ │ ─────╼..╾──────╼
|
||||||
0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0xb0 │ 00 00 00 00 │ ....
|
0xb0 │ 00 00 00 00 │ ....
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc4 (size: 4, align: 4) {
|
alloc5 (size: 4, align: 4) {
|
||||||
2a 00 00 00 │ *...
|
2a 00 00 00 │ *...
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc6 (fn: main)
|
alloc7 (fn: main)
|
||||||
|
|
||||||
alloc7 (size: 100, align: 1) {
|
alloc8 (size: 100, align: 1) {
|
||||||
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
|
||||||
|
|
|
@ -30,7 +30,7 @@ note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-a
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = IMPL_REF_BAR;
|
LL | const BAR: u32 = IMPL_REF_BAR;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: ...which requires optimizing MIR for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
|
note: ...which requires caching mir for `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR` for CTFE...
|
||||||
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = IMPL_REF_BAR;
|
LL | const BAR: u32 = IMPL_REF_BAR;
|
||||||
|
|
|
@ -30,7 +30,7 @@ note: ...which requires const-evaluating + checking `FooDefault::BAR`...
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = DEFAULT_REF_BAR;
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: ...which requires optimizing MIR for `FooDefault::BAR`...
|
note: ...which requires caching mir for `FooDefault::BAR` for CTFE...
|
||||||
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = DEFAULT_REF_BAR;
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
|
||||||
|
|
|
@ -30,7 +30,7 @@ note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-a
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = TRAIT_REF_BAR;
|
LL | const BAR: u32 = TRAIT_REF_BAR;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: ...which requires optimizing MIR for `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
|
note: ...which requires caching mir for `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR` for CTFE...
|
||||||
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
||||||
|
|
|
|
||||||
LL | const BAR: u32 = TRAIT_REF_BAR;
|
LL | const BAR: u32 = TRAIT_REF_BAR;
|
||||||
|
|
|
@ -7,13 +7,13 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/ub-nonnull.rs:18:29
|
--> $DIR/ub-nonnull.rs:18:30
|
||||||
|
|
|
|
||||||
LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
|
LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
|
||||||
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
|
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
|
||||||
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
|
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
|
||||||
LL | | let out_of_bounds_ptr = &ptr[255];
|
LL | | let out_of_bounds_ptr = &ptr[255];
|
||||||
| | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc10 which has size 1
|
| | ^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc10 which has size 1
|
||||||
LL | | mem::transmute(out_of_bounds_ptr)
|
LL | | mem::transmute(out_of_bounds_ptr)
|
||||||
LL | | } };
|
LL | | } };
|
||||||
| |____-
|
| |____-
|
||||||
|
|
|
@ -95,22 +95,26 @@ const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
|
||||||
|
|
||||||
// # trait object
|
// # trait object
|
||||||
// bad trait object
|
// bad trait object
|
||||||
|
#[warn(const_err)]
|
||||||
const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) };
|
const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ WARN any use of this value will cause an error [const_err]
|
||||||
// bad trait object
|
// bad trait object
|
||||||
|
#[warn(const_err)]
|
||||||
const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ WARN any use of this value will cause an error [const_err]
|
||||||
// bad trait object
|
// bad trait object
|
||||||
|
#[warn(const_err)]
|
||||||
const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) };
|
const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ WARN any use of this value will cause an error [const_err]
|
||||||
const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
|
const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ ERROR it is undefined behavior to use this value
|
||||||
const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
|
const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ ERROR it is undefined behavior to use this value
|
||||||
const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
|
const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ ERROR it is undefined behavior to use this value
|
||||||
|
#[warn(const_err)]
|
||||||
const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: &dyn Trait = unsafe { mem::transmute((&92u8, &[&42u8; 8])) };
|
const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: &dyn Trait = unsafe { mem::transmute((&92u8, &[&42u8; 8])) };
|
||||||
//~^ ERROR it is undefined behavior to use this value
|
//~^ WARN any use of this value will cause an error [const_err]
|
||||||
|
|
||||||
// bad data *inside* the trait object
|
// bad data *inside* the trait object
|
||||||
const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
|
const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
|
||||||
|
|
|
@ -134,32 +134,50 @@ LL | | };
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/ub-wide-ptr.rs:98:1
|
--> $DIR/ub-wide-ptr.rs:99:55
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) };
|
LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
|
| ------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
| |
|
||||||
|
| memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
note: the lint level is defined here
|
||||||
|
--> $DIR/ub-wide-ptr.rs:98:8
|
||||||
|
|
|
||||||
|
LL | #[warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/ub-wide-ptr.rs:101:1
|
--> $DIR/ub-wide-ptr.rs:103:55
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
|
| ------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
| |
|
||||||
|
| memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
note: the lint level is defined here
|
||||||
|
--> $DIR/ub-wide-ptr.rs:102:8
|
||||||
|
|
|
||||||
|
LL | #[warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/ub-wide-ptr.rs:104:1
|
--> $DIR/ub-wide-ptr.rs:107:51
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) };
|
LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
|
| --------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
| |
|
||||||
|
| unable to turn bytes into a pointer
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
note: the lint level is defined here
|
||||||
|
--> $DIR/ub-wide-ptr.rs:106:8
|
||||||
|
|
|
||||||
|
LL | #[warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:106:1
|
--> $DIR/ub-wide-ptr.rs:109:1
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
|
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer
|
||||||
|
@ -167,7 +185,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:108:1
|
--> $DIR/ub-wide-ptr.rs:111:1
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
|
||||||
|
@ -175,23 +193,29 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:110:1
|
--> $DIR/ub-wide-ptr.rs:113:1
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
|
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/ub-wide-ptr.rs:112:1
|
--> $DIR/ub-wide-ptr.rs:116:63
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: &dyn Trait = unsafe { mem::transmute((&92u8, &[&42u8; 8])) };
|
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: &dyn Trait = unsafe { mem::transmute((&92u8, &[&42u8; 8])) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
|
| --------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
| |
|
||||||
|
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||||
|
|
|
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
note: the lint level is defined here
|
||||||
|
--> $DIR/ub-wide-ptr.rs:115:8
|
||||||
|
|
|
||||||
|
LL | #[warn(const_err)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:116:1
|
--> $DIR/ub-wide-ptr.rs:120:1
|
||||||
|
|
|
|
||||||
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
|
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .<deref>.<dyn-downcast>, but expected a boolean
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x03 at .<deref>.<dyn-downcast>, but expected a boolean
|
||||||
|
@ -199,7 +223,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:120:1
|
--> $DIR/ub-wide-ptr.rs:124:1
|
||||||
|
|
|
|
||||||
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
|
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
|
||||||
|
@ -207,7 +231,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: it is undefined behavior to use this value
|
error[E0080]: it is undefined behavior to use this value
|
||||||
--> $DIR/ub-wide-ptr.rs:122:1
|
--> $DIR/ub-wide-ptr.rs:126:1
|
||||||
|
|
|
|
||||||
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
|
||||||
|
@ -215,17 +239,17 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
|
||||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||||
|
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $DIR/ub-wide-ptr.rs:128:5
|
--> $DIR/ub-wide-ptr.rs:132:5
|
||||||
|
|
|
|
||||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inbounds test failed: 0x0 is not a valid pointer
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inbounds test failed: 0x0 is not a valid pointer
|
||||||
|
|
||||||
error[E0080]: could not evaluate static initializer
|
error[E0080]: could not evaluate static initializer
|
||||||
--> $DIR/ub-wide-ptr.rs:132:5
|
--> $DIR/ub-wide-ptr.rs:136:5
|
||||||
|
|
|
|
||||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
|
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
||||||
|
|
||||||
error: aborting due to 28 previous errors
|
error: aborting due to 24 previous errors; 4 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -14,6 +14,11 @@ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`..
|
||||||
|
|
|
|
||||||
LL | bytes: [u8; std::mem::size_of::<Foo>()]
|
LL | bytes: [u8; std::mem::size_of::<Foo>()]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires simplifying constant for the type system `std::intrinsics::size_of`...
|
||||||
|
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub fn size_of<T>() -> usize;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: ...which requires computing layout of `Foo`...
|
= note: ...which requires computing layout of `Foo`...
|
||||||
= note: ...which requires normalizing `[u8; _]`...
|
= note: ...which requires normalizing `[u8; _]`...
|
||||||
= note: ...which again requires simplifying constant for the type system `Foo::bytes::{constant#0}`, completing the cycle
|
= note: ...which again requires simplifying constant for the type system `Foo::bytes::{constant#0}`, completing the cycle
|
||||||
|
|
|
@ -35,11 +35,11 @@ LL | U8_MUT => true,
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
warning: any use of this value will cause an error
|
warning: any use of this value will cause an error
|
||||||
--> $DIR/const_refers_to_static_cross_crate.rs:26:14
|
--> $DIR/const_refers_to_static_cross_crate.rs:26:15
|
||||||
|
|
|
|
||||||
LL | / const U8_MUT2: &u8 = {
|
LL | / const U8_MUT2: &u8 = {
|
||||||
LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
|
LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] }
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | | };
|
LL | | };
|
||||||
|
|
|
@ -66,6 +66,7 @@ const _: *const u8 =
|
||||||
//~^ NOTE
|
//~^ NOTE
|
||||||
unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
||||||
//~^ ERROR any use of this value will cause an error
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
//~| NOTE
|
||||||
|
|
||||||
const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||||
//~^ ERROR any use of this value will cause an error
|
//~^ ERROR any use of this value will cause an error
|
||||||
|
|
|
@ -16,19 +16,17 @@ LL | const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
|
||||||
= note: `#[deny(const_err)]` on by default
|
= note: `#[deny(const_err)]` on by default
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/ptr_comparisons.rs:67:14
|
--> $DIR/ptr_comparisons.rs:67:35
|
||||||
|
|
|
|
||||||
LL | / const _: *const u8 =
|
LL | / const _: *const u8 =
|
||||||
LL | |
|
LL | |
|
||||||
LL | | unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
LL | | unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
|
||||||
| |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
|
| |___________________________________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^___-
|
||||||
| |
|
| |
|
||||||
| memory access failed: pointer must be in-bounds at offset 1000, but is outside bounds of alloc2 which has size $WORD
|
| memory access failed: pointer must be in-bounds at offset 1000, but is outside bounds of alloc2 which has size $WORD
|
||||||
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/ptr_comparisons.rs:70:27
|
--> $DIR/ptr_comparisons.rs:71:27
|
||||||
|
|
|
|
||||||
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||||
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
@ -36,7 +34,7 @@ LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) +
|
||||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/ptr_comparisons.rs:75:27
|
--> $DIR/ptr_comparisons.rs:76:27
|
||||||
|
|
|
|
||||||
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
||||||
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue