Skip to content

Commit

Permalink
Auto merge of rust-lang#111414 - matthiaskrgr:rollup-q0qoc47, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#110673 (Make alias bounds sound in the new solver (take 2))
 - rust-lang#110747 (Encode types in SMIR)
 - rust-lang#111095 (Correctly handle associated items of a trait inside a `#[doc(hidden)]` item)
 - rust-lang#111381 (Keep encoding attributes for closures)
 - rust-lang#111408 (Fix incorrect implication of transmuting slices)
 - rust-lang#111410 (Switch to `EarlyBinder` for `thir_abstract_const` query)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 10, 2023
2 parents 63fc57b + 70d5bf7 commit 25444e5
Show file tree
Hide file tree
Showing 28 changed files with 616 additions and 220 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,7 @@ impl<'tcx> InferCtxt<'tcx> {
// variables
let tcx = self.tcx;
if substs.has_non_region_infer() {
if let Some(ct) = tcx.bound_abstract_const(unevaluated.def)? {
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs));
if let Err(e) = ct.error_reported() {
return Err(ErrorHandled::Reported(e));
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,11 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
| DefKind::Macro(_)
| DefKind::Field
| DefKind::Impl { .. } => true,
// Tools may want to be able to detect their tool lints on
// closures from upstream crates, too. This is used by
// https://github.com/model-checking/kani and is not a performance
// or maintenance issue for us.
DefKind::Closure => true,
DefKind::TyParam
| DefKind::ConstParam
| DefKind::Ctor(..)
Expand All @@ -874,7 +879,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
| DefKind::ImplTraitPlaceholder
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Closure
| DefKind::Generator => false,
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ define_tables! {
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
thir_abstract_const: Table<DefIndex, LazyValue<ty::Const<'static>>>,
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
constness: Table<DefIndex, hir::Constness>,
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuarantee
[u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()];
}

impl EraseType for Result<Option<ty::Const<'_>>, rustc_errors::ErrorGuaranteed> {
type Result =
[u8; size_of::<Result<Option<ty::Const<'static>>, rustc_errors::ErrorGuaranteed>>()];
impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> {
type Result = [u8; size_of::<
Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
>()];
}

impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rustc_queries! {
/// Try to build an abstract representation of the given constant.
query thir_abstract_const(
key: DefId
) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> {
) -> Result<Option<ty::EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed> {
desc {
|tcx| "building an abstract representation for `{}`", tcx.def_path_str(key),
}
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_middle/src/ty/abstract_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::ty::{
TypeVisitableExt,
};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;

#[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)]
#[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)]
Expand Down Expand Up @@ -35,12 +34,6 @@ TrivialTypeTraversalAndLiftImpls! {
pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;

impl<'tcx> TyCtxt<'tcx> {
/// Returns a const without substs applied
pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> {
let ac = self.thir_abstract_const(uv);
Ok(ac?.map(|ac| EarlyBinder(ac)))
}

pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T {
struct Expander<'tcx> {
tcx: TyCtxt<'tcx>,
Expand All @@ -59,7 +52,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
let ct = match c.kind() {
ty::ConstKind::Unevaluated(uv) => match self.tcx.bound_abstract_const(uv.def) {
ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e),
Ok(Some(bac)) => {
let substs = self.tcx.erase_regions(uv.substs);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_smir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
test(attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
#![feature(local_key_cell_methods)]
#![feature(ptr_metadata)]

pub mod rustc_internal;
pub mod stable_mir;
Expand Down
45 changes: 32 additions & 13 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,49 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.
use std::sync::RwLock;

use crate::stable_mir;
use crate::{
rustc_smir::Tables,
stable_mir::{self, with},
};
use rustc_middle::ty::TyCtxt;
pub use rustc_span::def_id::{CrateNum, DefId};

static DEF_ID_MAP: RwLock<Vec<DefId>> = RwLock::new(Vec::new());
fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
let mut ret = None;
with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t))));
ret.unwrap()
}

pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
DEF_ID_MAP.read().unwrap()[item.0]
with_tables(|t| t.item_def_id(item))
}

pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
// FIXME: this becomes inefficient when we have too many ids
let mut map = DEF_ID_MAP.write().unwrap();
for (i, &d) in map.iter().enumerate() {
if d == did {
return stable_mir::CrateItem(i);
with_tables(|t| t.crate_item(did))
}

impl<'tcx> Tables<'tcx> {
pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId {
self.def_ids[item.0]
}

pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
// FIXME: this becomes inefficient when we have too many ids
for (i, &d) in self.def_ids.iter().enumerate() {
if d == did {
return stable_mir::CrateItem(i);
}
}
let id = self.def_ids.len();
self.def_ids.push(did);
stable_mir::CrateItem(id)
}
let id = map.len();
map.push(did);
stable_mir::CrateItem(id)
}

pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
item.id.into()
}

pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
}
135 changes: 92 additions & 43 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,107 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
use crate::{
rustc_internal::{crate_item, item_def_id},
stable_mir::{self},
};
use rustc_middle::ty::{tls::with, TyCtxt};
use rustc_span::def_id::{CrateNum, LOCAL_CRATE};
use crate::stable_mir::{self, ty::TyKind, Context};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use tracing::debug;

/// Get information about the local crate.
pub fn local_crate() -> stable_mir::Crate {
with(|tcx| smir_crate(tcx, LOCAL_CRATE))
}
impl<'tcx> Context for Tables<'tcx> {
fn local_crate(&self) -> stable_mir::Crate {
smir_crate(self.tcx, LOCAL_CRATE)
}

/// Retrieve a list of all external crates.
pub fn external_crates() -> Vec<stable_mir::Crate> {
with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect())
}
fn external_crates(&self) -> Vec<stable_mir::Crate> {
self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect()
}

/// Find a crate with the given name.
pub fn find_crate(name: &str) -> Option<stable_mir::Crate> {
with(|tcx| {
[LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| {
let crate_name = tcx.crate_name(*crate_num).to_string();
(name == crate_name).then(|| smir_crate(tcx, *crate_num))
fn find_crate(&self, name: &str) -> Option<stable_mir::Crate> {
[LOCAL_CRATE].iter().chain(self.tcx.crates(()).iter()).find_map(|crate_num| {
let crate_name = self.tcx.crate_name(*crate_num).to_string();
(name == crate_name).then(|| smir_crate(self.tcx, *crate_num))
})
})
}

fn all_local_items(&mut self) -> stable_mir::CrateItems {
self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
}
fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
Some(self.crate_item(self.tcx.entry_fn(())?.0))
}
fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
let def_id = self.item_def_id(item);
let mir = self.tcx.optimized_mir(def_id);
stable_mir::mir::Body {
blocks: mir
.basic_blocks
.iter()
.map(|block| stable_mir::mir::BasicBlock {
terminator: rustc_terminator_to_terminator(block.terminator()),
statements: block.statements.iter().map(rustc_statement_to_statement).collect(),
})
.collect(),
locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(),
}
}

fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) {
f(self)
}

fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
self.rustc_ty_to_ty(self.types[ty.0])
}
}

/// Retrieve all items of the local crate that have a MIR associated with them.
pub fn all_local_items() -> stable_mir::CrateItems {
with(|tcx| tcx.mir_keys(()).iter().map(|item| crate_item(item.to_def_id())).collect())
pub struct Tables<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub def_ids: Vec<DefId>,
pub types: Vec<Ty<'tcx>>,
}

pub fn entry_fn() -> Option<stable_mir::CrateItem> {
with(|tcx| Some(crate_item(tcx.entry_fn(())?.0)))
impl<'tcx> Tables<'tcx> {
fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind {
match ty.kind() {
ty::Bool => TyKind::Bool,
ty::Char => todo!(),
ty::Int(_) => todo!(),
ty::Uint(_) => todo!(),
ty::Float(_) => todo!(),
ty::Adt(_, _) => todo!(),
ty::Foreign(_) => todo!(),
ty::Str => todo!(),
ty::Array(_, _) => todo!(),
ty::Slice(_) => todo!(),
ty::RawPtr(_) => todo!(),
ty::Ref(_, _, _) => todo!(),
ty::FnDef(_, _) => todo!(),
ty::FnPtr(_) => todo!(),
ty::Placeholder(..) => todo!(),
ty::Dynamic(_, _, _) => todo!(),
ty::Closure(_, _) => todo!(),
ty::Generator(_, _, _) => todo!(),
ty::GeneratorWitness(_) => todo!(),
ty::GeneratorWitnessMIR(_, _) => todo!(),
ty::Never => todo!(),
ty::Tuple(fields) => {
TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect())
}
ty::Alias(_, _) => todo!(),
ty::Param(_) => todo!(),
ty::Bound(_, _) => todo!(),
ty::Infer(_) => todo!(),
ty::Error(_) => todo!(),
}
}

fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty {
if let Some(id) = self.types.iter().position(|&t| t == ty) {
return stable_mir::ty::Ty(id);
}
let id = self.types.len();
self.types.push(ty);
stable_mir::ty::Ty(id)
}
}

/// Build a stable mir crate from a given crate number.
Expand All @@ -52,23 +118,6 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
}

pub fn mir_body(item: &stable_mir::CrateItem) -> stable_mir::mir::Body {
with(|tcx| {
let def_id = item_def_id(item);
let mir = tcx.optimized_mir(def_id);
stable_mir::mir::Body {
blocks: mir
.basic_blocks
.iter()
.map(|block| stable_mir::mir::BasicBlock {
terminator: rustc_terminator_to_terminator(block.terminator()),
statements: block.statements.iter().map(rustc_statement_to_statement).collect(),
})
.collect(),
}
})
}

fn rustc_statement_to_statement(
s: &rustc_middle::mir::Statement<'_>,
) -> stable_mir::mir::Statement {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_smir/src/stable_mir/mir/body.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::stable_mir::ty::Ty;

#[derive(Clone, Debug)]
pub struct Body {
pub blocks: Vec<BasicBlock>,
pub locals: Vec<Ty>,
}

#[derive(Clone, Debug)]
Expand Down
Loading

0 comments on commit 25444e5

Please sign in to comment.