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

[12/12] On-demand type-checking, const-evaluation, MIR building & const-qualification. #40008

Merged
merged 17 commits into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e8d01ea
rustc: store type parameter defaults outside of ty::Generics.
eddyb Jan 25, 2017
86e4029
rustc_typeck: simplify AstConv requests as implemented by collect.
eddyb Feb 2, 2017
e96a171
rustc: move the actual values of enum discriminants into a map.
eddyb Feb 5, 2017
cc8a3a9
rustc: consolidate dep-tracked hashmaps in tcx.maps.
eddyb Feb 7, 2017
b5c4244
rustc: introduce a query system for type information in ty::maps.
eddyb Sep 28, 2016
374ea14
rustc_mir: expose MIR building through ty::maps::Provider.
eddyb Feb 8, 2017
4649f73
rustc_typeck: lift CrateCtxt to TyCtxt.
eddyb Oct 3, 2016
28f1cf4
rustc_typeck: don't use Result for get_type_parameter_bounds and ensu…
eddyb Feb 11, 2017
91374f8
rustc: combine BareFnTy and ClosureTy into FnSig.
eddyb Feb 13, 2017
3146ee8
rustc: simplify tcx.closure_type(...) as it can copy the cached values.
eddyb Feb 13, 2017
9c3c306
rustc_typeck: move the leaves (generics, trait_def, adt_def) to on-de…
eddyb Feb 13, 2017
ba11640
rustc_typeck: hook up collect and item/body check to on-demand.
eddyb Feb 14, 2017
9890e04
rustc: allow handling cycle errors gracefully in on-demand.
eddyb Feb 19, 2017
c832e6f
rustc_typeck: rework coherence to be almost completely on-demand.
eddyb Feb 19, 2017
e7a4882
rustc_const_eval: always demand typeck_tables for evaluating constants.
eddyb Feb 15, 2017
d9f0a94
rustc_const_eval: demand that the MIR qualify_consts ran on each eval…
eddyb Feb 20, 2017
f702b20
rustc_save_analysis: don't pollute the codemap with fake files.
eddyb Jun 10, 2016
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
8 changes: 8 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub enum DepNode<D: Clone + Debug> {
Resolve,
EntryPoint,
CheckEntryFn,
CoherenceCheckTrait(D),
CoherenceCheckImpl(D),
CoherenceOverlapCheck(D),
CoherenceOverlapCheckSpecial(D),
Expand Down Expand Up @@ -109,11 +110,13 @@ pub enum DepNode<D: Clone + Debug> {
// predicates for an item wind up in `ItemSignature`).
AssociatedItems(D),
ItemSignature(D),
TypeParamPredicates((D, D)),
SizedConstraint(D),
AssociatedItemDefIds(D),
InherentImpls(D),
TypeckTables(D),
UsedTraitImports(D),
MonomorphicConstEval(D),

// The set of impls for a given trait. Ultimately, it would be
// nice to get more fine-grained here (e.g., to include a
Expand Down Expand Up @@ -239,6 +242,7 @@ impl<D: Clone + Debug> DepNode<D> {
MetaData(ref d) => op(d).map(MetaData),
CollectItem(ref d) => op(d).map(CollectItem),
CollectItemSig(ref d) => op(d).map(CollectItemSig),
CoherenceCheckTrait(ref d) => op(d).map(CoherenceCheckTrait),
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
Expand All @@ -258,11 +262,15 @@ impl<D: Clone + Debug> DepNode<D> {
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
AssociatedItems(ref d) => op(d).map(AssociatedItems),
ItemSignature(ref d) => op(d).map(ItemSignature),
TypeParamPredicates((ref item, ref param)) => {
Some(TypeParamPredicates((try_opt!(op(item)), try_opt!(op(param)))))
}
SizedConstraint(ref d) => op(d).map(SizedConstraint),
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
InherentImpls(ref d) => op(d).map(InherentImpls),
TypeckTables(ref d) => op(d).map(TypeckTables),
UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
MonomorphicConstEval(ref d) => op(d).map(MonomorphicConstEval),
TraitImpls(ref d) => op(d).map(TraitImpls),
TraitItems(ref d) => op(d).map(TraitItems),
ReprHints(ref d) => op(d).map(ReprHints),
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/dep_graph/dep_tracking_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use hir::def_id::DefId;
use rustc_data_structures::fx::FxHashMap;
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::ops::Index;
use std::hash::Hash;
use std::marker::PhantomData;
Expand Down Expand Up @@ -67,6 +68,11 @@ impl<M: DepTrackingMapConfig> DepTrackingMap<M> {
assert!(old_value.is_none());
}

pub fn entry(&mut self, k: M::Key) -> Entry<M::Key, M::Value> {
self.write(&k);
self.map.entry(k)
}

pub fn contains_key(&self, k: &M::Key) -> bool {
self.read(k);
self.map.contains_key(k)
Expand Down
90 changes: 17 additions & 73 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,44 +390,6 @@ RFC. It is, however, [currently unimplemented][iss15872].
[iss15872]: https://github.com/rust-lang/rust/issues/15872
"##,

E0109: r##"
You tried to give a type parameter to a type which doesn't need it. Erroneous
code example:

```compile_fail,E0109
type X = u32<i32>; // error: type parameters are not allowed on this type
```

Please check that you used the correct type and recheck its definition. Perhaps
it doesn't need the type parameter.

Example:

```
type X = u32; // this compiles
```

Note that type parameters for enum-variant constructors go after the variant,
not after the enum (Option::None::<u32>, not Option::<u32>::None).
"##,

E0110: r##"
You tried to give a lifetime parameter to a type which doesn't need it.
Erroneous code example:

```compile_fail,E0110
type X = u32<'static>; // error: lifetime parameters are not allowed on
// this type
```

Please check that the correct type was used and recheck its definition; perhaps
it doesn't need the lifetime parameter. Example:

```
type X = u32; // ok!
```
"##,

E0133: r##"
Unsafe code was used outside of an unsafe function or block.

Expand Down Expand Up @@ -627,41 +589,6 @@ attributes:
See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0229: r##"
An associated type binding was done outside of the type parameter declaration
and `where` clause. Erroneous code example:

```compile_fail,E0229
pub trait Foo {
type A;
fn boo(&self) -> <Self as Foo>::A;
}

struct Bar;

impl Foo for isize {
type A = usize;
fn boo(&self) -> usize { 42 }
}

fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
// error: associated type bindings are not allowed here
```

To solve this error, please move the type bindings in the type parameter
declaration:

```ignore
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
```

Or in the `where` clause:

```ignore
fn baz<I>(x: &<I as Foo>::A) where I: Foo<A=Bar> {}
```
"##,

E0261: r##"
When using a lifetime like `'a` in a type, it must be declared before being
used.
Expand Down Expand Up @@ -1390,6 +1317,23 @@ error. To resolve it, add an `else` block having the same type as the `if`
block.
"##,

E0391: r##"
This error indicates that some types or traits depend on each other
and therefore cannot be constructed.

The following example contains a circular dependency between two traits:

```compile_fail,E0391
trait FirstTrait : SecondTrait {

}

trait SecondTrait : FirstTrait {

}
```
"##,

E0398: r##"
In Rust 1.3, the default object lifetime bounds are expected to change, as
described in RFC #1156 [1]. You are getting a warning because the compiler
Expand Down
24 changes: 22 additions & 2 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pub struct LoweringContext<'a> {
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
bodies: FxHashMap<hir::BodyId, hir::Body>,

trait_impls: BTreeMap<DefId, Vec<NodeId>>,
trait_default_impl: BTreeMap<DefId, NodeId>,

loop_scopes: Vec<NodeId>,
is_in_loop_condition: bool,

Expand Down Expand Up @@ -116,6 +119,8 @@ pub fn lower_crate(sess: &Session,
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
bodies: FxHashMap(),
trait_impls: BTreeMap::new(),
trait_default_impl: BTreeMap::new(),
loop_scopes: Vec::new(),
is_in_loop_condition: false,
type_def_lifetime_params: DefIdMap(),
Expand Down Expand Up @@ -201,6 +206,8 @@ impl<'a> LoweringContext<'a> {
trait_items: self.trait_items,
impl_items: self.impl_items,
bodies: self.bodies,
trait_impls: self.trait_impls,
trait_default_impl: self.trait_default_impl,
}
}

Expand Down Expand Up @@ -525,7 +532,7 @@ impl<'a> LoweringContext<'a> {
return n;
}
assert!(!def_id.is_local());
let (n, _) = self.sess.cstore.item_generics_own_param_counts(def_id);
let n = self.sess.cstore.item_generics_cloned(def_id).regions.len();
self.type_def_lifetime_params.insert(def_id, n);
n
});
Expand Down Expand Up @@ -1089,14 +1096,27 @@ impl<'a> LoweringContext<'a> {
hir::ItemUnion(vdata, self.lower_generics(generics))
}
ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
let trait_ref = self.lower_trait_ref(trait_ref);

if let Def::Trait(def_id) = trait_ref.path.def {
self.trait_default_impl.insert(def_id, id);
}

hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
self.lower_trait_ref(trait_ref))
trait_ref)
}
ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
let new_impl_items = impl_items.iter()
.map(|item| self.lower_impl_item_ref(item))
.collect();
let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));

