Skip to content

Make EarlyBinder's inner value private #112006

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

Merged
merged 3 commits into from
May 28, 2023
Merged
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
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
@@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder(value),
ty::EarlyBinder::new(value),
)
}

Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>(
let callee = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder(callee),
ty::EarlyBinder::new(callee),
);
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
cx.dbg_scope_fn(callee, callee_fn_abi, None)
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
ty::EarlyBinder(value),
ty::EarlyBinder::new(value),
)
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
@@ -497,7 +497,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
.try_subst_mir_and_normalize_erasing_regions(
*self.tcx,
self.param_env,
ty::EarlyBinder(value),
ty::EarlyBinder::new(value),
)
.map_err(|_| err_inval!(TooGeneric))
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -1278,7 +1278,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// params (and trait ref's late bound params). This logic is very similar to
// `Predicate::subst_supertrait`, and it's no coincidence why.
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
let subst_output = ty::EarlyBinder(shifted_output).subst(tcx, substs);
let subst_output = ty::EarlyBinder::new(shifted_output).subst(tcx, substs);

let bound_vars = tcx.late_bound_vars(binding.hir_id);
ty::Binder::bind_with_vars(subst_output, bound_vars)
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
@@ -794,14 +794,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
})
});
debug!(%ty);
collected_tys.insert(def_id, ty::EarlyBinder(ty));
collected_tys.insert(def_id, ty::EarlyBinder::new(ty));
}
Err(err) => {
let reported = tcx.sess.delay_span_bug(
return_span,
format!("could not fully resolve: {ty} => {err:?}"),
);
collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported)));
collected_tys.insert(def_id, ty::EarlyBinder::new(tcx.ty_error(reported)));
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/dropck.rs
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// We don't need to normalize this param-env or anything, since we're only
// substituting it with free params, so no additional param-env normalization
// can occur on top of what has been done in the param_env query itself.
let param_env = ty::EarlyBinder(tcx.param_env(adt_def_id))
let param_env = ty::EarlyBinder::new(tcx.param_env(adt_def_id))
.subst(tcx, adt_to_impl_substs)
.with_constness(tcx.constness(drop_impl_def_id));

2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -1398,7 +1398,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
let mut param_count = CountParams::default();
let has_region = pred.visit_with(&mut param_count).is_break();
let substituted_pred = ty::EarlyBinder(pred).subst(tcx, substs);
let substituted_pred = ty::EarlyBinder::new(pred).subst(tcx, substs);
// Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params.
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
@@ -1124,7 +1124,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
bug!("unexpected sort of node in fn_sig(): {:?}", x);
}
};
ty::EarlyBinder(output)
ty::EarlyBinder::new(output)
}

fn infer_return_ty_for_fn_sig<'tcx>(
@@ -1312,7 +1312,7 @@ fn impl_trait_ref(
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
)
})
.map(ty::EarlyBinder)
.map(ty::EarlyBinder::new)
}

fn check_impl_constness(
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ pub(super) fn explicit_item_bounds(
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
let opaque_ty = item.expect_opaque_ty();
return ty::EarlyBinder(opaque_type_bounds(
return ty::EarlyBinder::new(opaque_type_bounds(
tcx,
opaque_def_id.expect_local(),
opaque_ty.bounds,
@@ -124,7 +124,7 @@ pub(super) fn explicit_item_bounds(
}
_ => bug!("item_bounds called on {:?}", def_id),
};
ty::EarlyBinder(bounds)
ty::EarlyBinder::new(bounds)
}

pub(super) fn item_bounds(
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -323,7 +323,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
return map[&assoc_item.trait_item_def_id.unwrap()];
}
Err(_) => {
return ty::EarlyBinder(tcx.ty_error_with_message(
return ty::EarlyBinder::new(tcx.ty_error_with_message(
DUMMY_SP,
"Could not collect return position impl trait in trait tys",
));
@@ -497,7 +497,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
bug!("unexpected sort of node in type_of(): {:?}", x);
}
};
ty::EarlyBinder(output)
ty::EarlyBinder::new(output)
}

fn infer_placeholder_type<'a>(
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/outlives/explicit.rs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
}
}

ty::EarlyBinder(required_predicates)
ty::EarlyBinder::new(required_predicates)
})
}
}
13 changes: 8 additions & 5 deletions compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
Original file line number Diff line number Diff line change
@@ -68,12 +68,13 @@ pub(super) fn infer_predicates(
// Therefore mark `predicates_added` as true and which will ensure
// we walk the crates again and re-calculate predicates for all
// items.
let item_predicates_len: usize =
global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.0.len());
let item_predicates_len: usize = global_inferred_outlives
.get(&item_did.to_def_id())
.map_or(0, |p| p.as_ref().skip_binder().len());
if item_required_predicates.len() > item_predicates_len {
predicates_added = true;
global_inferred_outlives
.insert(item_did.to_def_id(), ty::EarlyBinder(item_required_predicates));
.insert(item_did.to_def_id(), ty::EarlyBinder::new(item_required_predicates));
}
}

