Auto merge of #46657 - nikomatsakis:resolve-lifetimes-query, r=arielb1
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. r? @michaelwoerister
This commit is contained in:
commit
5951f8d1ba
|
@ -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 {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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