Skip to content

More EarlyBinder cleanups #100095

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
Aug 4, 2022
Merged
Show file tree
Hide file tree
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
32 changes: 16 additions & 16 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ use rustc_middle::mir::{
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
};
use rustc_middle::ty::{
self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty,
};
use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty};
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind;
Expand Down Expand Up @@ -461,35 +459,37 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let tcx = self.infcx.tcx;

// Find out if the predicates show that the type is a Fn or FnMut
let find_fn_kind_from_did = |predicates: &[(ty::Predicate<'tcx>, Span)], substs| {
predicates.iter().find_map(|(pred, _)| {
let pred = if let Some(substs) = substs {
EarlyBinder(*pred).subst(tcx, substs).kind().skip_binder()
} else {
pred.kind().skip_binder()
};
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
let find_fn_kind_from_did =
|predicates: ty::EarlyBinder<&[(ty::Predicate<'tcx>, Span)]>, substs| {
predicates.0.iter().find_map(|(pred, _)| {
let pred = if let Some(substs) = substs {
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
} else {
pred.kind().skip_binder()
};
if let ty::PredicateKind::Trait(pred) = pred && pred.self_ty() == ty {
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
return Some(hir::Mutability::Not);
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
return Some(hir::Mutability::Mut);
}
}
None
})
};
None
})
};

// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
// These types seem reasonably opaque enough that they could be substituted with their
// borrowed variants in a function body when we see a move error.
let borrow_level = match ty.kind() {
ty::Param(_) => find_fn_kind_from_did(
tcx.explicit_predicates_of(self.mir_def_id().to_def_id()).predicates,
tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id())
.map_bound(|p| p.predicates),
None,
),
ty::Opaque(did, substs) => {
find_fn_kind_from_did(tcx.explicit_item_bounds(*did), Some(*substs))
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs))
}
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_middle::mir::pretty::display_allocation;
use rustc_middle::traits::Reveal;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, subst::Subst, EarlyBinder, TyCtxt};
use rustc_middle::ty::{self, subst::Subst, TyCtxt};
use rustc_span::source_map::Span;
use rustc_target::abi::{self, Abi};
use std::borrow::Cow;
Expand Down Expand Up @@ -45,7 +45,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
"Unexpected DefKind: {:?}",
ecx.tcx.def_kind(cid.instance.def_id())
);
let layout = ecx.layout_of(EarlyBinder(body.return_ty()).subst(tcx, cid.instance.substs))?;
let layout = ecx.layout_of(body.bound_return_ty().subst(tcx, cid.instance.substs))?;
assert!(!layout.is_unsized());
let ret = ecx.allocate(layout, MemoryKind::Stack)?;

Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,12 @@ impl<'tcx> Body<'tcx> {
self.local_decls[RETURN_PLACE].ty
}

/// 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)
}

/// Gets the location of the terminator for the given block.
#[inline]
pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,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>) -> &'tcx [Ty<'tcx>] {
tcx.adt_sized_constraint(self.did()).0
pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
ty::EarlyBinder(tcx.adt_sized_constraint(self.did()).0)
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2191,7 +2191,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).is_empty(),
ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),

ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false,

Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,24 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
ty::EarlyBinder(self.const_param_default(def_id))
}

pub fn bound_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
ty::EarlyBinder(self.predicates_of(def_id))
}

pub fn bound_explicit_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
ty::EarlyBinder(self.explicit_predicates_of(def_id))
}

pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> {
ty::EarlyBinder(self.impl_subject(def_id))
}
}

struct OpaqueTypeExpander<'tcx> {
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::{
self, ConstKind, EarlyBinder, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable,
};
use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_span::{def_id::DefId, Span};
use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout};
use rustc_target::spec::abi::Abi as CallAbi;
Expand Down Expand Up @@ -387,7 +385,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
);

let ret_layout = ecx
.layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs))
.layout_of(body.bound_return_ty().subst(tcx, substs))
.ok()
// Don't bother allocating memory for large values.
// I don't know how return types can seem to be unsized but this happens in the
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/const_prop_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
use rustc_middle::ty::{
self, ConstInt, ConstKind, EarlyBinder, Instance, ParamEnv, ScalarInt, Ty, TyCtxt,
TypeVisitable,
self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable,
};
use rustc_session::lint;
use rustc_span::Span;
Expand Down Expand Up @@ -196,7 +195,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
);