@@ -137,7 +138,9 @@ fn insert_required_predicates_to_be_wf<'tcx>(
// 'a` holds for `Foo`.
debug!("Adt");
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 {
for (unsubstituted_predicate, &span) in
unsubstituted_predicates.as_ref().skip_binder()
{
// `unsubstituted_predicate` is `U: 'b` in the
// example above. So apply the substitution to
// get `T: 'a` (or `predicate`):
@@ -251,7 +254,7 @@ fn check_explicit_predicates<'tcx>(
);
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);

for (outlives_predicate, &span) in &explicit_predicates.0 {
for (outlives_predicate, &span) in explicit_predicates.as_ref().skip_binder() {
debug!("outlives_predicate = {:?}", &outlives_predicate);

// Careful: If we are inferring the effects of a `dyn Trait<..>`
37 changes: 20 additions & 17 deletions compiler/rustc_hir_analysis/src/outlives/mod.rs
Original file line number Diff line number Diff line change
@@ -98,24 +98,27 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
let predicates = global_inferred_outlives
.iter()
.map(|(&def_id, set)| {
let predicates = &*tcx.arena.alloc_from_iter(set.0.iter().filter_map(
|(ty::OutlivesPredicate(kind1, region2), &span)| {
match kind1.unpack() {
GenericArgKind::Type(ty1) => Some((
ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)),
span,
)),
GenericArgKind::Lifetime(region1) => Some((
ty::Clause::RegionOutlives(ty::OutlivesPredicate(region1, *region2)),
span,
)),
GenericArgKind::Const(_) => {
// Generic consts don't impose any constraints.
None
let predicates =
&*tcx.arena.alloc_from_iter(set.as_ref().skip_binder().iter().filter_map(
|(ty::OutlivesPredicate(kind1, region2), &span)| {
match kind1.unpack() {
GenericArgKind::Type(ty1) => Some((
ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)),
span,
)),
GenericArgKind::Lifetime(region1) => Some((
ty::Clause::RegionOutlives(ty::OutlivesPredicate(
region1, *region2,
)),
span,
)),
GenericArgKind::Const(_) => {
// Generic consts don't impose any constraints.
None
}
}
}
},
));
},
));
(def_id, predicates)
})
.collect();
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -1386,7 +1386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the referenced item.
let ty = tcx.type_of(def_id);
assert!(!substs.has_escaping_bound_vars());
assert!(!ty.0.has_escaping_bound_vars());
assert!(!ty.skip_binder().has_escaping_bound_vars());
let ty_substituted = self.normalize(span, ty.subst(tcx, substs));

if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
@@ -293,7 +293,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
) -> impl Iterator<Item = ty::Region<'tcx>> {
let tcx = self.tcx;
let bounds = tcx.item_bounds(alias_ty.def_id);
trace!("{:#?}", bounds.0);
trace!("{:#?}", bounds.skip_binder());
bounds
.subst_iter(tcx, alias_ty.substs)
.filter_map(|p| p.to_opt_type_outlives())
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
@@ -851,7 +851,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} else {
tcx.arena.alloc_from_iter(lazy.decode((self, tcx)))
};
ty::EarlyBinder(&*output)
ty::EarlyBinder::new(&*output)
}

