Skip to content

Commit

Permalink
Auto merge of rust-lang#65771 - Centril:rollup-upfsvrb, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - rust-lang#65625 (Turn crate store into a resolver output)
 - rust-lang#65627 (Forbid non-`structural_match` types in const generics)
 - rust-lang#65710 (Update cargo)
 - rust-lang#65729 (Update test cases for vxWorks)
 - rust-lang#65746 (Tweak format string error to point at arguments always)
 - rust-lang#65753 (Don't assert for different instance on impl trait alias)
 - rust-lang#65755 (Avoid ICE when adjusting bad self ty)
 - rust-lang#65766 (Update hashbrown to 0.6.2)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Oct 25, 2019
2 parents 10a52c2 + fd6795b commit d54111a
Show file tree
Hide file tree
Showing 51 changed files with 719 additions and 642 deletions.
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

0 comments on commit d54111a

Please sign in to comment.