if let Some(ref trait_ref) = ifce {
if let Def::Trait(def_id) = trait_ref.path.def {
self.trait_impls.entry(def_id).or_insert(vec![]).push(id);
}
}

hir::ItemImpl(self.lower_unsafety(unsafety),
self.lower_impl_polarity(polarity),
self.lower_generics(generics),
Expand Down
44 changes: 44 additions & 0 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,50 @@ impl<'hir> Map<'hir> {
self.local_def_id(self.body_owner(id))
}

pub fn ty_param_owner(&self, id: NodeId) -> NodeId {
match self.get(id) {
NodeItem(&Item { node: ItemTrait(..), .. }) => id,
NodeTyParam(_) => self.get_parent_node(id),
_ => {
bug!("ty_param_owner: {} not a type parameter",
self.node_to_string(id))
}
}
}

pub fn ty_param_name(&self, id: NodeId) -> Name {
match self.get(id) {
NodeItem(&Item { node: ItemTrait(..), .. }) => {
keywords::SelfType.name()
}
NodeTyParam(tp) => tp.name,
_ => {
bug!("ty_param_name: {} not a type parameter",
self.node_to_string(id))
}
}
}

pub fn trait_impls(&self, trait_did: DefId) -> &'hir [NodeId] {
self.dep_graph.read(DepNode::TraitImpls(trait_did));

// NB: intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
self.forest.krate.trait_impls.get(&trait_did).map_or(&[], |xs| &xs[..])
}