fn get_variant(
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
@@ -1727,7 +1727,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
ty::Closure(_, substs) => {
let constness = self.tcx.constness(def_id.to_def_id());
self.tables.constness.set_some(def_id.to_def_id().index, constness);
record!(self.tables.fn_sig[def_id.to_def_id()] <- ty::EarlyBinder(substs.as_closure().sig()));
record!(self.tables.fn_sig[def_id.to_def_id()] <- ty::EarlyBinder::new(substs.as_closure().sig()));
}

_ => bug!("closure that is neither generator nor closure"),
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -476,7 +476,7 @@ impl<'tcx> Body<'tcx> {
/// Returns the return type; it always return first element from `local_decls` array.
#[inline]
pub fn bound_return_ty(&self) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.local_decls[RETURN_PLACE].ty)
ty::EarlyBinder::new(self.local_decls[RETURN_PLACE].ty)
}

/// Gets the location of the terminator for the given block.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
@@ -573,7 +573,7 @@ impl<'tcx> AdtDef<'tcx> {
/// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer (e.g., issue #31299).
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
ty::EarlyBinder(tcx.adt_sized_constraint(self.did()))
ty::EarlyBinder::new(tcx.adt_sized_constraint(self.did()))
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
@@ -254,5 +254,5 @@ pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBind
"`const_param_default` expected a generic parameter with a constant"
),
};
ty::EarlyBinder(Const::from_anon_const(tcx, default_def_id))
ty::EarlyBinder::new(Const::from_anon_const(tcx, default_def_id))
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
@@ -343,7 +343,7 @@ impl<'tcx> GenericPredicates<'tcx> {
substs: SubstsRef<'tcx>,
) -> impl Iterator<Item = (Predicate<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
{
EarlyBinder(self.predicates).subst_iter_copied(tcx, substs)
EarlyBinder::new(self.predicates).subst_iter_copied(tcx, substs)
}

#[instrument(level = "debug", skip(self, tcx))]
@@ -358,7 +358,7 @@ impl<'tcx> GenericPredicates<'tcx> {
}
instantiated
.predicates
.extend(self.predicates.iter().map(|(p, _)| EarlyBinder(*p).subst(tcx, substs)));
.extend(self.predicates.iter().map(|(p, _)| EarlyBinder::new(*p).subst(tcx, substs)));
instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
}

