Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify ExprUseVisitor #64874

Merged
merged 2 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
473 changes: 79 additions & 394 deletions src/librustc/middle/expr_use_visitor.rs

Large diffs are not rendered by default.

66 changes: 11 additions & 55 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this crate is becoming quite pointless.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could split them out to a crate for each pass. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are tiny though... a bunch of them belong in rustc::hir which could become a crate (with only the data types remaining in rustc).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever we do, let's please not inflate the size of the rustc crate. :)


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