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

Rollup of 8 pull requests #65771

Merged
merged 31 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
600607f
Move `search_for_adt_without_structural_match` to `ty/mod`
varkor Oct 20, 2019
bbd53de
Forbid non-`structural_match` types in const generics
varkor Oct 20, 2019
133cd2c
Search for generic parameters when finding non-`structural_match` types
varkor Oct 20, 2019
f0e6cd9
Remove "type parameter depends on const parameter" error from resolution
varkor Oct 20, 2019
9f788f3
Fix rustdoc const generics test
varkor Oct 21, 2019
7f13a4a
Remove FIXME
varkor Oct 22, 2019
2dda8ad
Use E0741 for structural match error
varkor Oct 22, 2019
fe3dc31
Update cargo
ehuss Oct 22, 2019
eb6d757
UI failures fix
Oct 21, 2019
8467cef
Tweak format string error to point at arguments always
estebank Oct 24, 2019
18d873e
Avoid ICE when adjusting bad self ty
estebank Oct 24, 2019
060b6cb
Update hashbrown to 0.6.2
alexcrichton Oct 24, 2019
184a61f
Don't assert for different instance on impl trait alias
csmoe Oct 24, 2019
2c16f84
rustc_driver: Remove unnecessary use of crate store
petrochenkov Oct 16, 2019
2cda75c
rustc_metadata: Remove unnecessary use of crate store in plugin loader
petrochenkov Oct 16, 2019
175d325
rustc_metadata: Move some code around
petrochenkov Oct 17, 2019
222503a
rustc: Add a convenience alias for `dyn MetadataLoader + Sync`
petrochenkov Oct 17, 2019
fb353f0
resolve: Privatize all resolver fields
petrochenkov Oct 19, 2019
5fd796a
rustc: Combine resolver outputs into a single struct
petrochenkov Oct 20, 2019
3534ca8
Turn crate store into a resolver output
petrochenkov Oct 20, 2019
c5fee33
rustc_metadata: Remove `RwLock` from `CStore`
petrochenkov Oct 20, 2019
9f5a530
rustc_metadata: Minimize use of `Lrc` in crate store
petrochenkov Oct 20, 2019
94216ce
rustc_interface: Remove `ExpansionResult` and some `Steal`s
petrochenkov Oct 21, 2019
cdb7634
Rollup merge of #65625 - petrochenkov:cstore, r=Mark-Simulacrum,Zoxc
Centril Oct 24, 2019
9c04bd1
Rollup merge of #65627 - varkor:const-generics-forbid-non-structural_…
Centril Oct 24, 2019
0da94a4
Rollup merge of #65710 - ehuss:update-cargo, r=alexcrichton
Centril Oct 24, 2019
efa5037
Rollup merge of #65729 - Wind-River:master_003, r=alexcrichton
Centril Oct 24, 2019
1e4a2ee
Rollup merge of #65746 - estebank:newcomer-format, r=Centril
Centril Oct 24, 2019
1b03671
Rollup merge of #65753 - csmoe:derive_fold, r=Centril
Centril Oct 24, 2019
7b3896f
Rollup merge of #65755 - estebank:icicle, r=davidtwco
Centril Oct 24, 2019
fd6795b
Rollup merge of #65766 - alexcrichton:less-inline-hashbrown, r=Mark-S…
Centril Oct 24, 2019
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
6 changes: 3 additions & 3 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1297,9 +1297,9 @@ dependencies = [

[[package]]
name = "hashbrown"
version = "0.6.1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a"
checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab"
dependencies = [
"autocfg",
"compiler_builtins",
Expand Down Expand Up @@ -4146,7 +4146,7 @@ dependencies = [
"core",
"dlmalloc",
"fortanix-sgx-abi",
"hashbrown 0.6.1",
"hashbrown 0.6.2",
"libc",
"panic_abort",
"panic_unwind",
Expand Down
12 changes: 5 additions & 7 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ pub struct LoweringContext<'a> {
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
sess: &'a Session,

cstore: &'a dyn CrateStore,

resolver: &'a mut dyn Resolver,

/// HACK(Centril): there is a cyclic dependency between the parser and lowering
Expand Down Expand Up @@ -160,6 +158,8 @@ pub struct LoweringContext<'a> {
}

pub trait Resolver {
fn cstore(&self) -> &dyn CrateStore;

/// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;

Expand Down Expand Up @@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> {

pub fn lower_crate(
sess: &Session,
cstore: &dyn CrateStore,
dep_graph: &DepGraph,
krate: &Crate,
resolver: &mut dyn Resolver,
Expand All @@ -256,7 +255,6 @@ pub fn lower_crate(
LoweringContext {
crate_root: sess.parse_sess.injected_crate_name.try_get().copied(),
sess,
cstore,
resolver,
nt_to_tokenstream,
items: BTreeMap::new(),
Expand Down Expand Up @@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> {
if id.is_local() {
self.resolver.definitions().def_key(id.index)
} else {
self.cstore.def_key(id)
self.resolver.cstore().def_key(id)
}
}

Expand Down Expand Up @@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> {
return n;
}
assert!(!def_id.is_local());
let item_generics =
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
let item_generics = self.resolver.cstore()
.item_generics_cloned_untracked(def_id, self.sess);
let n = item_generics.own_counts().lifetimes;
self.type_def_lifetime_params.insert(def_id, n);
n
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use syntax::ast;
use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_target::spec::Target;
use rustc_data_structures::sync::{self, MetadataRef, Lrc};
use rustc_data_structures::sync::{self, MetadataRef};
use rustc_macros::HashStable;

pub use self::NativeLibraryKind::*;
Expand Down Expand Up @@ -191,6 +191,8 @@ pub trait MetadataLoader {
-> Result<MetadataRef, String>;
}

pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;

/// A store of Rust crates, through which their metadata can be accessed.
///
/// Note that this trait should probably not be expanding today. All new
Expand All @@ -201,13 +203,13 @@ pub trait MetadataLoader {
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
/// during resolve)
pub trait CrateStore {
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any>;
fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any;

// resolve
fn def_key(&self, def: DefId) -> DefKey;
fn def_path(&self, def: DefId) -> hir_map::DefPath;
fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
fn def_path_table(&self, cnum: CrateNum) -> Lrc<DefPathTable>;
fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable;

// "queries" used in resolve that aren't tracked for incremental compilation
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
Expand Down
31 changes: 12 additions & 19 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ pub struct GlobalCtxt<'tcx> {

interners: CtxtInterners<'tcx>,

cstore: &'tcx CrateStoreDyn,
cstore: Box<CrateStoreDyn>,

pub sess: &'tcx Session,

Expand Down Expand Up @@ -1195,11 +1195,10 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn create_global_ctxt(
s: &'tcx Session,
lint_store: Lrc<lint::LintStore>,
cstore: &'tcx CrateStoreDyn,
local_providers: ty::query::Providers<'tcx>,
extern_providers: ty::query::Providers<'tcx>,
arenas: &'tcx AllArenas,
resolutions: ty::Resolutions,
resolutions: ty::ResolverOutputs,
hir: hir_map::Map<'tcx>,
on_disk_query_result_cache: query::OnDiskCache<'tcx>,
crate_name: &str,
Expand All @@ -1213,34 +1212,28 @@ impl<'tcx> TyCtxt<'tcx> {
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
let dep_graph = hir.dep_graph.clone();
let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
let cstore = resolutions.cstore;
let crates = cstore.crates_untracked();
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;

let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore
.crates_untracked()
let def_path_tables = crates
.iter()
.map(|&cnum| (cnum, cstore.def_path_table(cnum)))
.collect();

let def_path_tables = || {
upstream_def_path_tables
.iter()
.map(|&(cnum, ref rc)| (cnum, &**rc))
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())))
};
.chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table())));

// Precompute the capacity of the hashmap so we don't have to
// re-allocate when populating it.
let capacity = def_path_tables().map(|(_, t)| t.size()).sum::<usize>();
let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::<usize>();

let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher(
capacity,
::std::default::Default::default()
);

for (cnum, def_path_table) in def_path_tables() {
for (cnum, def_path_table) in def_path_tables {
def_path_table.add_def_path_hashes_to(cnum, &mut map);
}

Expand Down Expand Up @@ -1417,8 +1410,8 @@ impl<'tcx> TyCtxt<'tcx> {

// Note that this is *untracked* and should only be used within the query
// system if the result is otherwise tracked through queries
pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
self.cstore.crate_data_as_rc_any(cnum)
pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any {
self.cstore.crate_data_as_any(cnum)
}

#[inline(always)]
Expand All @@ -1428,7 +1421,7 @@ impl<'tcx> TyCtxt<'tcx> {
StableHashingContext::new(self.sess,
krate,
self.hir().definitions(),
self.cstore)
&*self.cstore)
}

// This method makes sure that we have a DepNode and a Fingerprint for
Expand Down
133 changes: 129 additions & 4 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub use self::Variance::*;
pub use self::AssocItemContainer::*;
pub use self::BorrowKind::*;
pub use self::IntVarValue::*;
pub use self::fold::TypeFoldable;
pub use self::fold::{TypeFoldable, TypeVisitor};

use crate::hir::{map as hir_map, GlobMap, TraitMap};
use crate::hir::Node;
Expand All @@ -15,6 +15,7 @@ use rustc_macros::HashStable;
use crate::ich::Fingerprint;
use crate::ich::StableHashingContext;
use crate::infer::canonical::Canonical;
use crate::middle::cstore::CrateStoreDyn;
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::mir::Body;
Expand Down Expand Up @@ -50,7 +51,7 @@ use syntax::symbol::{kw, sym, Symbol};
use syntax_pos::Span;

use smallvec;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_index::vec::{Idx, IndexVec};

Expand Down Expand Up @@ -119,8 +120,9 @@ mod sty;

// Data types

#[derive(Clone)]
pub struct Resolutions {
pub struct ResolverOutputs {
pub definitions: hir_map::Definitions,
pub cstore: Box<CrateStoreDyn>,
pub extern_crate_map: NodeMap<CrateNum>,
pub trait_map: TraitMap,
pub maybe_unused_trait_imports: NodeSet,
Expand Down Expand Up @@ -3393,6 +3395,129 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
fn_like.asyncness()
}

pub enum NonStructuralMatchTy<'tcx> {
Adt(&'tcx AdtDef),
Param,
}

/// This method traverses the structure of `ty`, trying to find an
/// instance of an ADT (i.e. struct or enum) that was declared without
/// the `#[structural_match]` attribute, or a generic type parameter
/// (which cannot be determined to be `structural_match`).
///
/// The "structure of a type" includes all components that would be
/// considered when doing a pattern match on a constant of that
/// type.
///
/// * This means this method descends into fields of structs/enums,
/// and also descends into the inner type `T` of `&T` and `&mut T`
///
/// * The traversal doesn't dereference unsafe pointers (`*const T`,
/// `*mut T`), and it does not visit the type arguments of an
/// instantiated generic like `PhantomData<T>`.
///
/// The reason we do this search is Rust currently require all ADTs
/// reachable from a constant's type to be annotated with
/// `#[structural_match]`, an attribute which essentially says that
/// the implementation of `PartialEq::eq` behaves *equivalently* to a
/// comparison against the unfolded structure.
///
/// For more background on why Rust has this requirement, and issues
/// that arose when the requirement was not enforced completely, see
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
pub fn search_for_structural_match_violation<'tcx>(
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<NonStructuralMatchTy<'tcx>> {
let mut search = Search { tcx, found: None, seen: FxHashSet::default() };
ty.visit_with(&mut search);
return search.found;

struct Search<'tcx> {
tcx: TyCtxt<'tcx>,

// Records the first ADT or type parameter we find without `#[structural_match`.
found: Option<NonStructuralMatchTy<'tcx>>,

// Tracks ADTs previously encountered during search, so that
// we will not recurse on them again.
seen: FxHashSet<hir::def_id::DefId>,
}

impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
debug!("Search visiting ty: {:?}", ty);

let (adt_def, substs) = match ty.kind {
ty::Adt(adt_def, substs) => (adt_def, substs),
ty::Param(_) => {
self.found = Some(NonStructuralMatchTy::Param);
return true; // Stop visiting.
}
ty::RawPtr(..) => {
// `#[structural_match]` ignores substructure of
// `*const _`/`*mut _`, so skip super_visit_with
//
// (But still tell caller to continue search.)
return false;
}
ty::FnDef(..) | ty::FnPtr(..) => {
// types of formals and return in `fn(_) -> _` are also irrelevant
//
// (But still tell caller to continue search.)
return false;
}
ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0)
=> {
// rust-lang/rust#62336: ignore type of contents
// for empty array.
return false;
}
_ => {
ty.super_visit_with(self);
return false;
}
};

if !self.tcx.has_attr(adt_def.did, sym::structural_match) {
self.found = Some(NonStructuralMatchTy::Adt(&adt_def));
debug!("Search found adt_def: {:?}", adt_def);
return true; // Stop visiting.
}

if !self.seen.insert(adt_def.did) {
debug!("Search already seen adt_def: {:?}", adt_def);
// let caller continue its search
return false;
}

// `#[structural_match]` does not care about the
// instantiation of the generics in an ADT (it
// instead looks directly at its fields outside
// this match), so we skip super_visit_with.
//
// (Must not recur on substs for `PhantomData<T>` cf
// rust-lang/rust#55028 and rust-lang/rust#55837; but also
// want to skip substs when only uses of generic are
// behind unsafe pointers `*const T`/`*mut T`.)

// even though we skip super_visit_with, we must recur on
// fields of ADT.
let tcx = self.tcx;
for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) {
if field_ty.visit_with(self) {
// found an ADT without `#[structural_match]`; halt visiting!
assert!(self.found.is_some());
return true;
}
}

// Even though we do not want to recur on substs, we do
// want our caller to continue its own search.
false
}
}
}

pub fn provide(providers: &mut ty::query::Providers<'_>) {
context::provide(providers);
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
x.val
};

// Currently, the values that can be unified are those that
// implement both `PartialEq` and `Eq`, corresponding to
// `structural_match` types.
// FIXME(const_generics): check for `structural_match` synthetic attribute.
// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
// to `structural_match` types.
let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) {
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
// The caller should handle these cases!
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use std::sync::Arc;
use std::ffi::CStr;

use rustc::dep_graph::DepGraph;
use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
use rustc::session::Session;
use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel};
use rustc::ty::{self, TyCtxt};
Expand Down Expand Up @@ -260,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend {
target_features(sess)
}

fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
box metadata::LlvmMetadataLoader
}

Expand Down
Loading