Original file line number Diff line number Diff line change
@@ -158,7 +158,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
fn subst_opt(self, tcx: TyCtxt<'tcx>, substs: ty::SubstsRef<'tcx>) -> Option<Self> {
match self {
Self::ConstIsZero(c) => {
let c = ty::EarlyBinder(c).subst(tcx, substs);
let c = ty::EarlyBinder::new(c).subst(tcx, substs);
let pred = match c.kind().try_to_target_usize(tcx) {
Some(0) => Self::True,
Some(1..) => Self::False,
@@ -167,7 +167,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
Some(pred)
}
Self::GenericType(t) => {
Some(ty::EarlyBinder(t).subst(tcx, substs).inhabited_predicate(tcx))
Some(ty::EarlyBinder::new(t).subst(tcx, substs).inhabited_predicate(tcx))
}
Self::And(&[a, b]) => match a.subst_opt(tcx, substs) {
None => b.subst_opt(tcx, substs).map(|b| a.and(tcx, b)),
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -764,7 +764,7 @@ impl<'tcx> Predicate<'tcx> {
let shifted_pred =
tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
// 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
let new = EarlyBinder::new(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
// 3) ['x] + ['b] -> ['x, 'b]
let bound_vars =
tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ pub trait Printer<'tcx>: Sized {
impl_trait_ref.map(|i| i.subst(self.tcx(), substs)),
)
} else {
(self_ty.0, impl_trait_ref.map(|i| i.0))
(self_ty.subst_identity(), impl_trait_ref.map(|i| i.subst_identity()))
};
self.print_impl_path(def_id, substs, self_ty, impl_trait_ref)
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -568,7 +568,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
let layout = tcx.generator_layout(def_id).unwrap();
layout.variant_fields.iter().map(move |variant| {
variant.iter().map(move |field| {
ty::EarlyBinder(layout.field_tys[*field].ty).subst(tcx, self.substs)
ty::EarlyBinder::new(layout.field_tys[*field].ty).subst(tcx, self.substs)
})
})
}
@@ -2366,7 +2366,7 @@ impl<'tcx> Ty<'tcx> {

ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),

ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
ty::Adt(def, _substs) => def.sized_constraint(tcx).skip_binder().is_empty(),

ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,

9 changes: 8 additions & 1 deletion compiler/rustc_middle/src/ty/subst.rs
Original file line number Diff line number Diff line change
@@ -538,13 +538,17 @@ impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx
/// [`subst_identity`](EarlyBinder::subst_identity) or [`skip_binder`](EarlyBinder::skip_binder).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable)]
pub struct EarlyBinder<T>(pub T);
pub struct EarlyBinder<T>(T);

/// For early binders, you should first call `subst` before using any visitors.
impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}

impl<T> EarlyBinder<T> {
pub fn new(inner: T) -> EarlyBinder<T> {
EarlyBinder(inner)
}

pub fn as_ref(&self) -> EarlyBinder<&T> {
EarlyBinder(&self.0)
}
@@ -582,6 +586,9 @@ impl<T> EarlyBinder<T> {
/// arguments of an `FnSig`). Otherwise, consider using
/// [`subst_identity`](EarlyBinder::subst_identity).
///
/// To skip the binder on `x: &EarlyBinder<T>` to obtain `&T`, leverage
/// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`.
///
/// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is
/// the analogous operation on [`super::Binder`].
pub fn skip_binder(self) -> T {
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
@@ -709,7 +709,7 @@ impl<'tcx> TyCtxt<'tcx> {
.as_ref()
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
.filter(|decl| !decl.ignore_for_traits)
.map(|decl| ty::EarlyBinder(decl.ty))
.map(|decl| ty::EarlyBinder::new(decl.ty))
}

/// Normalizes all opaque types in the given value, replacing them
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
@@ -96,13 +96,13 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Representability {

impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<Ty<'_>> {
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
ty::EarlyBinder(Ty::from_cycle_error(tcx, cycle))
ty::EarlyBinder::new(Ty::from_cycle_error(tcx, cycle))
}
}

impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>> {
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
ty::EarlyBinder(ty::Binder::from_cycle_error(tcx, cycle))
ty::EarlyBinder::new(ty::Binder::from_cycle_error(tcx, cycle))
}
}

Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
// If the inner type matches the type bound by `Pointer`
if inner_ty == bound_ty {
// Do a substitution using the parameters from the callsite
let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref);
let subst_ty = EarlyBinder::new(inner_ty).subst(self.tcx, substs_ref);
if let Some((fn_id, fn_substs)) =
FunctionItemRefChecker::is_fn_ref(subst_ty)
{
8 changes: 4 additions & 4 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
@@ -192,7 +192,7 @@ impl<'tcx> Inliner<'tcx> {
let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
self.tcx,
self.param_env,
ty::EarlyBinder(callee_body.clone()),
ty::EarlyBinder::new(callee_body.clone()),
) else {
return Err("failed to normalize callee body");
};
@@ -455,7 +455,7 @@ impl<'tcx> Inliner<'tcx> {
// If the place doesn't actually need dropping, treat it like a regular goto.
let ty = callsite
.callee
.subst_mir(self.tcx, ty::EarlyBinder(&place.ty(callee_body, tcx).ty));
.subst_mir(self.tcx, ty::EarlyBinder::new(&place.ty(callee_body, tcx).ty));
if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
work_list.push(unwind);
}
@@ -790,7 +790,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
// If the place doesn't actually need dropping, treat it like a regular goto.
let ty = self
.instance
.subst_mir(tcx, ty::EarlyBinder(&place.ty(self.callee_body, tcx).ty));
.subst_mir(tcx, ty::EarlyBinder::new(&place.ty(self.callee_body, tcx).ty));
if ty.needs_drop(tcx, self.param_env) {
self.cost += CALL_PENALTY;
if let UnwindAction::Cleanup(_) = unwind {
@@ -801,7 +801,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}
}
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder(&f.literal.ty()));
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::new(&f.literal.ty()));
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
// Don't give intrinsics the extra penalty for calls
INSTR_COST
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/inline/cycle.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(
tcx,
param_env,
ty::EarlyBinder(substs),
ty::EarlyBinder::new(substs),
) else {
trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping");
continue;
9 changes: 6 additions & 3 deletions compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
// of this function. Is this intentional?
if let Some(ty::Generator(gen_def_id, substs, _)) = ty.map(Ty::kind) {
let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap();
let body = EarlyBinder(body.clone()).subst(tcx, substs);
let body = EarlyBinder::new(body.clone()).subst(tcx, substs);
debug!("make_shim({:?}) = {:?}", instance, body);
return body;
}
@@ -644,8 +644,11 @@ fn build_call_shim<'tcx>(
let sig = sig.map_bound(|sig| tcx.erase_late_bound_regions(sig));

assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body());
let mut sig =
if let Some(sig_substs) = sig_substs { sig.subst(tcx, &sig_substs) } else { sig.0 };
let mut sig = if let Some(sig_substs) = sig_substs {
sig.subst(tcx, &sig_substs)
} else {
sig.skip_binder()
Copy link
Member

Choose a reason for hiding this comment

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

subst_identity i feel

Copy link
Contributor

Choose a reason for hiding this comment

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

I would expect this to be no_bound_vars() 🤔 though that may break with polymorphization rn?

Copy link
Member

Choose a reason for hiding this comment

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

This type of pattern was always sketchy to me. Adding the EarlyBinder type makes it clear why.

I'm not sure how polymorphization works; seems like this could be a byproduct of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this panics with no_bound_vars().unwrap() unfortunately.

From reading the polymorphization section in the rustc_dev_guide, it looks like polymorphization uses ty::Param to represent unused generics. So after polymorphization sig may appear to needs_subst() because of the presence of ty::Params. I'm sure it's more complicated than that in practice, but is that sort of the right way to think about this?

Copy link
Contributor

@lcnr lcnr Jun 5, 2023

Choose a reason for hiding this comment

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

Yeah, this panics with no_bound_vars().unwrap() unfortunately.

From reading the polymorphization section in the rustc_dev_guide, it looks like polymorphization uses ty::Param to represent unused generics. So after polymorphization sig may appear to needs_subst() because of the presence of ty::Params. I'm sure it's more complicated than that in practice, but is that sort of the right way to think about this?

yeah, it is exactly that, I want to move polymorphization to bound vars by changing instances to use ty::Binder and then using bound vars of params (as params are conceptionally just a different representation of bound vars or placeholders, depending on context 😁)

I think using ty::Param for polymorphization will end up causing issues like the above in the future.

Copy link
Contributor

@lcnr lcnr Jun 5, 2023

Choose a reason for hiding this comment

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

that would be an option, I don't like it too much because ty::Erased should be equal to itself and for<T, U> my_function<T, U> should be different from for<T> my_function<T, T>. While we may not necessarily end up with these cases in practice it still feels a bit dangerous

Copy link
Member

Choose a reason for hiding this comment

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

Both for<T, U> my_function<T, U> and for<T> my_function<T, T> should be equal to be able to codegen a single instance, right? Polymorphization already makes sure that it won't erase types that actually matter for codegen.

Copy link
Contributor

Choose a reason for hiding this comment

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

Both for<T, U> my_function<T, U> and for<T> my_function<T, T> should be equal to be able to codegen a single instance, right?

yes, the issue is that if you polymorphize to bound vars, these two are different, but if you polymorphize to erased, then both end up as my_function<erased, erased> which should be equal to itself

Copy link
Member

Choose a reason for hiding this comment

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

You can't observe the difference at runtime, right? If you did, polymorphization should reject the candidates. Rustc passes unnamed_addr to LLVM, so just comparing the function pointers can return true already if after optimizations the function bodies are identical.

Copy link
Contributor

@lcnr lcnr Jun 5, 2023

Choose a reason for hiding this comment

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

for<T, U> my_function<T, U> and for<T> my_function<T, T> probably won't happen in practice but you could imagine

fn check_type_ids<T, U, V>() -> u8 {
    if TypeId::of::<T>() == TypeId::of::<U>() {
        0
    } else if TypeId::of::<T>() == TypeId::of::<U>() {
        1
    } else {
        2
    }
}

we end up with for<Eq, DontCare> check_type_ids<Eq, DontCare, Eq> and for<DontCare, Eq> check_type_ids<DontCare, Eq, Eq>

fn check_type_ids<Eq, DontCare, Eq>() -> u8 {
    0
}

fn check_type_ids<DontCare, Eq, Eq>() -> u8 {
    if TypeId::of::<T>() == TypeId::of::<U>() {
        0
    } else {
        1
    }
}

this isn't a great example which is why I said "While we may not necessarily end up with these cases in practice it still feels a bit dangerous". I am worried about having yet another global invariant which is difficult to sensibly check

};

if let CallKind::Indirect(fnty) = call_kind {
// `sig` determines our local decls, and thus the callee type in the `Call` terminator. This
2 changes: 1 addition & 1 deletion compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
@@ -677,7 +677,7 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder(value),
ty::EarlyBinder::new(value),
)
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_monomorphize/src/util.rs
Original file line number Diff line number Diff line change
@@ -29,12 +29,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
closure_instance.substs,
param_env,
ty::EarlyBinder(before_feature_tys),
ty::EarlyBinder::new(before_feature_tys),
);
let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
closure_instance.substs,
param_env,
ty::EarlyBinder(after_feature_tys),
ty::EarlyBinder::new(after_feature_tys),
);

