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

[Step 2] Implement "small substs optimization" for substs of length 1 #59312

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -54,6 +54,20 @@ impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T
}
}

impl<'a, 'tcx> ToStableHashKey<StableHashingContext<'a>> for ty::subst::SubstsRef<'tcx>
{
type KeyType = <&'tcx ty::List<ty::subst::Kind<'tcx>>
as ToStableHashKey<StableHashingContext<'a>>>::KeyType;

#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
let mut hasher = StableHasher::new();
let mut hcx: StableHashingContext<'a> = hcx.clone();
self.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
@@ -62,6 +76,20 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::SubstsRef<'gcx> {
fn hash_stable<W: StableHasherResult>(
&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>,
) {
let ty::subst::SubstsRef {
inner
} = self;

inner.hash_stable(hcx, hasher);
}
}

impl<'a> HashStable<StableHashingContext<'a>>
for ty::RegionKind {
fn hash_stable<W: StableHasherResult>(&self,
@@ -447,7 +447,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
use hir::def_id::CrateNum;
use hir::map::DisambiguatedDefPathData;
use ty::print::Printer;
use ty::subst::Kind;

struct AbsolutePathPrinter<'a, 'gcx, 'tcx> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
@@ -523,7 +522,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
_args: SubstsRef<'tcx>,
) -> Result<Self::Path, Self::Error> {
print_prefix(self)
}
@@ -535,7 +534,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
let abs_path = |def_id| {
AbsolutePathPrinter { tcx: self.tcx }
.print_def_path(def_id, &[])
.print_def_path(def_id, SubstsRef::empty())
};

// We compare strings because DefPath can be different
@@ -18,7 +18,7 @@ use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use crate::ty::fold::TypeFoldable;
use crate::ty::relate::RelateResult;
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef};
use crate::ty::subst::{Kind, SubstsRef};
use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners};
use crate::ty::{FloatVid, IntVid, TyVid};
use crate::util::nodemap::FxHashMap;
@@ -1100,7 +1100,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> {
InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
SubstsRef::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
}

/// Returns `true` if errors have been reported since this infcx was
@@ -8,7 +8,7 @@ use crate::traits::{self, PredicateObligation};
use crate::ty::{self, Ty, TyCtxt, GenericParamDefKind};
use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder};
use crate::ty::outlives::Component;
use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
use crate::ty::subst::{Kind, SubstsRef, UnpackedKind};
use crate::util::nodemap::DefIdMap;

pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
@@ -469,7 +469,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// lifetimes with 'static and remapping only those used in the
// `impl Trait` return type, resulting in the parameters
// shifting.
let id_substs = InternalSubsts::identity_for_item(gcx, def_id);
let id_substs = SubstsRef::identity_for_item(gcx, def_id);
let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> = opaque_defn
.substs
.iter()
@@ -653,7 +653,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx>
},
));

self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs })
self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs: substs.into() })
}

_ => ty.super_fold_with(self),
@@ -2,7 +2,7 @@ use crate::hir::def_id::DefId;
use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::{GenericKind, VerifyBound};
use crate::traits;
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, Ty, TyCtxt};
use crate::util::captures::Captures;

@@ -292,7 +292,7 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
.iter()
.map(|(p, _)| *p)
.collect();
let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id);
let identity_substs = SubstsRef::identity_for_item(tcx, assoc_item_def_id);
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
self.collect_outlives_from_predicate_list(
move |ty| ty == identity_proj,
@@ -25,7 +25,7 @@ use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
use crate::middle::privacy::AccessLevels;
use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
use crate::session::{config, early_error, Session};
use crate::ty::{self, print::Printer, subst::Kind, TyCtxt, Ty};
use crate::ty::{self, print::Printer, subst::SubstsRef, TyCtxt, Ty};
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
use crate::util::nodemap::FxHashMap;
use crate::util::common::time;
@@ -873,14 +873,14 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
_args: SubstsRef<'tcx>,
) -> Result<Self::Path, Self::Error> {
print_prefix(self)
}
}

AbsolutePathPrinter { tcx: self.tcx }
.print_def_path(def_id, &[])
.print_def_path(def_id, SubstsRef::empty())
.unwrap()
}
}
@@ -89,7 +89,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {

let trait_ref = ty::TraitRef {
def_id: trait_did,
substs: tcx.mk_substs_trait(ty, &[]),
substs: tcx.mk_substs_trait(ty, SubstsRef::empty()),
};

let trait_pred = ty::Binder::bind(trait_ref);
@@ -306,7 +306,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
predicates.push_back(ty::Binder::bind(ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id: trait_did,
substs: infcx.tcx.mk_substs_trait(ty, &[]),
substs: infcx.tcx.mk_substs_trait(ty, SubstsRef::empty()),
},
}));

@@ -100,7 +100,7 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
impl_def_id,
self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs),
trait_ref: tcx.impl_trait_ref(impl_def_id).subst(tcx, impl_substs),
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs.into()).predicates,
};

let Normalized { value: mut header, obligations } =
@@ -1,5 +1,6 @@
use crate::infer::InferCtxt;
use crate::ty::{self, Ty, TyCtxt, ToPredicate};
use crate::ty::subst::SubstsRef;
use crate::traits::Obligation;
use crate::hir::def_id::DefId;

