Skip to content

Commit

Permalink
Remove HIR based const qualification
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjasper committed Sep 30, 2019
1 parent 22bc9e1 commit 455945f
Show file tree
Hide file tree
Showing 19 changed files with 66 additions and 916 deletions.
15 changes: 1 addition & 14 deletions src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -20,7 +20,6 @@ use crate::ty::{self, DefIdTree, TyCtxt, adjustment};
use crate::hir::{self, PatKind};
use std::rc::Rc;
use syntax_pos::Span;
use crate::util::nodemap::ItemLocalSet;

///////////////////////////////////////////////////////////////////////////
// The Delegate trait
Expand Down Expand Up @@ -261,9 +260,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
/// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
/// - `region_scope_tree` --- region scope tree for the code being analyzed
/// - `tables` --- typeck results for the code being analyzed
/// - `rvalue_promotable_map` --- if you care about rvalue promotion, then provide
/// the map here (it can be computed with `tcx.rvalue_promotable_map(def_id)`).
/// `None` means that rvalues will be given more conservative lifetimes.
///
/// See also `with_infer`, which is used *during* typeck.
pub fn new(
Expand All @@ -273,15 +269,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>,
rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
) -> Self {
ExprUseVisitor {
mc: mc::MemCategorizationContext::new(tcx,
param_env,
body_owner,
region_scope_tree,
tables,
rvalue_promotable_map),
tables),
delegate,
param_env,
}
Expand Down Expand Up @@ -317,16 +311,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
let param_ty = return_if_err!(self.mc.pat_ty_adjusted(&param.pat));
debug!("consume_body: param_ty = {:?}", param_ty);

let fn_body_scope_r =
self.tcx().mk_region(ty::ReScope(
region::Scope {
id: body.value.hir_id.local_id,
data: region::ScopeData::Node
}));
let param_cmt = Rc::new(self.mc.cat_rvalue(
param.hir_id,
param.pat.span,
fn_body_scope_r, // Parameters live only as long as the fn body.
param_ty));

self.walk_irrefutable_pat(param_cmt, &param.pat);
Expand Down
66 changes: 11 additions & 55 deletions src/librustc/middle/mem_categorization.rs
Expand Up @@ -79,12 +79,11 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use rustc_data_structures::fx::FxIndexMap;
use std::rc::Rc;
use crate::util::nodemap::ItemLocalSet;

#[derive(Clone, Debug, PartialEq)]
pub enum Categorization<'tcx> {
Rvalue(ty::Region<'tcx>), // temporary val, argument is its scope
ThreadLocal(ty::Region<'tcx>), // value that cannot move, but still restricted in scope
Rvalue, // temporary val
ThreadLocal, // value that cannot move, but still restricted in scope
StaticItem,
Upvar(Upvar), // upvar referenced by closure env
Local(hir::HirId), // local variable
Expand Down Expand Up @@ -219,7 +218,6 @@ pub struct MemCategorizationContext<'a, 'tcx> {
pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
pub region_scope_tree: &'a region::ScopeTree,
pub tables: &'a ty::TypeckTables<'tcx>,
rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
infcx: Option<&'a InferCtxt<'a, 'tcx>>,
}

Expand Down Expand Up @@ -335,15 +333,13 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
body_owner: DefId,
region_scope_tree: &'a region::ScopeTree,
tables: &'a ty::TypeckTables<'tcx>,
rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
) -> MemCategorizationContext<'a, 'tcx> {
MemCategorizationContext {
tcx,
body_owner,
upvars: tcx.upvars(body_owner),
region_scope_tree,
tables,
rvalue_promotable_map,
infcx: None,
param_env,
}
Expand All @@ -369,19 +365,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
) -> MemCategorizationContext<'a, 'tcx> {
let tcx = infcx.tcx;

// Subtle: we can't do rvalue promotion analysis until the
// typeck phase is complete, which means that you can't trust
// the rvalue lifetimes that result, but that's ok, since we
// don't need to know those during type inference.
let rvalue_promotable_map = None;

MemCategorizationContext {
tcx,
body_owner,
upvars: tcx.upvars(body_owner),
region_scope_tree,
tables,
rvalue_promotable_map,
infcx: Some(infcx),
param_env,
}
Expand Down Expand Up @@ -664,8 +653,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
.any(|attr| attr.check_name(sym::thread_local));

let cat = if is_thread_local {
let re = self.temporary_scope(hir_id.local_id);
Categorization::ThreadLocal(re)
Categorization::ThreadLocal
} else {
Categorization::StaticItem
};
Expand Down Expand Up @@ -876,16 +864,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
ret
}

/// Returns the lifetime of a temporary created by expr with id `id`.
/// This could be `'static` if `id` is part of a constant expression.
pub fn temporary_scope(&self, id: hir::ItemLocalId) -> ty::Region<'tcx> {
let scope = self.region_scope_tree.temporary_scope(id);
self.tcx.mk_region(match scope {
Some(scope) => ty::ReScope(scope),
None => ty::ReStatic
})
}