let new_size = tcx
2 changes: 1 addition & 1 deletion compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
@@ -274,7 +274,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {

let mut param_env = self.tcx.param_env_reveal_all_normalized(impl_def_id);
if !substs.is_empty() {
param_env = EarlyBinder(param_env).subst(self.tcx, substs);
param_env = EarlyBinder::new(param_env).subst(self.tcx, substs);
}

match &mut impl_trait_ref {
Original file line number Diff line number Diff line change
@@ -148,11 +148,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(

ty::Adt(def, substs) => {
let sized_crit = def.sized_constraint(ecx.tcx());
Ok(sized_crit
.0
.iter()
.map(|ty| sized_crit.rebind(*ty).subst(ecx.tcx(), substs))
.collect())
Ok(sized_crit.subst_iter_copied(ecx.tcx(), substs).collect())
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
tcx,
ObligationCause::dummy_with_span(*span),
param_env,
ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs),
ty::EarlyBinder::new(*pred).subst(tcx, impl_trait_ref.substs),
)
})
});
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
@@ -642,7 +642,7 @@ fn receiver_for_self_ty<'tcx>(
if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) }
});

let result = EarlyBinder(receiver_ty).subst(tcx, substs);
let result = EarlyBinder::new(receiver_ty).subst(tcx, substs);
debug!(
"receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
receiver_ty, self_ty, method_def_id, result
Original file line number Diff line number Diff line change
@@ -307,13 +307,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
// there, but that needs some way to handle cycles.
constraints
.dtorck_types
.extend(dtorck_types.iter().map(|t| EarlyBinder(*t).subst(tcx, substs)));
.extend(dtorck_types.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
constraints
.outlives
.extend(outlives.iter().map(|t| EarlyBinder(*t).subst(tcx, substs)));
.extend(outlives.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
constraints
.overflows
.extend(overflows.iter().map(|t| EarlyBinder(*t).subst(tcx, substs)));
.extend(overflows.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
}

// Objects must be alive in order for their destructor
Original file line number Diff line number Diff line change
@@ -360,7 +360,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// consider a "quick reject". This avoids creating more types
// and so forth that we need to.
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
if !drcx.substs_refs_may_unify(obligation_substs, impl_trait_ref.0.substs) {
if !drcx
.substs_refs_may_unify(obligation_substs, impl_trait_ref.skip_binder().substs)
{
return;
}
if self.reject_fn_ptr_impls(
Original file line number Diff line number Diff line change
@@ -527,9 +527,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
substs.extend(trait_predicate.trait_ref.substs.iter());
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(
bound.0.kind().bound_vars().len() + defs.count(),
bound.skip_binder().kind().bound_vars().len() + defs.count(),
);
bound_vars.extend(bound.0.kind().bound_vars().into_iter());
bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter());
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
.kind
{
12 changes: 5 additions & 7 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
@@ -2149,13 +2149,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
ty::Adt(def, substs) => {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(obligation.predicate.rebind({
sized_crit
.0
.iter()
.map(|ty| sized_crit.rebind(*ty).subst(self.tcx(), substs))
.collect()
}))
Where(
obligation
.predicate
.rebind(sized_crit.subst_iter_copied(self.tcx(), substs).collect()),
)
}

ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None,
2 changes: 1 addition & 1 deletion compiler/rustc_traits/src/chalk/db.rs
Original file line number Diff line number Diff line change
@@ -294,7 +294,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
};
Arc::new(chalk_solve::rust_ir::FnDefDatum {
id: fn_def_id,
sig: sig.0.lower_into(self.interner),
sig: sig.skip_binder().lower_into(self.interner),
binders: chalk_ir::Binders::new(binders, bound),
})
}
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
@@ -301,7 +301,7 @@ fn associated_type_for_impl_trait_in_trait(
trait_assoc_ty.impl_defaultness(tcx.impl_defaultness(fn_def_id));

// Copy type_of of the opaque.
trait_assoc_ty.type_of(ty::EarlyBinder(tcx.mk_opaque(
trait_assoc_ty.type_of(ty::EarlyBinder::new(tcx.mk_opaque(
opaque_ty_def_id.to_def_id(),
InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
)));
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/consts.rs
Original file line number Diff line number Diff line change
@@ -419,7 +419,7 @@ pub fn thir_abstract_const(

let root_span = body.exprs[body_id].span;

Ok(Some(ty::EarlyBinder(recurse_build(tcx, body, body_id, root_span)?)))
Ok(Some(ty::EarlyBinder::new(recurse_build(tcx, body, body_id, root_span)?)))
}

pub fn provide(providers: &mut Providers) {
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
@@ -610,7 +610,7 @@ fn generator_layout<'tcx>(
) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
use SavedLocalEligibility::*;
let tcx = cx.tcx;
let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs);
let subst_field = |ty: Ty<'tcx>| EarlyBinder::new(ty).subst(tcx, substs);

let Some(info) = tcx.generator_layout(def_id) else {
return Err(LayoutError::Unknown(ty));
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/needs_drop.rs
Original file line number Diff line number Diff line change
@@ -210,7 +210,7 @@ fn drop_tys_helper<'tcx>(
match subty.kind() {
ty::Adt(adt_id, subst) => {
for subty in tcx.adt_drop_tys(adt_id.did())? {
vec.push(EarlyBinder(subty).subst(tcx, subst));
vec.push(EarlyBinder::new(subty).subst(tcx, subst));
}
}
_ => vec.push(subty),
6 changes: 2 additions & 4 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -44,9 +44,7 @@ fn sized_constraint_for_ty<'tcx>(
let adt_tys = adt.sized_constraint(tcx);
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys);
adt_tys
.0
.iter()
.map(|ty| adt_tys.rebind(*ty).subst(tcx, substs))
.subst_iter_copied(tcx, substs)
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
.collect()
}
@@ -508,7 +506,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'

if self_ty_matches {
debug!("issue33140_self_ty - MATCHES!");
Some(EarlyBinder(self_ty))
Some(EarlyBinder::new(self_ty))
} else {
debug!("issue33140_self_ty - non-matching self type");
None
14 changes: 7 additions & 7 deletions src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
let mut impls = Vec::new();
for trait_def_id in cx.tcx.all_traits() {
if !cx.cache.effective_visibilities.is_reachable(cx.tcx, trait_def_id)
|| cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some()
|| cx.generated_synthetics.get(&(ty.skip_binder(), trait_def_id)).is_some()
{
continue;
}
@@ -34,13 +34,13 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
impl_def_id
);
let trait_ref = cx.tcx.impl_trait_ref(impl_def_id).unwrap();
if !matches!(trait_ref.0.self_ty().kind(), ty::Param(_)) {
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
continue;
}
let infcx = cx.tcx.infer_ctxt().build();
let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
let impl_ty = ty.subst(infcx.tcx, substs);
let param_env = EarlyBinder(param_env).subst(infcx.tcx, substs);
let param_env = EarlyBinder::new(param_env).subst(infcx.tcx, substs);

let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
@@ -87,7 +87,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
trait_ref, ty
);

cx.generated_synthetics.insert((ty.0, trait_def_id));
cx.generated_synthetics.insert((ty.skip_binder(), trait_def_id));

impls.push(Item {
name: None,
@@ -104,10 +104,10 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
// the post-inference `trait_ref`, as it's more accurate.
trait_: Some(clean_trait_ref_with_bindings(
cx,
ty::Binder::dummy(trait_ref.0),
ty::Binder::dummy(trait_ref.skip_binder()),
ThinVec::new(),
)),
for_: clean_middle_ty(ty::Binder::dummy(ty.0), cx, None),
for_: clean_middle_ty(ty::Binder::dummy(ty.skip_binder()), cx, None),
items: cx
.tcx
.associated_items(impl_def_id)
@@ -116,7 +116,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.collect::<Vec<_>>(),
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(Box::new(clean_middle_ty(
ty::Binder::dummy(trait_ref.0.self_ty()),
ty::Binder::dummy(trait_ref.skip_binder().self_ty()),
cx,
None,
))),
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
@@ -1219,7 +1219,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
return false;
}

let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
let predicate = EarlyBinder::new(predicate).subst(cx.tcx, &substs_with_referent_ty);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
let infcx = cx.tcx.infer_ctxt().build();
infcx.predicate_must_hold_modulo_regions(&obligation)
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/eta_reduction.rs
Original file line number Diff line number Diff line change
@@ -243,7 +243,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs
| ty::Ref(..)
| ty::Slice(_)
| ty::Tuple(_) => {
format!("<{}>", EarlyBinder(ty).subst(cx.tcx, substs))
format!("<{}>", EarlyBinder::new(ty).subst(cx.tcx, substs))
},
_ => ty.to_string(),
}
Original file line number Diff line number Diff line change
@@ -241,7 +241,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
&& let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
&& let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
{
item_ty == EarlyBinder(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
item_ty == EarlyBinder::new(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
} else {
false
}
Original file line number Diff line number Diff line change
@@ -428,7 +428,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
}));

if trait_predicates.any(|predicate| {
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
let predicate = EarlyBinder::new(predicate).subst(cx.tcx, new_subst);
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
}) {
@@ -438,7 +438,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
let output_ty = fn_sig.output();
if output_ty.contains(*param_ty) {
if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
new_subst, cx.param_env, EarlyBinder(output_ty)) {
new_subst, cx.param_env, EarlyBinder::new(output_ty)) {
expr = parent_expr;
ty = new_ty;
continue;
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ fn collect_unsafe_exprs<'tcx>(
.type_dependent_def_id(expr.hir_id)
.map(|def_id| cx.tcx.fn_sig(def_id))
{
if sig.0.unsafety() == Unsafety::Unsafe {
if sig.skip_binder().unsafety() == Unsafety::Unsafe {
unsafe_ops.push(("unsafe method call occurs here", expr.span));
}
}
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_utils/src/consts.rs
Original file line number Diff line number Diff line change
@@ -462,7 +462,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
let substs = if self.substs.is_empty() {
substs
} else {
EarlyBinder(substs).subst(self.lcx.tcx, self.substs)
EarlyBinder::new(substs).subst(self.lcx.tcx, self.substs)
};

let result = self