@@ -28,7 +29,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
) {
let trait_ref = ty::TraitRef {
def_id,
substs: infcx.tcx.mk_substs_trait(ty, &[]),
substs: infcx.tcx.mk_substs_trait(ty, SubstsRef::empty()),
};
self.register_predicate_obligation(infcx, Obligation {
cause,
@@ -28,7 +28,7 @@ use crate::ty::GenericParamDefKind;
use crate::ty::error::ExpectedFound;
use crate::ty::fast_reject;
use crate::ty::fold::TypeFolder;
use crate::ty::subst::Subst;
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::SubtypePredicate;
use crate::util::nodemap::{FxHashMap, FxHashSet};

@@ -716,7 +716,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let predicate = trait_predicate.map_bound(|mut trait_pred| {
trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
self.tcx.mk_unit(),
&trait_pred.trait_ref.substs[1..],
SubstsRef::from_slice(
self.tcx,
&trait_pred.trait_ref.substs[1..],
),
);
trait_pred
});
@@ -972,7 +975,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if let ty::Ref(_, t_type, _) = trait_type.sty {
trait_type = t_type;

let substs = self.tcx.mk_substs_trait(trait_type, &[]);
let substs = self.tcx.mk_substs_trait(trait_type, SubstsRef::empty());
let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs);
let new_obligation = Obligation::new(ObligationCause::dummy(),
obligation.param_env,
@@ -29,7 +29,7 @@ use crate::mir::interpret::ErrorHandled;
use rustc_macros::HashStable;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
use crate::ty::subst::{InternalSubsts, SubstsRef};
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, List, Ty, TyCtxt, GenericParamDefKind, ToPredicate};
use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::fold::{TypeFolder, TypeFoldable, TypeVisitor};
@@ -654,7 +654,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(

let trait_ref = ty::TraitRef {
def_id,
substs: infcx.tcx.mk_substs_trait(ty, &[]),
substs: infcx.tcx.mk_substs_trait(ty, SubstsRef::empty()),
};
let obligation = Obligation {
param_env,
@@ -1008,7 +1008,7 @@ fn vtable_methods<'a, 'tcx>(
// the method may have some early-bound lifetimes, add
// regions for those
let substs = trait_ref.map_bound(|trait_ref|
InternalSubsts::for_item(tcx, def_id, |param, _|
SubstsRef::for_item(tcx, def_id, |param, _|
match param.kind {
GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
GenericParamDefKind::Type { .. } |
@@ -15,7 +15,7 @@ use crate::hir::def_id::DefId;
use crate::lint;
use crate::traits::{self, Obligation, ObligationCause};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable, Predicate, ToPredicate};
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::subst::{Subst, SubstsRef};
use std::borrow::Cow;
use std::iter::{self};
use syntax::ast::{self, Name};
@@ -407,7 +407,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
) -> Ty<'tcx> {
debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
let substs = InternalSubsts::for_item(self, method_def_id, |param, _| {
let substs = SubstsRef::for_item(self, method_def_id, |param, _| {
if param.index == 0 {
self_ty.into()
} else {
@@ -555,12 +555,15 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
// Self: Unsize<U>
let unsize_predicate = ty::TraitRef {
def_id: unsize_did,
substs: self.mk_substs_trait(self.mk_self_type(), &[unsized_self_ty.into()]),
substs: self.mk_substs_trait(
self.mk_self_type(),
SubstsRef::from_slice(self, &[unsized_self_ty.into()]),
),
}.to_predicate();

// U: Trait<Arg1, ..., ArgN>
let trait_predicate = {
let substs = InternalSubsts::for_item(
let substs = SubstsRef::for_item(
self,
method.container.assert_trait(),
|param, _| {
@@ -592,7 +595,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
let obligation = {
let predicate = ty::TraitRef {
def_id: dispatch_from_dyn_did,
substs: self.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
substs: self.mk_substs_trait(
receiver_ty,
SubstsRef::from_slice(self, &[unsized_receiver_ty.into()]),
),
}.to_predicate();

Obligation::new(
@@ -19,7 +19,7 @@ use crate::mir::interpret::{GlobalId, ConstValue};
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use rustc_macros::HashStable;
use syntax::ast::Ident;
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::util::common::FN_OUTPUT_NAME;
@@ -402,7 +402,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
let tcx = self.selcx.tcx().global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() || substs.has_placeholders() {
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
let identity_substs = SubstsRef::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {
let cid = GlobalId {
@@ -1492,7 +1492,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
}
let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
let ty = if let ty::AssociatedKind::Existential = assoc_ty.item.kind {
let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
let item_substs = SubstsRef::identity_for_item(tcx, assoc_ty.item.def_id);
tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
} else {
tcx.type_of(assoc_ty.item.def_id)
@@ -9,7 +9,7 @@ use crate::mir::interpret::{GlobalId, ConstValue};
use crate::traits::project::Normalized;
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::ty::subst::{Subst, InternalSubsts};
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, Ty, TyCtxt};

use super::NoSolution;
@@ -193,7 +193,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
let tcx = self.infcx.tcx.global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() || substs.has_placeholders() {
let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
let identity_substs = SubstsRef::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {
let cid = GlobalId {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.