mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
move resolve_lifetimes
into a proper query
Now that we made `resolve_lifetimes` into a query, elision errors no longer abort compilation, which affects some tests. Also, remove `dep_graph_crosscontaminate_tables` -- there is no a path in the dep-graph, though red-green handles it. The same scenario is (correctly) tested by issue-42602.rs in any case.
This commit is contained in:
parent
d737ea7902
commit
b7794c0d3f
@ -588,9 +588,10 @@ define_dep_nodes!( <'tcx>
|
||||
[] NativeLibraryKind(DefId),
|
||||
[input] LinkArgs,
|
||||
|
||||
[input] NamedRegion(DefIndex),
|
||||
[input] IsLateBound(DefIndex),
|
||||
[input] ObjectLifetimeDefaults(DefIndex),
|
||||
[] ResolveLifetimes(CrateNum),
|
||||
[] NamedRegion(DefIndex),
|
||||
[] IsLateBound(DefIndex),
|
||||
[] ObjectLifetimeDefaults(DefIndex),
|
||||
|
||||
[] Visibility(DefId),
|
||||
[] DepKind(CrateNum),
|
||||
|
@ -28,7 +28,7 @@ pub use self::UnsafeSource::*;
|
||||
pub use self::Visibility::{Public, Inherited};
|
||||
|
||||
use hir::def::Def;
|
||||
use hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
|
||||
use util::nodemap::{NodeMap, FxHashSet};
|
||||
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
@ -92,6 +92,16 @@ pub struct HirId {
|
||||
pub local_id: ItemLocalId,
|
||||
}
|
||||
|
||||
impl HirId {
|
||||
pub fn owner_def_id(self) -> DefId {
|
||||
DefId::local(self.owner)
|
||||
}
|
||||
|
||||
pub fn owner_local_def_id(self) -> LocalDefId {
|
||||
LocalDefId::from_def_id(DefId::local(self.owner))
|
||||
}
|
||||
}
|
||||
|
||||
impl serialize::UseSpecializedEncodable for HirId {
|
||||
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let HirId {
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
use hir::map::Map;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::DefId;
|
||||
use middle::cstore::CrateStore;
|
||||
use session::Session;
|
||||
use ty;
|
||||
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use hir::ItemLocalId;
|
||||
use ty::{self, TyCtxt};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::mem::replace;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::ptr::P;
|
||||
@ -181,9 +181,14 @@ impl<T: PartialEq> Set1<T> {
|
||||
|
||||
pub type ObjectLifetimeDefault = Set1<Region>;
|
||||
|
||||
// Maps the id of each lifetime reference to the lifetime decl
|
||||
// that it corresponds to.
|
||||
pub struct NamedRegionMap {
|
||||
/// Maps the id of each lifetime reference to the lifetime decl
|
||||
/// that it corresponds to.
|
||||
///
|
||||
/// FIXME. This struct gets converted to a `ResolveLifetimes` for
|
||||
/// actual use. It has the same data, but indexed by `DefIndex`. This
|
||||
/// is silly.
|
||||
#[derive(Default)]
|
||||
struct NamedRegionMap {
|
||||
// maps from every use of a named (not anonymous) lifetime to a
|
||||
// `Region` describing how that region is bound
|
||||
pub defs: NodeMap<Region>,
|
||||
@ -198,10 +203,22 @@ pub struct NamedRegionMap {
|
||||
pub object_lifetime_defaults: NodeMap<Vec<ObjectLifetimeDefault>>,
|
||||
}
|
||||
|
||||
/// See `NamedRegionMap`.
|
||||
pub struct ResolveLifetimes {
|
||||
defs: FxHashMap<LocalDefId, Rc<FxHashMap<ItemLocalId, Region>>>,
|
||||
late_bound: FxHashMap<LocalDefId, Rc<FxHashSet<ItemLocalId>>>,
|
||||
object_lifetime_defaults:
|
||||
FxHashMap<LocalDefId, Rc<FxHashMap<ItemLocalId, Rc<Vec<ObjectLifetimeDefault>>>>>,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ::middle::resolve_lifetime::ResolveLifetimes {
|
||||
defs,
|
||||
late_bound,
|
||||
object_lifetime_defaults
|
||||
});
|
||||
|
||||
struct LifetimeContext<'a, 'tcx: 'a> {
|
||||
sess: &'a Session,
|
||||
cstore: &'a CrateStore,
|
||||
hir_map: &'a Map<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
map: &'a mut NamedRegionMap,
|
||||
scope: ScopeRef<'a>,
|
||||
// Deep breath. Our representation for poly trait refs contains a single
|
||||
@ -299,22 +316,92 @@ type ScopeRef<'a> = &'a Scope<'a>;
|
||||
|
||||
const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
|
||||
|
||||
pub fn krate(
|
||||
sess: &Session,
|
||||
cstore: &CrateStore,
|
||||
hir_map: &Map,
|
||||
) -> Result<NamedRegionMap, ErrorReported> {
|
||||
let krate = hir_map.krate();
|
||||
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||
*providers = ty::maps::Providers {
|
||||
resolve_lifetimes,
|
||||
|
||||
named_region_map: |tcx, id| {
|
||||
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
|
||||
tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned()
|
||||
},
|
||||
|
||||
is_late_bound_map: |tcx, id| {
|
||||
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
|
||||
tcx.resolve_lifetimes(LOCAL_CRATE)
|
||||
.late_bound
|
||||
.get(&id)
|
||||
.cloned()
|
||||
},
|
||||
|
||||
object_lifetime_defaults_map: |tcx, id| {
|
||||
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
|
||||
tcx.resolve_lifetimes(LOCAL_CRATE)
|
||||
.object_lifetime_defaults
|
||||
.get(&id)
|
||||
.cloned()
|
||||
},
|
||||
|
||||
..*providers
|
||||
};
|
||||
|
||||
// (*) FIXME the query should be defined to take a LocalDefId
|
||||
}
|
||||
|
||||
/// Computes the `ResolveLifetimes` map that contains data for the
|
||||
/// entire crate. You should not read the result of this query
|
||||
/// directly, but rather use `named_region_map`, `is_late_bound_map`,
|
||||
/// etc.
|
||||
fn resolve_lifetimes<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
for_krate: CrateNum,
|
||||
) -> Rc<ResolveLifetimes> {
|
||||
assert_eq!(for_krate, LOCAL_CRATE);
|
||||
|
||||
let named_region_map = krate(tcx).unwrap_or_default();
|
||||
|
||||
let mut defs = FxHashMap();
|
||||
for (k, v) in named_region_map.defs {
|
||||
let hir_id = tcx.hir.node_to_hir_id(k);
|
||||
let map = defs.entry(hir_id.owner_local_def_id())
|
||||
.or_insert_with(|| Rc::new(FxHashMap()));
|
||||
Rc::get_mut(map).unwrap().insert(hir_id.local_id, v);
|
||||
}
|
||||
let mut late_bound = FxHashMap();
|
||||
for k in named_region_map.late_bound {
|
||||
let hir_id = tcx.hir.node_to_hir_id(k);
|
||||
let map = late_bound
|
||||
.entry(hir_id.owner_local_def_id())
|
||||
.or_insert_with(|| Rc::new(FxHashSet()));
|
||||
Rc::get_mut(map).unwrap().insert(hir_id.local_id);
|
||||
}
|
||||
let mut object_lifetime_defaults = FxHashMap();
|
||||
for (k, v) in named_region_map.object_lifetime_defaults {
|
||||
let hir_id = tcx.hir.node_to_hir_id(k);
|
||||
let map = object_lifetime_defaults
|
||||
.entry(hir_id.owner_local_def_id())
|
||||
.or_insert_with(|| Rc::new(FxHashMap()));
|
||||
Rc::get_mut(map)
|
||||
.unwrap()
|
||||
.insert(hir_id.local_id, Rc::new(v));
|
||||
}
|
||||
|
||||
Rc::new(ResolveLifetimes {
|
||||
defs,
|
||||
late_bound,
|
||||
object_lifetime_defaults,
|
||||
})
|
||||
}
|
||||
|
||||
fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> Result<NamedRegionMap, ErrorReported> {
|
||||
let krate = tcx.hir.krate();
|
||||
let mut map = NamedRegionMap {
|
||||
defs: NodeMap(),
|
||||
late_bound: NodeSet(),
|
||||
object_lifetime_defaults: compute_object_lifetime_defaults(sess, hir_map),
|
||||
object_lifetime_defaults: compute_object_lifetime_defaults(tcx),
|
||||
};
|
||||
sess.track_errors(|| {
|
||||
{
|
||||
let mut visitor = LifetimeContext {
|
||||
sess,
|
||||
cstore,
|
||||
hir_map,
|
||||
tcx,
|
||||
map: &mut map,
|
||||
scope: ROOT_SCOPE,
|
||||
trait_ref_hack: false,
|
||||
@ -325,13 +412,13 @@ pub fn krate(
|
||||
for (_, item) in &krate.items {
|
||||
visitor.visit_item(item);
|
||||
}
|
||||
})?;
|
||||
}
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||
NestedVisitorMap::All(self.hir_map)
|
||||
NestedVisitorMap::All(&self.tcx.hir)
|
||||
}
|
||||
|
||||
// We want to nest trait/impl items in their parent, but nothing else.
|
||||
@ -340,7 +427,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
fn visit_nested_body(&mut self, body: hir::BodyId) {
|
||||
// Each body has their own set of labels, save labels.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
let body = self.hir_map.body(body);
|
||||
let body = self.tcx.hir.body(body);
|
||||
extract_labels(self, body);
|
||||
self.with(
|
||||
Scope::Body {
|
||||
@ -393,7 +480,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let lifetimes = generics
|
||||
.lifetimes
|
||||
.iter()
|
||||
.map(|def| Region::early(self.hir_map, &mut index, def))
|
||||
.map(|def| Region::early(&self.tcx.hir, &mut index, def))
|
||||
.collect();
|
||||
let next_early_index = index + generics.ty_params.len() as u32;
|
||||
let scope = Scope::Binder {
|
||||
@ -435,10 +522,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let scope = Scope::Binder {
|
||||
lifetimes: c.lifetimes
|
||||
.iter()
|
||||
.map(|def| Region::late(self.hir_map, def))
|
||||
.map(|def| Region::late(&self.tcx.hir, def))
|
||||
.collect(),
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
};
|
||||
self.with(scope, |old_scope, this| {
|
||||
// a bare fn has no bounds, so everything
|
||||
@ -481,18 +568,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
// In the future, this should be fixed and this error should be removed.
|
||||
let def = self.map.defs.get(&lifetime.id);
|
||||
if let Some(&Region::LateBound(_, def_id, _)) = def {
|
||||
if let Some(node_id) = self.hir_map.as_local_node_id(def_id) {
|
||||
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||
// Ensure that the parent of the def is an item, not HRTB
|
||||
let parent_id = self.hir_map.get_parent_node(node_id);
|
||||
let parent_id = self.tcx.hir.get_parent_node(node_id);
|
||||
let parent_impl_id = hir::ImplItemId { node_id: parent_id };
|
||||
let parent_trait_id = hir::TraitItemId { node_id: parent_id };
|
||||
let krate = self.hir_map.forest.krate();
|
||||
let krate = self.tcx.hir.forest.krate();
|
||||
if !(krate.items.contains_key(&parent_id)
|
||||
|| krate.impl_items.contains_key(&parent_impl_id)
|
||||
|| krate.trait_items.contains_key(&parent_trait_id))
|
||||
{
|
||||
span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
lifetime.span,
|
||||
E0657,
|
||||
"`impl Trait` can only capture lifetimes \
|
||||
@ -517,7 +604,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let lifetimes = generics
|
||||
.lifetimes
|
||||
.iter()
|
||||
.map(|lt_def| Region::early(self.hir_map, &mut index, lt_def))
|
||||
.map(|lt_def| Region::early(&self.tcx.hir, &mut index, lt_def))
|
||||
.collect();
|
||||
|
||||
let next_early_index = index + generics.ty_params.len() as u32;
|
||||
@ -538,9 +625,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
|
||||
let tcx = self.tcx;
|
||||
if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node {
|
||||
self.visit_early_late(
|
||||
Some(self.hir_map.get_parent(trait_item.id)),
|
||||
Some(tcx.hir.get_parent(trait_item.id)),
|
||||
&sig.decl,
|
||||
&trait_item.generics,
|
||||
|this| intravisit::walk_trait_item(this, trait_item),
|
||||
@ -551,9 +639,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
|
||||
let tcx = self.tcx;
|
||||
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
|
||||
self.visit_early_late(
|
||||
Some(self.hir_map.get_parent(impl_item.id)),
|
||||
Some(tcx.hir.get_parent(impl_item.id)),
|
||||
&sig.decl,
|
||||
&impl_item.generics,
|
||||
|this| intravisit::walk_impl_item(this, impl_item),
|
||||
@ -593,7 +682,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||
check_mixed_explicit_and_in_band_defs(&self.sess, &generics.lifetimes);
|
||||
check_mixed_explicit_and_in_band_defs(self.tcx, &generics.lifetimes);
|
||||
for ty_param in generics.ty_params.iter() {
|
||||
walk_list!(self, visit_ty_param_bound, &ty_param.bounds);
|
||||
if let Some(ref ty) = ty_param.default {
|
||||
@ -614,10 +703,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
let scope = Scope::Binder {
|
||||
lifetimes: bound_lifetimes
|
||||
.iter()
|
||||
.map(|def| Region::late(self.hir_map, def))
|
||||
.map(|def| Region::late(&self.tcx.hir, def))
|
||||
.collect(),
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
};
|
||||
let result = self.with(scope, |old_scope, this| {
|
||||
this.check_lifetime_defs(old_scope, bound_lifetimes);
|
||||
@ -663,7 +752,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() {
|
||||
if self.trait_ref_hack {
|
||||
span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
trait_ref.span,
|
||||
E0316,
|
||||
"nested quantification of lifetimes"
|
||||
@ -674,10 +763,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
lifetimes: trait_ref
|
||||
.bound_lifetimes
|
||||
.iter()
|
||||
.map(|def| Region::late(self.hir_map, def))
|
||||
.map(|def| Region::late(&self.tcx.hir, def))
|
||||
.collect(),
|
||||
next_early_index,
|
||||
s: self.scope,
|
||||
next_early_index,
|
||||
};
|
||||
self.with(scope, |old_scope, this| {
|
||||
this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes);
|
||||
@ -740,13 +829,16 @@ impl ShadowKind {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_mixed_explicit_and_in_band_defs(sess: &Session, lifetime_defs: &[hir::LifetimeDef]) {
|
||||
fn check_mixed_explicit_and_in_band_defs(
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
lifetime_defs: &[hir::LifetimeDef],
|
||||
) {
|
||||
let oob_def = lifetime_defs.iter().find(|lt| !lt.in_band);
|
||||
let in_band_def = lifetime_defs.iter().find(|lt| lt.in_band);
|
||||
|
||||
if let (Some(oob_def), Some(in_band_def)) = (oob_def, in_band_def) {
|
||||
struct_span_err!(
|
||||
sess,
|
||||
tcx.sess,
|
||||
in_band_def.lifetime.span,
|
||||
E0688,
|
||||
"cannot mix in-band and explicit lifetime definitions"
|
||||
@ -759,11 +851,16 @@ fn check_mixed_explicit_and_in_band_defs(sess: &Session, lifetime_defs: &[hir::L
|
||||
}
|
||||
}
|
||||
|
||||
fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) {
|
||||
fn signal_shadowing_problem(
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
name: ast::Name,
|
||||
orig: Original,
|
||||
shadower: Shadower,
|
||||
) {
|
||||
let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
|
||||
// lifetime/lifetime shadowing is an error
|
||||
struct_span_err!(
|
||||
sess,
|
||||
tcx.sess,
|
||||
shadower.span,
|
||||
E0496,
|
||||
"{} name `{}` shadows a \
|
||||
@ -775,7 +872,7 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha
|
||||
} else {
|
||||
// shadowing involving a label is only a warning, due to issues with
|
||||
// labels and lifetimes not being macro-hygienic.
|
||||
sess.struct_span_warn(
|
||||
tcx.sess.struct_span_warn(
|
||||
shadower.span,
|
||||
&format!(
|
||||
"{} name `{}` shadows a \
|
||||
@ -793,17 +890,15 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha
|
||||
|
||||
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
|
||||
// if one of the label shadows a lifetime or another label.
|
||||
fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
|
||||
struct GatherLabels<'a, 'tcx: 'a> {
|
||||
sess: &'a Session,
|
||||
hir_map: &'a Map<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
scope: ScopeRef<'a>,
|
||||
labels_in_fn: &'a mut Vec<(ast::Name, Span)>,
|
||||
}
|
||||
|
||||
let mut gather = GatherLabels {
|
||||
sess: ctxt.sess,
|
||||
hir_map: ctxt.hir_map,
|
||||
tcx: ctxt.tcx,
|
||||
scope: ctxt.scope,
|
||||
labels_in_fn: &mut ctxt.labels_in_fn,
|
||||
};
|
||||
@ -820,7 +915,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
// FIXME (#24278): non-hygienic comparison
|
||||
if label == prior {
|
||||
signal_shadowing_problem(
|
||||
self.sess,
|
||||
self.tcx,
|
||||
label,
|
||||
original_label(prior_span),
|
||||
shadower_label(label_span),
|
||||
@ -828,13 +923,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
}
|
||||
}
|
||||
|
||||
check_if_label_shadows_lifetime(
|
||||
self.sess,
|
||||
self.hir_map,
|
||||
self.scope,
|
||||
label,
|
||||
label_span,
|
||||
);
|
||||
check_if_label_shadows_lifetime(self.tcx, self.scope, label, label_span);
|
||||
|
||||
self.labels_in_fn.push((label, label_span));
|
||||
}
|
||||
@ -851,10 +940,9 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_if_label_shadows_lifetime<'a>(
|
||||
sess: &'a Session,
|
||||
hir_map: &Map,
|
||||
mut scope: ScopeRef<'a>,
|
||||
fn check_if_label_shadows_lifetime(
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
mut scope: ScopeRef<'_>,
|
||||
label: ast::Name,
|
||||
label_span: Span,
|
||||
) {
|
||||
@ -877,12 +965,12 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
} => {
|
||||
// FIXME (#24278): non-hygienic comparison
|
||||
if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) {
|
||||
let node_id = hir_map.as_local_node_id(def.id().unwrap()).unwrap();
|
||||
let node_id = tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
|
||||
|
||||
signal_shadowing_problem(
|
||||
sess,
|
||||
tcx,
|
||||
label,
|
||||
original_lifetime(hir_map.span(node_id)),
|
||||
original_lifetime(tcx.hir.span(node_id)),
|
||||
shadower_label(label_span),
|
||||
);
|
||||
return;
|
||||
@ -895,18 +983,17 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) {
|
||||
}
|
||||
|
||||
fn compute_object_lifetime_defaults(
|
||||
sess: &Session,
|
||||
hir_map: &Map,
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
) -> NodeMap<Vec<ObjectLifetimeDefault>> {
|
||||
let mut map = NodeMap();
|
||||
for item in hir_map.krate().items.values() {
|
||||
for item in tcx.hir.krate().items.values() {
|
||||
match item.node {
|
||||
hir::ItemStruct(_, ref generics)
|
||||
| hir::ItemUnion(_, ref generics)
|
||||
| hir::ItemEnum(_, ref generics)
|
||||
| hir::ItemTy(_, ref generics)
|
||||
| hir::ItemTrait(_, _, ref generics, ..) => {
|
||||
let result = object_lifetime_defaults_for_item(hir_map, generics);
|
||||
let result = object_lifetime_defaults_for_item(tcx, generics);
|
||||
|
||||
// Debugging aid.
|
||||
if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") {
|
||||
@ -926,7 +1013,7 @@ fn compute_object_lifetime_defaults(
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
sess.span_err(item.span, &object_lifetime_default_reprs);
|
||||
tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
|
||||
}
|
||||
|
||||
map.insert(item.id, result);
|
||||
@ -941,7 +1028,7 @@ fn compute_object_lifetime_defaults(
|
||||
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
|
||||
/// for each type parameter.
|
||||
fn object_lifetime_defaults_for_item(
|
||||
hir_map: &Map,
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
generics: &hir::Generics,
|
||||
) -> Vec<ObjectLifetimeDefault> {
|
||||
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) {
|
||||
@ -960,7 +1047,7 @@ fn object_lifetime_defaults_for_item(
|
||||
|
||||
add_bounds(&mut set, ¶m.bounds);
|
||||
|
||||
let param_def_id = hir_map.local_def_id(param.id);
|
||||
let param_def_id = tcx.hir.local_def_id(param.id);
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
// Look for `type: ...` where clauses.
|
||||
let data = match *predicate {
|
||||
@ -996,7 +1083,7 @@ fn object_lifetime_defaults_for_item(
|
||||
.enumerate()
|
||||
.find(|&(_, def)| def.lifetime.name == name)
|
||||
.map_or(Set1::Many, |(i, def)| {
|
||||
let def_id = hir_map.local_def_id(def.lifetime.id);
|
||||
let def_id = tcx.hir.local_def_id(def.lifetime.id);
|
||||
let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
|
||||
Set1::One(Region::EarlyBound(i as u32, def_id, origin))
|
||||
})
|
||||
@ -1022,19 +1109,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
F: for<'b> FnOnce(ScopeRef, &mut LifetimeContext<'b, 'tcx>),
|
||||
{
|
||||
let LifetimeContext {
|
||||
sess,
|
||||
cstore,
|
||||
hir_map,
|
||||
ref mut map,
|
||||
..
|
||||
tcx, ref mut map, ..
|
||||
} = *self;
|
||||
let labels_in_fn = replace(&mut self.labels_in_fn, vec![]);
|
||||
let xcrate_object_lifetime_defaults =
|
||||
replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap());
|
||||
let mut this = LifetimeContext {
|
||||
sess,
|
||||
cstore,
|
||||
hir_map,
|
||||
tcx,
|
||||
map: *map,
|
||||
scope: &wrap_scope,
|
||||
trait_ref_hack: self.trait_ref_hack,
|
||||
@ -1081,7 +1162,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// Find the start of nested early scopes, e.g. in methods.
|
||||
let mut index = 0;
|
||||
if let Some(parent_id) = parent_id {
|
||||
let parent = self.hir_map.expect_item(parent_id);
|
||||
let parent = self.tcx.hir.expect_item(parent_id);
|
||||
if let hir::ItemTrait(..) = parent.node {
|
||||
index += 1; // Self comes first.
|
||||
}
|
||||
@ -1099,9 +1180,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
.iter()
|
||||
.map(|def| {
|
||||
if self.map.late_bound.contains(&def.lifetime.id) {
|
||||
Region::late(self.hir_map, def)
|
||||
Region::late(&self.tcx.hir, def)
|
||||
} else {
|
||||
Region::early(self.hir_map, &mut index, def)
|
||||
Region::early(&self.tcx.hir, &mut index, def)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -1182,8 +1263,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
if let Region::EarlyBound(..) = def {
|
||||
// Do not free early-bound regions, only late-bound ones.
|
||||
} else if let Some(body_id) = outermost_body {
|
||||
let fn_id = self.hir_map.body_owner(body_id);
|
||||
match self.hir_map.get(fn_id) {
|
||||
let fn_id = self.tcx.hir.body_owner(body_id);
|
||||
match self.tcx.hir.get(fn_id) {
|
||||
hir::map::NodeItem(&hir::Item {
|
||||
node: hir::ItemFn(..),
|
||||
..
|
||||
@ -1196,7 +1277,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
node: hir::ImplItemKind::Method(..),
|
||||
..
|
||||
}) => {
|
||||
let scope = self.hir_map.local_def_id(fn_id);
|
||||
let scope = self.tcx.hir.local_def_id(fn_id);
|
||||
def = Region::Free(scope, def.id().unwrap());
|
||||
}
|
||||
_ => {}
|
||||
@ -1209,7 +1290,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
Region::EarlyBound(_, _, LifetimeDefOrigin::InBand)
|
||||
| Region::LateBound(_, _, LifetimeDefOrigin::InBand) => {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
lifetime_ref.span,
|
||||
E0687,
|
||||
"lifetimes used in `fn` or `Fn` syntax must be \
|
||||
@ -1229,7 +1310,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
self.insert_lifetime(lifetime_ref, def);
|
||||
} else {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
lifetime_ref.span,
|
||||
E0261,
|
||||
"use of undeclared lifetime name `{}`",
|
||||
@ -1264,11 +1345,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// Figure out if this is a type/trait segment,
|
||||
// which requires object lifetime defaults.
|
||||
let parent_def_id = |this: &mut Self, def_id: DefId| {
|
||||
let def_key = if def_id.is_local() {
|
||||
this.hir_map.def_key(def_id)
|
||||
} else {
|
||||
this.cstore.def_key(def_id)
|
||||
};
|
||||
let def_key = this.tcx.def_key(def_id);
|
||||
DefId {
|
||||
krate: def_id.krate,
|
||||
index: def_key.parent.expect("missing parent"),
|
||||
@ -1307,18 +1384,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let map = &self.map;
|
||||
let unsubst = if let Some(id) = self.hir_map.as_local_node_id(def_id) {
|
||||
let unsubst = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||
&map.object_lifetime_defaults[&id]
|
||||
} else {
|
||||
let cstore = self.cstore;
|
||||
let sess = self.sess;
|
||||
let tcx = self.tcx;
|
||||
self.xcrate_object_lifetime_defaults
|
||||
.entry(def_id)
|
||||
.or_insert_with(|| {
|
||||
cstore
|
||||
.item_generics_cloned_untracked(def_id, sess)
|
||||
tcx.generics_of(def_id)
|
||||
.types
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|def| def.object_lifetime_default)
|
||||
.collect()
|
||||
})
|
||||
@ -1326,13 +1401,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
unsubst
|
||||
.iter()
|
||||
.map(|set| match *set {
|
||||
Set1::Empty => {
|
||||
if in_body {
|
||||
None
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
}
|
||||
}
|
||||
Set1::Empty => if in_body {
|
||||
None
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
},
|
||||
Set1::One(r) => r.subst(¶ms.lifetimes, map),
|
||||
Set1::Many => None,
|
||||
})
|
||||
@ -1387,8 +1460,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// and whether there's a `self` argument (treated specially).
|
||||
let mut assoc_item_kind = None;
|
||||
let mut impl_self = None;
|
||||
let parent = self.hir_map.get_parent_node(output.id);
|
||||
let body = match self.hir_map.get(parent) {
|
||||
let parent = self.tcx.hir.get_parent_node(output.id);
|
||||
let body = match self.tcx.hir.get(parent) {
|
||||
// `fn` definitions and methods.
|
||||
hir::map::NodeItem(&hir::Item {
|
||||
node: hir::ItemFn(.., body),
|
||||
@ -1399,8 +1472,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
node: hir::TraitItemKind::Method(_, ref m),
|
||||
..
|
||||
}) => {
|
||||
match self.hir_map
|
||||
.expect_item(self.hir_map.get_parent(parent))
|
||||
match self.tcx
|
||||
.hir
|
||||
.expect_item(self.tcx.hir.get_parent(parent))
|
||||
.node
|
||||
{
|
||||
hir::ItemTrait(.., ref trait_items) => {
|
||||
@ -1421,8 +1495,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
node: hir::ImplItemKind::Method(_, body),
|
||||
..
|
||||
}) => {
|
||||
match self.hir_map
|
||||
.expect_item(self.hir_map.get_parent(parent))
|
||||
match self.tcx
|
||||
.hir
|
||||
.expect_item(self.tcx.hir.get_parent(parent))
|
||||
.node
|
||||
{
|
||||
hir::ItemImpl(.., ref self_ty, ref impl_items) => {
|
||||
@ -1660,7 +1735,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0106,
|
||||
"missing lifetime specifier{}",
|
||||
@ -1706,8 +1781,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
} = info;
|
||||
|
||||
let help_name = if let Some(body) = parent {
|
||||
let arg = &self.hir_map.body(body).arguments[index];
|
||||
format!("`{}`", self.hir_map.node_to_pretty_string(arg.pat.id))
|
||||
let arg = &self.tcx.hir.body(body).arguments[index];
|
||||
format!("`{}`", self.tcx.hir.node_to_pretty_string(arg.pat.id))
|
||||
} else {
|
||||
format!("argument {}", index + 1)
|
||||
};
|
||||
@ -1802,7 +1877,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let lifetime = lifetime.lifetime;
|
||||
let name = lifetime.name.name();
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
lifetime.span,
|
||||
E0262,
|
||||
"invalid lifetime parameter name: `{}`",
|
||||
@ -1824,7 +1899,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
if lifetime_i.lifetime.name == lifetime_j.lifetime.name {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
lifetime_j.lifetime.span,
|
||||
E0263,
|
||||
"lifetime name `{}` declared twice in the same scope",
|
||||
@ -1842,7 +1917,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
match bound.name {
|
||||
hir::LifetimeName::Underscore => {
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
self.tcx.sess,
|
||||
bound.span,
|
||||
E0637,
|
||||
"invalid lifetime bound name: `'_`"
|
||||
@ -1852,7 +1927,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
hir::LifetimeName::Static => {
|
||||
self.insert_lifetime(bound, Region::Static);
|
||||
self.sess
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_warn(
|
||||
lifetime_i.lifetime.span.to(bound.span),
|
||||
&format!(
|
||||
@ -1880,7 +1956,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// FIXME (#24278): non-hygienic comparison
|
||||
if lifetime.name.name() == label {
|
||||
signal_shadowing_problem(
|
||||
self.sess,
|
||||
self.tcx,
|
||||
label,
|
||||
original_label(label_span),
|
||||
shadower_lifetime(&lifetime),
|
||||
@ -1907,12 +1983,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
next_early_index: _,
|
||||
} => {
|
||||
if let Some(&def) = lifetimes.get(&lifetime.name) {
|
||||
let node_id = self.hir_map.as_local_node_id(def.id().unwrap()).unwrap();
|
||||
let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
|
||||
|
||||
signal_shadowing_problem(
|
||||
self.sess,
|
||||
self.tcx,
|
||||
lifetime.name.name(),
|
||||
original_lifetime(self.hir_map.span(node_id)),
|
||||
original_lifetime(self.tcx.hir.span(node_id)),
|
||||
shadower_lifetime(&lifetime),
|
||||
);
|
||||
return;
|
||||
@ -1935,9 +2011,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
debug!(
|
||||
"insert_lifetime: {} resolved to {:?} span={:?}",
|
||||
self.hir_map.node_to_string(lifetime_ref.id),
|
||||
self.tcx.hir.node_to_string(lifetime_ref.id),
|
||||
def,
|
||||
self.sess.codemap().span_to_string(lifetime_ref.span)
|
||||
self.tcx.sess.codemap().span_to_string(lifetime_ref.span)
|
||||
);
|
||||
self.map.defs.insert(lifetime_ref.id, def);
|
||||
}
|
||||
@ -2007,13 +2083,13 @@ fn insert_late_bound_lifetimes(
|
||||
walk_list!(
|
||||
&mut appears_in_where_clause,
|
||||
visit_ty,
|
||||
decl.inputs.iter().filter(|ty| {
|
||||
if let hir::TyImplTraitUniversal(..) = ty.node {
|
||||
decl.inputs
|
||||
.iter()
|
||||
.filter(|ty| if let hir::TyImplTraitUniversal(..) = ty.node {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
})
|
||||
);
|
||||
for lifetime_def in &generics.lifetimes {
|
||||
if !lifetime_def.bounds.is_empty() {
|
||||
|
@ -802,8 +802,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||
/// Export map produced by name resolution.
|
||||
export_map: FxHashMap<DefId, Rc<Vec<Export>>>,
|
||||
|
||||
named_region_map: NamedRegionMap,
|
||||
|
||||
pub hir: hir_map::Map<'tcx>,
|
||||
|
||||
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
|
||||
@ -986,7 +984,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
arenas: &'tcx GlobalArenas<'tcx>,
|
||||
arena: &'tcx DroplessArena,
|
||||
resolutions: ty::Resolutions,
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
hir: hir_map::Map<'tcx>,
|
||||
on_disk_query_result_cache: maps::OnDiskCache<'tcx>,
|
||||
crate_name: &str,
|
||||
@ -1044,27 +1041,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
.insert(hir_id.local_id,
|
||||
Rc::new(StableVec::new(v)));
|
||||
}
|
||||
let mut defs = FxHashMap();
|
||||
for (k, v) in named_region_map.defs {
|
||||
let hir_id = hir.node_to_hir_id(k);
|
||||
let map = defs.entry(hir_id.owner)
|
||||
.or_insert_with(|| Rc::new(FxHashMap()));
|
||||
Rc::get_mut(map).unwrap().insert(hir_id.local_id, v);
|
||||
}
|
||||
let mut late_bound = FxHashMap();
|
||||
for k in named_region_map.late_bound {
|
||||
let hir_id = hir.node_to_hir_id(k);
|
||||
let map = late_bound.entry(hir_id.owner)
|
||||
.or_insert_with(|| Rc::new(FxHashSet()));
|
||||
Rc::get_mut(map).unwrap().insert(hir_id.local_id);
|
||||
}
|
||||
let mut object_lifetime_defaults = FxHashMap();
|
||||
for (k, v) in named_region_map.object_lifetime_defaults {
|
||||
let hir_id = hir.node_to_hir_id(k);
|
||||
let map = object_lifetime_defaults.entry(hir_id.owner)
|
||||
.or_insert_with(|| Rc::new(FxHashMap()));
|
||||
Rc::get_mut(map).unwrap().insert(hir_id.local_id, Rc::new(v));
|
||||
}
|
||||
|
||||
tls::enter_global(GlobalCtxt {
|
||||
sess: s,
|
||||
@ -1074,11 +1050,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
dep_graph: dep_graph.clone(),
|
||||
on_disk_query_result_cache,
|
||||
types: common_types,
|
||||
named_region_map: NamedRegionMap {
|
||||
defs,
|
||||
late_bound,
|
||||
object_lifetime_defaults,
|
||||
},
|
||||
trait_map,
|
||||
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
|
||||
(k, Rc::new(v))
|
||||
@ -2176,27 +2147,12 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
struct NamedRegionMap {
|
||||
defs: FxHashMap<DefIndex, Rc<FxHashMap<ItemLocalId, resolve_lifetime::Region>>>,
|
||||
late_bound: FxHashMap<DefIndex, Rc<FxHashSet<ItemLocalId>>>,
|
||||
object_lifetime_defaults:
|
||||
FxHashMap<
|
||||
DefIndex,
|
||||
Rc<FxHashMap<ItemLocalId, Rc<Vec<ObjectLifetimeDefault>>>>,
|
||||
>,
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||
// FIXME(#44234) - almost all of these queries have no sub-queries and
|
||||
// therefore no actual inputs, they're just reading tables calculated in
|
||||
// resolve! Does this work? Unsure! That's what the issue is about
|
||||
providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
|
||||
providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
|
||||
providers.named_region_map = |tcx, id| tcx.gcx.named_region_map.defs.get(&id).cloned();
|
||||
providers.is_late_bound_map = |tcx, id| tcx.gcx.named_region_map.late_bound.get(&id).cloned();
|
||||
providers.object_lifetime_defaults_map = |tcx, id| {
|
||||
tcx.gcx.named_region_map.object_lifetime_defaults.get(&id).cloned()
|
||||
};
|
||||
providers.crate_name = |tcx, id| {
|
||||
assert_eq!(id, LOCAL_CRATE);
|
||||
tcx.crate_name
|
||||
|
@ -443,6 +443,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
|
||||
format!("resolving lifetimes")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, _: DefIndex) -> String {
|
||||
format!("looking up a named region")
|
||||
|
@ -23,7 +23,7 @@ use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody};
|
||||
use middle::privacy::AccessLevels;
|
||||
use middle::reachable::ReachableSet;
|
||||
use middle::region;
|
||||
use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
|
||||
use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault};
|
||||
use middle::stability::{self, DeprecationEntry};
|
||||
use middle::lang_items::{LanguageItems, LangItem};
|
||||
use middle::exported_symbols::SymbolExportLevel;
|
||||
@ -306,6 +306,8 @@ define_maps! { <'tcx>
|
||||
-> Option<NativeLibraryKind>,
|
||||
[] fn link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
|
||||
|
||||
// Lifetime resolution. See `middle::resolve_lifetimes`.
|
||||
[] fn resolve_lifetimes: ResolveLifetimes(CrateNum) -> Rc<ResolveLifetimes>,
|
||||
[] fn named_region_map: NamedRegion(DefIndex) ->
|
||||
Option<Rc<FxHashMap<ItemLocalId, Region>>>,
|
||||
[] fn is_late_bound_map: IsLateBound(DefIndex) ->
|
||||
|
@ -875,6 +875,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
|
||||
DepKind::NativeLibraryKind => { force!(native_library_kind, def_id!()); }
|
||||
DepKind::LinkArgs => { force!(link_args, LOCAL_CRATE); }
|
||||
|
||||
DepKind::ResolveLifetimes => { force!(resolve_lifetimes, krate!()); }
|
||||
DepKind::NamedRegion => { force!(named_region_map, def_id!().index); }
|
||||
DepKind::IsLateBound => { force!(is_late_bound_map, def_id!().index); }
|
||||
DepKind::ObjectLifetimeDefaults => {
|
||||
|
@ -19,7 +19,7 @@ use rustc::session::CompileIncomplete;
|
||||
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
|
||||
use rustc::session::search_paths::PathKind;
|
||||
use rustc::lint;
|
||||
use rustc::middle::{self, stability, reachable};
|
||||
use rustc::middle::{self, stability, reachable, resolve_lifetime};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
|
||||
@ -928,6 +928,7 @@ pub fn default_provide(providers: &mut ty::maps::Providers) {
|
||||
borrowck::provide(providers);
|
||||
mir::provide(providers);
|
||||
reachable::provide(providers);
|
||||
resolve_lifetime::provide(providers);
|
||||
rustc_privacy::provide(providers);
|
||||
DefaultTransCrate::provide(providers);
|
||||
typeck::provide(providers);
|
||||
@ -984,10 +985,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController,
|
||||
"load query result cache",
|
||||
|| rustc_incremental::load_query_result_cache(sess));
|
||||
|
||||
let named_region_map = time(time_passes,
|
||||
"lifetime resolution",
|
||||
|| middle::resolve_lifetime::krate(sess, cstore, &hir_map))?;
|
||||
|
||||
time(time_passes,
|
||||
"looking for entry point",
|
||||
|| middle::entry::find_entry_point(sess, &hir_map));
|
||||
@ -1022,7 +1019,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController,
|
||||
arenas,
|
||||
arena,
|
||||
resolutions,
|
||||
named_region_map,
|
||||
hir_map,
|
||||
query_result_on_disk_cache,
|
||||
name,
|
||||
|
@ -18,7 +18,6 @@ use rustc_lint;
|
||||
use rustc_resolve::MakeGlobMap;
|
||||
use rustc_trans;
|
||||
use rustc::middle::region;
|
||||
use rustc::middle::resolve_lifetime;
|
||||
use rustc::ty::subst::{Kind, Subst};
|
||||
use rustc::traits::{ObligationCause, Reveal};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -137,7 +136,6 @@ fn test_env<F>(source_string: &str,
|
||||
let hir_map = hir_map::map_crate(&sess, &*cstore, &mut hir_forest, &defs);
|
||||
|
||||
// run just enough stuff to build a tcx:
|
||||
let named_region_map = resolve_lifetime::krate(&sess, &*cstore, &hir_map);
|
||||
let (tx, _rx) = mpsc::channel();
|
||||
let outputs = OutputFilenames {
|
||||
out_directory: PathBuf::new(),
|
||||
@ -153,7 +151,6 @@ fn test_env<F>(source_string: &str,
|
||||
&arenas,
|
||||
&arena,
|
||||
resolutions,
|
||||
named_region_map.unwrap(),
|
||||
hir_map,
|
||||
OnDiskCache::new_empty(sess.codemap()),
|
||||
"test_crate",
|
||||
|
@ -140,7 +140,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
}
|
||||
|
||||
None => {
|
||||
self.re_infer(lifetime.span, def).expect("unelided lifetime in signature")
|
||||
self.re_infer(lifetime.span, def)
|
||||
.unwrap_or_else(|| {
|
||||
// This indicates an illegal lifetime
|
||||
// elision. `resolve_lifetime` should have
|
||||
// reported an error in this case -- but if
|
||||
// not, let's error out.
|
||||
tcx.sess.delay_span_bug(lifetime.span, "unelided lifetime in signature");
|
||||
|
||||
// Supply some dummy value. We don't have an
|
||||
// `re_error`, annoyingly, so use `'static`.
|
||||
tcx.types.re_static
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that the `TypeckTables` nodes for impl items are independent from
|
||||
// one another.
|
||||
|
||||
// compile-flags: -Z query-dep-graph
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo {
|
||||
x: u8
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
// Changing the item `new`...
|
||||
#[rustc_if_this_changed(HirBody)]
|
||||
fn new() -> Foo {
|
||||
Foo { x: 0 }
|
||||
}
|
||||
|
||||
// ...should not cause us to recompute the tables for `with`!
|
||||
#[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path
|
||||
fn with(x: u8) -> Foo {
|
||||
Foo { x: x }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = Foo::new();
|
||||
let g = Foo::with(22);
|
||||
assert_eq!(f.x, g.x - 22);
|
||||
}
|
@ -8,8 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait Trait1 {}
|
||||
trait Trait2 {}
|
||||
trait Trait1<'a> {}
|
||||
trait Trait2<'a, 'b> {}
|
||||
|
||||
fn f() where
|
||||
for<'a> Trait1<'a>: Trait1<'a>, // OK
|
||||
|
@ -16,8 +16,9 @@
|
||||
// This was fixed by improving the resolution of the `FnOnce` trait
|
||||
// selection node.
|
||||
|
||||
// revisions:cfail1
|
||||
// revisions:cfail1 cfail2 cfail3
|
||||
// compile-flags:-Zquery-dep-graph
|
||||
// must-compile-successfully
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
@ -27,16 +28,24 @@ fn main() {
|
||||
}
|
||||
|
||||
mod a {
|
||||
#[rustc_if_this_changed(HirBody)]
|
||||
#[cfg(cfail1)]
|
||||
pub fn foo() {
|
||||
let x = vec![1, 2, 3];
|
||||
let v = || ::std::mem::drop(x);
|
||||
v();
|
||||
}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
pub fn foo() {
|
||||
let x = vec![1, 2, 3, 4];
|
||||
let v = || ::std::mem::drop(x);
|
||||
v();
|
||||
}
|
||||
}
|
||||
|
||||
mod b {
|
||||
#[rustc_then_this_would_need(TypeckTables)] //[cfail1]~ ERROR no path
|
||||
#[rustc_clean(cfg="cfail2")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn bar() {
|
||||
let x = vec![1, 2, 3];
|
||||
let v = || ::std::mem::drop(x);
|
||||
|
0
src/test/ui/print_type_sizes/anonymous.stderr
Normal file
0
src/test/ui/print_type_sizes/anonymous.stderr
Normal file
0
src/test/ui/print_type_sizes/anonymous.stdout
Normal file
0
src/test/ui/print_type_sizes/anonymous.stdout
Normal file
0
src/test/ui/print_type_sizes/multiple_types.stderr
Normal file
0
src/test/ui/print_type_sizes/multiple_types.stderr
Normal file
0
src/test/ui/print_type_sizes/packed.stderr
Normal file
0
src/test/ui/print_type_sizes/packed.stderr
Normal file
0
src/test/ui/print_type_sizes/repr-align.stderr
Normal file
0
src/test/ui/print_type_sizes/repr-align.stderr
Normal file
@ -23,6 +23,7 @@ trait Baz {
|
||||
impl<T> Baz for T where T: Foo {
|
||||
type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
|
||||
//~^ ERROR undeclared lifetime
|
||||
//~| ERROR lifetime parameters are not allowed on this type [E0110]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -4,5 +4,11 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
24 | type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0110]: lifetime parameters are not allowed on this type
|
||||
--> $DIR/construct_with_other_type.rs:24:37
|
||||
|
|
||||
24 | type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
|
||||
| ^^ lifetime parameter not allowed on this type
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,5 +4,5 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
34 | type WithDefault<'a, T> = &'a Iterator<T>;
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
error: cannot continue compilation due to previous error
|
||||
|
||||
|
@ -16,8 +16,10 @@ trait Iterable {
|
||||
type Item<'a>;
|
||||
type Iter<'a>: Iterator<Item = Self::Item<'a>>;
|
||||
//~^ ERROR undeclared lifetime
|
||||
//~| ERROR lifetime parameters are not allowed on this type [E0110]
|
||||
|
||||
fn iter<'a>(&'a self) -> Self::Iter<'a>;
|
||||
//~^ ERROR lifetime parameters are not allowed on this type [E0110]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -4,5 +4,17 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
17 | type Iter<'a>: Iterator<Item = Self::Item<'a>>;
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0110]: lifetime parameters are not allowed on this type
|
||||
--> $DIR/iterable.rs:17:47
|
||||
|
|
||||
17 | type Iter<'a>: Iterator<Item = Self::Item<'a>>;
|
||||
| ^^ lifetime parameter not allowed on this type
|
||||
|
||||
error[E0110]: lifetime parameters are not allowed on this type
|
||||
--> $DIR/iterable.rs:21:41
|
||||
|
|
||||
21 | fn iter<'a>(&'a self) -> Self::Iter<'a>;
|
||||
| ^^ lifetime parameter not allowed on this type
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user