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

Ak 44493 infer predicate #45298

Merged
merged 1 commit into from
Apr 13, 2018
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ __pycache__/
/src/libstd_unicode/UnicodeData.txt
/stage[0-9]+/
/target
target/
/test/
/tmp/
TAGS
Expand Down
1 change: 1 addition & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ define_dep_nodes!( <'tcx>
[] GenericsOfItem(DefId),
[] PredicatesOfItem(DefId),
[] InferredOutlivesOf(DefId),
[] InferredOutlivesCrate(CrateNum),
[] SuperPredicatesOfItem(DefId),
[] TraitDefOfItem(DefId),
[] AdtDefOfItem(DefId),
Expand Down
14 changes: 14 additions & 0 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,20 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::CrateVariancesMap {
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::CratePredicatesMap<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
let ty::CratePredicatesMap {
ref predicates,
// This is just an irrelevant helper value.
empty_predicate: _,
} = *self;

predicates.hash_stable(hcx, hasher);
}
}

impl_stable_hash_for!(struct ty::AssociatedItem {
def_id,
name,
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/maps/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("computing the inferred outlives predicates for items in this crate")
}
}

impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
format!("generating MIR shim for `{}`",
Expand Down
7 changes: 6 additions & 1 deletion src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ define_maps! { <'tcx>
/// associated generics and predicates.
[] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
[] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
[] fn explicit_predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,

/// Maps from the def-id of a trait to the list of
/// super-predicates. This is a subset of the full list of
Expand Down Expand Up @@ -139,7 +140,11 @@ define_maps! { <'tcx>
[] fn variances_of: ItemVariances(DefId) -> Lrc<Vec<ty::Variance>>,

/// Maps from def-id of a type to its (inferred) outlives.
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Vec<ty::Predicate<'tcx>>,
[] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc<Vec<ty::Predicate<'tcx>>>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the Lrc is causing the error if executed with parallel on. Need to update the outlives code to return an Lrc rather than a Rc

Copy link
Contributor

Choose a reason for hiding this comment

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

sounds right


/// Maps from def-id of a type to its (inferred) outlives.
[] fn inferred_outlives_crate: InferredOutlivesCrate(CrateNum)
-> Lrc<ty::CratePredicatesMap<'tcx>>,

/// Maps from an impl/trait def-id to a list of the def-ids of its items
[] fn associated_item_def_ids: AssociatedItemDefIds(DefId) -> Lrc<Vec<DefId>>,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
DepKind::TraitDefOfItem => { force!(trait_def, def_id!()); }
DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
Expand Down
16 changes: 16 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,22 @@ pub enum Predicate<'tcx> {
ConstEvaluatable(DefId, &'tcx Substs<'tcx>),
}

/// The crate outlives map is computed during typeck and contains the
/// outlives of every item in the local crate. You should not use it
/// directly, because to do so will make your pass dependent on the
/// HIR of every item in the local crate. Instead, use
/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
/// item.
pub struct CratePredicatesMap<'tcx> {
/// For each struct with outlive bounds, maps to a vector of the
/// predicate of its outlive bounds. If an item has no outlives
/// bounds, it will have no entry.
pub predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,

/// An empty vector, useful for cloning.
pub empty_predicate: Lrc<Vec<ty::Predicate<'tcx>>>,
}

impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
fn as_ref(&self) -> &Predicate<'tcx> {
self
Expand Down
9 changes: 7 additions & 2 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub fn provide(providers: &mut Providers) {
type_of,
generics_of,
predicates_of,
explicit_predicates_of,
super_predicates_of,
type_param_predicates,
trait_def,
Expand Down Expand Up @@ -1296,13 +1297,17 @@ fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ty::GenericPredicates<'tcx> {
let explicit = explicit_predicates_of(tcx, def_id);
let predicates = if tcx.sess.features_untracked().infer_outlives_requirements {
[&explicit.predicates[..], &tcx.inferred_outlives_of(def_id)[..]].concat()
} else { explicit.predicates };

ty::GenericPredicates {
parent: explicit.parent,
predicates: [&explicit.predicates[..], &tcx.inferred_outlives_of(def_id)[..]].concat()
predicates: predicates,
}
}

fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ty::GenericPredicates<'tcx> {
use rustc::hir::map::*;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4840,11 +4840,11 @@ register_diagnostics! {
E0588, // packed type cannot transitively contain a `[repr(align)]` type
E0592, // duplicate definitions with name `{}`
// E0613, // Removed (merged with E0609)
E0640, // infer outlives
E0627, // yield statement outside of generator literal
E0632, // cannot provide explicit type parameters when `impl Trait` is used in
// argument position.
E0634, // type has conflicting packed representaton hints
E0640, // infer outlives requirements
E0641, // cannot cast to/from a pointer with an unknown kind
E0645, // trait aliases not finished
E0907, // type inside generator must be known in this context
Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ This API is completely unstable and subject to change.
#![feature(slice_patterns)]
#![feature(slice_sort_by_cached_key)]
#![feature(dyn_trait)]
#![feature(underscore_lifetimes)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
Expand Down
82 changes: 82 additions & 0 deletions src/librustc_typeck/outlives/explicit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2013 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.

use hir::map as hir_map;
use rustc::hir;
use rustc::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::maps::Providers;
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_data_structures::sync::Lrc;
use util::nodemap::FxHashMap;

pub fn explicit_predicates<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
crate_num: CrateNum,
) -> FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>> {
assert_eq!(crate_num, LOCAL_CRATE);
let mut predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>> = FxHashMap();

// iterate over the entire crate
tcx.hir.krate().visit_all_item_likes(&mut ExplicitVisitor {
tcx: tcx,
explicit_predicates: &mut predicates,
crate_num: crate_num,
});

predicates
}

pub struct ExplicitVisitor<'cx, 'tcx: 'cx> {
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
explicit_predicates: &'cx mut FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,
crate_num: CrateNum,
}

impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for ExplicitVisitor<'cx, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) {
let def_id = DefId {
krate: self.crate_num,
index: item.hir_id.owner,
};

let local_explicit_predicate = self.tcx.explicit_predicates_of(def_id);

let filtered_predicates = local_explicit_predicate
.predicates
.into_iter()
.filter(|pred| match pred {
ty::Predicate::TypeOutlives(..) | ty::Predicate::RegionOutlives(..) => true,

ty::Predicate::Trait(..)
| ty::Predicate::Projection(..)
| ty::Predicate::WellFormed(..)
| ty::Predicate::ObjectSafe(..)
| ty::Predicate::ClosureKind(..)
| ty::Predicate::Subtype(..)
| ty::Predicate::ConstEvaluatable(..) => false,
})
.collect();

match item.node {
hir::ItemStruct(..) | hir::ItemEnum(..) => {
self.tcx.adt_def(def_id);
}
_ => {}
}

self.explicit_predicates
.insert(def_id, Lrc::new(filtered_predicates));
}

fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {}

fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {}
}
52 changes: 52 additions & 0 deletions src/librustc_typeck/outlives/implicit_empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2013 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.

use hir::map as hir_map;
use rustc::hir;
use rustc::hir::def_id::{self, CrateNum, DefId, LOCAL_CRATE};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::maps::Providers;
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_data_structures::sync::Lrc;
use util::nodemap::FxHashMap;

// Create the sets of inferred predicates for each type. These sets
// are initially empty but will grow during the inference step.
pub fn empty_predicate_map<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
) -> FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>> {
let mut predicates = FxHashMap();

// iterate over the entire crate
tcx.hir
.krate()
.visit_all_item_likes(&mut EmptyImplicitVisitor {
tcx,
predicates: &mut predicates,
});

predicates
}

pub struct EmptyImplicitVisitor<'cx, 'tcx: 'cx> {
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
predicates: &'cx mut FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,
}

impl<'a, 'p, 'v> ItemLikeVisitor<'v> for EmptyImplicitVisitor<'a, 'p> {
fn visit_item(&mut self, item: &hir::Item) {
self.predicates
.insert(self.tcx.hir.local_def_id(item.id), Lrc::new(Vec::new()));
}

fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {}

fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {}
}
Loading