use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use ty::subst::{CanonicalUserSubsts, Subst, Substs};
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
+use ty::layout::VariantIdx;
use util::ppaux;
pub use mir::interpret::AssertMessage;
pub kind: StatementKind<'tcx>,
}
+ // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
+ #[cfg(target_arch = "x86_64")]
+ static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 56);
+
impl<'tcx> Statement<'tcx> {
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// invalidating statement indices in `Location`s.
pub fn make_nop(&mut self) {
- // `Statement` contributes significantly to peak memory usage. Make
- // sure it doesn't get bigger.
- static_assert!(STATEMENT_IS_AT_MOST_56_BYTES: mem::size_of::<Statement<'_>>() <= 56);
-
self.kind = StatementKind::Nop
}
/// Write the discriminant for a variant to the enum Place.
SetDiscriminant {
place: Place<'tcx>,
- variant_index: usize,
+ variant_index: VariantIdx,
},
/// Start a live range for the storage of the local.
/// "Downcast" to a variant of an ADT. Currently, we only introduce
/// this for ADTs with more than one variant. It may be better to
/// just introduce it always, or always for enums.
- Downcast(&'tcx AdtDef, usize),
+ Downcast(&'tcx AdtDef, VariantIdx),
}
/// Alias for projections as they appear in places, where the base is a place
/// and the index is a local.
pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
+// at least on 64 bit systems, `PlaceElem` should not be larger than two pointers
+static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE:
+ mem::size_of::<PlaceElem<'_>>() <= 16
+);
+
/// Alias for projections as they appear in `UserTypeProjection`, where we
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
pub type ProjectionKind<'tcx> = ProjectionElem<'tcx, (), ()>;
self.elem(ProjectionElem::Deref)
}
- pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: usize) -> Place<'tcx> {
+ pub fn downcast(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx) -> Place<'tcx> {
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
}
/// active field index would identity the field `c`
Adt(
&'tcx AdtDef,
- usize,
+ VariantIdx,
&'tcx Substs<'tcx>,
Option<UserTypeAnnotation<'tcx>>,
Option<usize>,
_ => {}
}
}
- // print function definitons
+ // print function definitions
if let FnDef(did, _) = ty.sty {
return write!(f, "{}", item_path_str(did));
}
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
use ty::TyKind::*;
use ty::GenericParamDefKind;
-use ty::layout::{LayoutDetails, TargetDataLayout};
+use ty::layout::{LayoutDetails, TargetDataLayout, VariantIdx};
use ty::query;
use ty::steal::Steal;
use ty::BindingMode;
impl<'tcx> CommonTypes<'tcx> {
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
- // Ensure our type representation does not grow
- #[cfg(target_pointer_width = "64")]
- static_assert!(ASSERT_TY_KIND: ::std::mem::size_of::<ty::TyKind<'_>>() <= 24);
- #[cfg(target_pointer_width = "64")]
- static_assert!(ASSERT_TYS: ::std::mem::size_of::<ty::TyS<'_>>() <= 32);
-
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
let mk_region = |r| {
if let Some(r) = interners.region.borrow().get(&r) {
pub fn alloc_adt_def(self,
did: DefId,
kind: AdtKind,
- variants: Vec<ty::VariantDef>,
+ variants: IndexVec<VariantIdx, ty::VariantDef>,
repr: ReprOptions)
-> &'gcx ty::AdtDef {
let def = ty::AdtDef::new(self, did, kind, variants, repr);
use session::CrateDisambiguator;
use traits::{self, Reveal};
use ty;
+use ty::layout::VariantIdx;
use ty::subst::{Subst, Substs};
use ty::util::{IntTypeExt, Discr};
use ty::walk::TypeWalker;
use syntax_pos::{DUMMY_SP, Span};
use smallvec;
-use rustc_data_structures::indexed_vec::Idx;
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
HashStable};
outer_exclusive_binder: ty::DebruijnIndex,
}
+ // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
+ #[cfg(target_arch = "x86_64")]
+ static_assert!(MEM_SIZE_OF_TY_S: ::std::mem::size_of::<TyS<'_>>() == 32);
+
impl<'tcx> Ord for TyS<'tcx> {
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
self.sty.cmp(&other.sty)
/// For efficiency reasons, the distance from the
/// last `Explicit` discriminant is being stored,
/// or `0` for the first variant, if it has none.
- Relative(usize),
+ Relative(u32),
}
#[derive(Debug)]
/// table.
pub struct AdtDef {
pub did: DefId,
- pub variants: Vec<VariantDef>,
+ pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
flags: AdtFlags,
pub repr: ReprOptions,
}
fn new(tcx: TyCtxt<'_, '_, '_>,
did: DefId,
kind: AdtKind,
- variants: Vec<VariantDef>,
+ variants: IndexVec<VariantIdx, VariantDef>,
repr: ReprOptions) -> Self {
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
let mut flags = AdtFlags::NO_ADT_FLAGS;
/// Asserts this is a struct or union and returns its unique variant.
pub fn non_enum_variant(&self) -> &VariantDef {
assert!(self.is_struct() || self.is_union());
- &self.variants[0]
+ &self.variants[VariantIdx::new(0)]
}
#[inline]
.expect("variant_with_id: unknown variant")
}
- pub fn variant_index_with_id(&self, vid: DefId) -> usize {
+ pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx {
self.variants
- .iter()
- .position(|v| v.did == vid)
+ .iter_enumerated()
+ .find(|(_, v)| v.did == vid)
.expect("variant_index_with_id: unknown variant")
+ .0
}
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
pub fn discriminants(
&'a self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- ) -> impl Iterator<Item=Discr<'tcx>> + Captures<'gcx> + 'a {
+ ) -> impl Iterator<Item=(VariantIdx, Discr<'tcx>)> + Captures<'gcx> + 'a {
let repr_type = self.repr.discr_type();
let initial = repr_type.initial_discriminant(tcx.global_tcx());
let mut prev_discr = None::<Discr<'tcx>>;
- self.variants.iter().map(move |v| {
+ self.variants.iter_enumerated().map(move |(i, v)| {
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
if let VariantDiscr::Explicit(expr_did) = v.discr {
if let Some(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
}
prev_discr = Some(discr);
- discr
+ (i, discr)
})
}
/// assuming there are no constant-evaluation errors there.
pub fn discriminant_for_variant(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- variant_index: usize)
+ variant_index: VariantIdx)
-> Discr<'tcx> {
let (val, offset) = self.discriminant_def_for_variant(variant_index);
let explicit_value = val
/// inferred discriminant directly
pub fn discriminant_def_for_variant(
&self,
- variant_index: usize,
- ) -> (Option<DefId>, usize) {
- let mut explicit_index = variant_index;
+ variant_index: VariantIdx,
+ ) -> (Option<DefId>, u32) {
+ let mut explicit_index = variant_index.as_u32();
let expr_did;
loop {
- match self.variants[explicit_index].discr {
+ match self.variants[VariantIdx::from_u32(explicit_index)].discr {
ty::VariantDiscr::Relative(0) => {
expr_did = None;
break;
}
}
}
- (expr_did, variant_index - explicit_index)
+ (expr_did, variant_index.as_u32() - explicit_index)
}
pub fn destructor(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Destructor> {
/// Gets a complete map from all types to their inherent impls.
/// Not meant to be used directly outside of coherence.
/// (Defined only for LOCAL_CRATE)
- [] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
+ [] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum)
+ -> Lrc<CrateInherentImpls>,
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
/// Not meant to be used directly outside of coherence.
) -> Clauses<'tcx>,
// Get the chalk-style environment of the given item.
- [] fn environment: Environment(DefId) -> traits::Environment<'tcx>,
+ [] fn environment: Environment(DefId) -> ty::Binder<traits::Environment<'tcx>>,
},
Linking {
use rustc::ty::fold::TypeFoldable;
use rustc::ty::query::Providers;
use rustc::ty::util::{Representability, IntTypeExt, Discr};
+use rustc::ty::layout::VariantIdx;
+use rustc_data_structures::indexed_vec::Idx;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use require_c_abi_if_variadic;
/// current expression. As each subpart is processed, they may set
/// the flag to `Always` etc. Finally, at the end, we take the
/// result and "union" it with the original value, so that when we
- /// return the flag indicates if any subpart of the the parent
+ /// return the flag indicates if any subpart of the parent
/// expression (up to and including this part) has diverged. So,
/// if you read it after evaluating a subexpression `X`, the value
/// you get indicates whether any subexpression that was
}
let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
- for (discr, v) in def.discriminants(tcx).zip(vs) {
+ for ((_, discr), v) in def.discriminants(tcx).zip(vs) {
// Check for duplicate discriminant values
if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
- let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap();
+ let variant_did = def.variants[VariantIdx::new(i)].did;
+ let variant_i_node_id = tcx.hir.as_local_node_id(variant_did).unwrap();
let variant_i = tcx.hir.expect_variant(variant_i_node_id);
let i_span = match variant_i.node.disr_expr {
Some(ref expr) => tcx.hir.span(expr.id),
poly_trait_ref: ty::PolyTraitRef<'tcx>)
-> Ty<'tcx>
{
- let (trait_ref, _) =
- self.replace_late_bound_regions_with_fresh_var(
- span,
- infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
- &poly_trait_ref);
+ let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars(
+ span,
+ infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id),
+ &poly_trait_ref
+ );
self.tcx().mk_projection(item_def_id, trait_ref.substs)
}
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
+use rustc::ty::layout::VariantIdx;
use rustc::middle::stability;
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_typeck::hir_ty_to_ty;
use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use std::collections::hash_map::Entry;
use std::fmt;
}
}
+impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> {
+ fn clean(&self, cx: &DocContext) -> IndexVec<V, U> {
+ self.iter().map(|x| x.clean(cx)).collect()
+ }
+}
+
impl<T: Clean<U>, U> Clean<U> for P<T> {
fn clean(&self, cx: &DocContext) -> U {
(**self).clean(cx)
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
Predicate::Projection(ref pred) => pred.clean(cx),
- Predicate::WellFormed(ty) => {
- // This comes from `where Ty:` (i.e. no bounds) (see #53696).
- WherePredicate::BoundPredicate {
- ty: ty.clean(cx),
- bounds: vec![],
- }
- }
- Predicate::ObjectSafe(_) => panic!("not user writable"),
- Predicate::ClosureKind(..) => panic!("not user writable"),
+
+ Predicate::WellFormed(..) |
+ Predicate::ObjectSafe(..) |
+ Predicate::ClosureKind(..) |
Predicate::ConstEvaluatable(..) => panic!("not user writable"),
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Enum {
- pub variants: Vec<Item>,
+ pub variants: IndexVec<VariantIdx, Item>,
pub generics: Generics,
pub variants_stripped: bool,
}
stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx),
inner: EnumItem(Enum {
- variants: self.variants.clean(cx),
+ variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
generics: self.generics.clean(cx),
variants_stripped: false,
}),
// forcefully don't inline if this is not public or if the
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
- let denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
+ let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
a.name() == "doc" && match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, "no_inline") ||
attr::list_contains_name(&l, "hidden"),
None => false,
}
});
+ // Also check whether imports were asked to be inlined, in case we're trying to re-export a
+ // crate in Rust 2018+
+ let please_inline = self.attrs.lists("doc").has_word("inline");
let path = self.path.clean(cx);
let inner = if self.glob {
if !denied {
Import::Glob(resolve_use_source(cx, path))
} else {
let name = self.name;
+ if !please_inline {
+ match path.def {
+ Def::Mod(did) => if !did.is_local() && did.index == CRATE_DEF_INDEX {
+ // if we're `pub use`ing an extern crate root, don't inline it unless we
+ // were specifically asked for it
+ denied = true;
+ }
+ _ => {}
+ }
+ }
if !denied {
let mut visited = FxHashSet::default();
if let Some(items) = inline::try_inline(cx, path.def, name, &mut visited) {