let ret_layout = ecx
.layout_of(EarlyBinder(body.return_ty()).subst(tcx, substs))
.layout_of(body.bound_return_ty().subst(tcx, substs))
.ok()
// Don't bother allocating memory for large values.
// I don't know how return types can seem to be unsized but this happens in the
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
use rustc_middle::ty::{self, EarlyBinder, Term, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::sym;

use std::collections::BTreeMap;
Expand Down Expand Up @@ -2005,16 +2005,16 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
let substs =
translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
let ty = tcx.type_of(assoc_ty.item.def_id);
let ty = tcx.bound_type_of(assoc_ty.item.def_id);
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
let term: ty::Term<'tcx> = if is_const {
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
let identity_substs =
crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id);
let kind = ty::ConstKind::Unevaluated(ty::Unevaluated::new(did, identity_substs));
tcx.mk_const(ty::ConstS { ty, kind }).into()
ty.map_bound(|ty| tcx.mk_const(ty::ConstS { ty, kind }).into())
} else {
ty.into()
ty.map_bound(|ty| ty.into())
};
if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() {
let err = tcx.ty_error_with_message(
Expand All @@ -2024,7 +2024,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
Progress { term: err.into(), obligations: nested }
} else {
assoc_ty_own_obligations(selcx, obligation, &mut nested);
Progress { term: EarlyBinder(term).subst(tcx, substs), obligations: nested }
Progress { term: term.subst(tcx, substs), obligations: nested }
}
}

Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,7 +1883,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(obligation.predicate.rebind({
sized_crit.iter().map(|ty| EarlyBinder(*ty).subst(self.tcx(), substs)).collect()
sized_crit
.0
.iter()
.map(|ty| sized_crit.rebind(*ty).subst(self.tcx(), substs))
.collect()
}))
}

Expand Down Expand Up @@ -2356,11 +2360,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
// `$1: Copy`, so we must ensure the obligations are emitted in
// that order.
let predicates = tcx.predicates_of(def_id);
let predicates = tcx.bound_predicates_of(def_id);
debug!(?predicates);
assert_eq!(predicates.parent, None);
let mut obligations = Vec::with_capacity(predicates.predicates.len());
for (predicate, span) in predicates.predicates {
assert_eq!(predicates.0.parent, None);
let mut obligations = Vec::with_capacity(predicates.0.predicates.len());
for (predicate, span) in predicates.0.predicates {
let span = *span;
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
Expand All @@ -2374,7 +2378,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
param_env,
cause.clone(),
recursion_depth,
EarlyBinder(*predicate).subst(tcx, substs),
predicates.rebind(*predicate).subst(tcx, substs),
&mut obligations,
);
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use smallvec::SmallVec;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
use rustc_middle::ty::{self, EarlyBinder, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};

use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
pub use rustc_infer::traits::{self, util::*};
Expand Down Expand Up @@ -200,8 +200,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().impl_subject(impl_def_id);
let subject = EarlyBinder(subject).subst(selcx.tcx(), impl_substs);
let subject = selcx.tcx().bound_impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);
let Normalized { value: subject, obligations: normalization_obligations1 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), subject);

Expand Down
31 changes: 16 additions & 15 deletions compiler/rustc_traits/src/chalk/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ impl<'tcx> RustIrDatabase<'tcx> {
where
ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option<T>>,
{
self.interner
.tcx
.explicit_item_bounds(def_id)
let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id);
bounds
.0
.iter()
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
.map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars))
.filter_map(|bound| LowerInto::<Option<_>>::lower_into(bound, self.interner))
.collect()
}
Expand Down Expand Up @@ -268,21 +268,20 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t

let where_clauses = self.where_clauses_for(def_id, bound_vars);

let sig = self.interner.tcx.fn_sig(def_id);
let sig = self.interner.tcx.bound_fn_sig(def_id);
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
self.interner,
self.interner.tcx,
EarlyBinder(sig.inputs_and_output()).subst(self.interner.tcx, bound_vars),
sig.map_bound(|s| s.inputs_and_output()).subst(self.interner.tcx, bound_vars),
);

let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
.iter()
.map(|t| {
EarlyBinder(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner)
})
.map(|t| sig.rebind(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner))
.collect();

let return_type = EarlyBinder(inputs_and_output[inputs_and_output.len() - 1])
let return_type = sig
.rebind(inputs_and_output[inputs_and_output.len() - 1])
.subst(self.interner.tcx, &bound_vars)
.lower_into(self.interner);

Expand All @@ -295,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.lower_into(self.interner),
sig: sig.0.lower_into(self.interner),
binders: chalk_ir::Binders::new(binders, bound),
})
}
Expand Down Expand Up @@ -503,12 +502,14 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t

let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0);

let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0);
let bounds =
self.interner
.tcx
.explicit_item_bounds(opaque_ty_id.0)
explicit_item_bounds
.0
.iter()
.map(|(bound, _)| EarlyBinder(*bound).subst(self.interner.tcx, &bound_vars))
.map(|(bound, _)| {
explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)
})
.map(|bound| {
bound.fold_with(&mut ReplaceOpaqueTyFolder {
tcx: self.interner.tcx,
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{
self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt,
};
use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt};
use rustc_trait_selection::traits;

fn sized_constraint_for_ty<'tcx>(
Expand Down Expand Up @@ -33,8 +31,9 @@ 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| EarlyBinder(*ty).subst(tcx, substs))
.map(|ty| adt_tys.rebind(*ty).subst(tcx, substs))
.flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
.collect()
}
Expand Down
Loading