pub fn cat_rvalue_node(&self,
hir_id: hir::HirId,
span: Span,
Expand All @@ -894,41 +872,19 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
debug!("cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
hir_id, span, expr_ty);

let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
.unwrap_or(false);

debug!("cat_rvalue_node: promotable = {:?}", promotable);

// Always promote `[T; 0]` (even when e.g., borrowed mutably).
let promotable = match expr_ty.kind {
ty::Array(_, len) if len.try_eval_usize(self.tcx, self.param_env) == Some(0) => true,
_ => promotable,
};

debug!("cat_rvalue_node: promotable = {:?} (2)", promotable);

// Compute maximum lifetime of this rvalue. This is 'static if
// we can promote to a constant, otherwise equal to enclosing temp
// lifetime.
let re = if promotable {
self.tcx.lifetimes.re_static
} else {
self.temporary_scope(hir_id.local_id)
};
let ret = self.cat_rvalue(hir_id, span, re, expr_ty);
let ret = self.cat_rvalue(hir_id, span, expr_ty);
debug!("cat_rvalue_node ret {:?}", ret);
ret
}

pub fn cat_rvalue(&self,
cmt_hir_id: hir::HirId,
span: Span,
temp_scope: ty::Region<'tcx>,
expr_ty: Ty<'tcx>) -> cmt_<'tcx> {
let ret = cmt_ {
hir_id: cmt_hir_id,
span:span,
cat:Categorization::Rvalue(temp_scope),
cat:Categorization::Rvalue,
mutbl:McDeclared,
ty:expr_ty,
note: NoteNone
Expand Down Expand Up @@ -1376,9 +1332,9 @@ impl<'tcx> cmt_<'tcx> {
//! determines how long the value in `self` remains live.

match self.cat {
Categorization::Rvalue(..) |
Categorization::Rvalue |
Categorization::StaticItem |
Categorization::ThreadLocal(..) |
Categorization::ThreadLocal |
Categorization::Local(..) |
Categorization::Deref(_, UnsafePtr(..)) |
Categorization::Deref(_, BorrowedPtr(..)) |
Expand Down Expand Up @@ -1409,8 +1365,8 @@ impl<'tcx> cmt_<'tcx> {
b.freely_aliasable()
}

Categorization::Rvalue(..) |
Categorization::ThreadLocal(..) |
Categorization::Rvalue |
Categorization::ThreadLocal |
Categorization::Local(..) |
Categorization::Upvar(..) |
Categorization::Deref(_, UnsafePtr(..)) => { // yes, it's aliasable, but...
Expand Down Expand Up @@ -1457,10 +1413,10 @@ impl<'tcx> cmt_<'tcx> {
Categorization::StaticItem => {
"static item".into()
}
Categorization::ThreadLocal(..) => {
Categorization::ThreadLocal => {
"thread-local static item".into()
}
Categorization::Rvalue(..) => {
Categorization::Rvalue => {
"non-place".into()
}
Categorization::Local(vid) => {
Expand Down
14 changes: 1 addition & 13 deletions src/librustc/query/mod.rs
Expand Up @@ -94,6 +94,7 @@ rustc_queries! {
/// of the MIR qualify_consts pass. The actual meaning of
/// the value isn't known except to the pass itself.
query mir_const_qualif(key: DefId) -> (u8, &'tcx BitSet<mir::Local>) {
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
}

Expand Down Expand Up @@ -530,19 +531,6 @@ rustc_queries! {

TypeChecking {
query trait_of_item(_: DefId) -> Option<DefId> {}
query const_is_rvalue_promotable_to_static(key: DefId) -> bool {
desc { |tcx|
"const checking if rvalue is promotable to static `{}`",
tcx.def_path_str(key)
}
cache_on_disk_if { true }
}
query rvalue_promotable_map(key: DefId) -> &'tcx ItemLocalSet {
desc { |tcx|
"checking which parts of `{}` are promotable to static",
tcx.def_path_str(key)
}
}
}

Codegen {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/query/mod.rs
Expand Up @@ -37,7 +37,7 @@ use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, AdtSizedConst
use crate::ty::steal::Steal;
use crate::ty::util::NeedsDrop;
use crate::ty::subst::SubstsRef;
use crate::util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};
use crate::util::nodemap::{DefIdSet, DefIdMap};
use crate::util::common::ErrorReported;
use crate::util::profiling::ProfileCategory::*;

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_interface/passes.rs
Expand Up @@ -916,9 +916,8 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {

time(sess, "misc checking 2", || {
parallel!({
time(sess, "rvalue promotion + match checking", || {
time(sess, "match checking", || {
tcx.par_body_owners(|def_id| {
tcx.ensure().const_is_rvalue_promotable_to_static(def_id);
tcx.ensure().check_match(def_id);
});
});
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_metadata/cstore_impl.rs
Expand Up @@ -154,9 +154,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
rendered_const => { cdata.get_rendered_const(def_id.index) }
impl_parent => { cdata.get_parent_impl(def_id.index) }
trait_of_item => { cdata.get_trait_of_item(def_id.index) }
const_is_rvalue_promotable_to_static => {
cdata.const_is_rvalue_promotable_to_static(def_id.index)
}
is_mir_available => { cdata.is_item_mir_available(def_id.index) }

dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
Expand Down
8 changes: 0 additions & 8 deletions src/librustc_metadata/decoder.rs
Expand Up @@ -915,14 +915,6 @@ impl<'a, 'tcx> CrateMetadata {
}
}

pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool {
match self.entry(id).kind {
EntryKind::AssocConst(_, data, _) |
EntryKind::Const(data, _) => data.ast_promotable,
_ => bug!(),
}
}

pub fn is_item_mir_available(&self, id: DefIndex) -> bool {
!self.is_proc_macro(id) &&
self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
Expand Down
22 changes: 4 additions & 18 deletions src/librustc_metadata/encoder.rs
Expand Up @@ -861,18 +861,11 @@ impl EncodeContext<'tcx> {

let kind = match trait_item.kind {
ty::AssocKind::Const => {
let const_qualif =
if let hir::TraitItemKind::Const(_, Some(body)) = ast_item.kind {
self.const_qualif(0, body)
} else {
ConstQualif { mir: 0, ast_promotable: false }
};

let rendered =
hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
let rendered_const = self.lazy(RenderedConst(rendered));

EntryKind::AssocConst(container, const_qualif, rendered_const)
EntryKind::AssocConst(container, ConstQualif { mir: 0 }, rendered_const)
}
ty::AssocKind::Method => {
let fn_data = if let hir::TraitItemKind::Method(method_sig, m) = &ast_item.kind {
Expand Down Expand Up @@ -946,13 +939,6 @@ impl EncodeContext<'tcx> {
!self.tcx.sess.opts.output_types.should_codegen()
}

fn const_qualif(&self, mir: u8, body_id: hir::BodyId) -> ConstQualif {
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body_id);
let ast_promotable = self.tcx.const_is_rvalue_promotable_to_static(body_owner_def_id);

ConstQualif { mir, ast_promotable }
}

fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
let tcx = self.tcx;
Expand All @@ -974,7 +960,7 @@ impl EncodeContext<'tcx> {
let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id).0;

EntryKind::AssocConst(container,
self.const_qualif(mir, body_id),
ConstQualif { mir },
self.encode_rendered_const_for_body(body_id))
} else {
bug!()
Expand Down Expand Up @@ -1123,7 +1109,7 @@ impl EncodeContext<'tcx> {
hir::ItemKind::Const(_, body_id) => {
let mir = tcx.at(item.span).mir_const_qualif(def_id).0;
EntryKind::Const(
self.const_qualif(mir, body_id),
ConstQualif { mir },
self.encode_rendered_const_for_body(body_id)
)
}
Expand Down Expand Up @@ -1475,7 +1461,7 @@ impl EncodeContext<'tcx> {
let mir = tcx.mir_const_qualif(def_id).0;

Entry {
kind: EntryKind::Const(self.const_qualif(mir, body_id), const_data),
kind: EntryKind::Const(ConstQualif { mir }, const_data),
visibility: self.lazy(ty::Visibility::Public),
span: self.lazy(tcx.def_span(def_id)),
attributes: Lazy::empty(),
Expand Down
1 change: 0 additions & 1 deletion src/librustc_metadata/schema.rs
Expand Up @@ -274,7 +274,6 @@ pub enum EntryKind<'tcx> {
#[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
pub struct ConstQualif {
pub mir: u8,
pub ast_promotable: bool,
}

/// Contains a constant which has been rendered to a String.
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_passes/lib.rs
Expand Up @@ -19,12 +19,10 @@ use rustc::ty::query::Providers;
pub mod error_codes;

pub mod ast_validation;
pub mod rvalue_promotion;
pub mod hir_stats;
pub mod layout_test;
pub mod loops;

pub fn provide(providers: &mut Providers<'_>) {
rvalue_promotion::provide(providers);
loops::provide(providers);
}

0 comments on commit 455945f

Please sign in to comment.