pub fn trait_default_impl(&self, trait_did: DefId) -> Option<NodeId> {
self.dep_graph.read(DepNode::TraitImpls(trait_did));

// NB: intentionally bypass `self.forest.krate()` so that we
// do not trigger a read of the whole krate here
self.forest.krate.trait_default_impl.get(&trait_did).cloned()
}

pub fn trait_is_auto(&self, trait_did: DefId) -> bool {
self.trait_default_impl(trait_did).is_some()
}

/// Get the attributes on the krate. This is preferable to
/// invoking `krate.attrs` because it registers a tighter
/// dep-graph access.
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ pub struct Crate {
pub trait_items: BTreeMap<TraitItemId, TraitItem>,
pub impl_items: BTreeMap<ImplItemId, ImplItem>,
pub bodies: FxHashMap<BodyId, Body>,

pub trait_impls: BTreeMap<DefId, Vec<NodeId>>,
pub trait_default_impl: BTreeMap<DefId, NodeId>,
}

impl Crate {
Expand Down
31 changes: 15 additions & 16 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
evaluation_cache: traits::EvaluationCache::new(),
projection_cache: RefCell::new(traits::ProjectionCache::new()),
reported_trait_errors: RefCell::new(FxHashSet()),
projection_mode: Reveal::NotSpecializable,
projection_mode: Reveal::UserFacing,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count(),
obligations_in_snapshot: Cell::new(false),
Expand Down Expand Up @@ -600,7 +600,7 @@ impl_trans_normalize!('gcx,
Ty<'gcx>,
&'gcx Substs<'gcx>,
ty::FnSig<'gcx>,
&'gcx ty::BareFnTy<'gcx>,
ty::PolyFnSig<'gcx>,
ty::ClosureSubsts<'gcx>,
ty::PolyTraitRef<'gcx>,
ty::ExistentialTraitRef<'gcx>
Expand Down Expand Up @@ -1197,16 +1197,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// as the substitutions for the default, `(T, U)`.
pub fn type_var_for_def(&self,
span: Span,
def: &ty::TypeParameterDef<'tcx>,
def: &ty::TypeParameterDef,
substs: &[Kind<'tcx>])
-> Ty<'tcx> {
let default = def.default.map(|default| {
type_variable::Default {
let default = if def.has_default {
let default = self.tcx.item_type(def.def_id);
Copy link
Contributor

Choose a reason for hiding this comment

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

Man, we really need to document all the things that can have def-ids and what each table means for each kind of thing. Is this written down anywhere? I guess not.

Some(type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
def_id: def.default_def_id
}
});
def_id: def.def_id
})
} else {
None
};


let ty_var_id = self.type_variables
Expand Down Expand Up @@ -1646,20 +1649,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
Some(self.tcx.closure_kind(def_id))
}

pub fn closure_type(&self,
def_id: DefId,
substs: ty::ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx>
{
pub fn closure_type(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
if let InferTables::InProgress(tables) = self.tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
if let Some(ty) = tables.borrow().closure_tys.get(&id) {
return ty.subst(self.tcx, substs.substs);
if let Some(&ty) = tables.borrow().closure_tys.get(&id) {
return ty;
}
}
}

self.tcx.closure_type(def_id, substs)
self.tcx.closure_type(def_id)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(slice_patterns)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(unboxed_closures)]

Expand Down Expand Up @@ -75,7 +76,6 @@ pub mod infer;
pub mod lint;

pub mod middle {
pub mod astconv_util;
pub mod expr_use_visitor;
pub mod const_val;
pub mod cstore;
Expand Down
Loading