Skip to content
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
53 changes: 23 additions & 30 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1383,37 +1383,30 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
_ => (),
}
let sig = substs
.split_closure_args_untupled()
.closure_sig_as_fn_ptr_ty
.callable_sig(interner);
if let Some(sig) = sig {
let sig = sig.skip_binder();
let InternedClosure(def, _) = db.lookup_intern_closure(id);
let infer = InferenceResult::for_body(db, def);
let (_, kind) = infer.closure_info(id);
match f.closure_style {
ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
ClosureStyle::RANotation => write!(f, "|")?,
_ => unreachable!(),
}
if sig.inputs().is_empty() {
} else if f.should_truncate() {
write!(f, "{TYPE_HINT_TRUNCATION}")?;
} else {
f.write_joined(sig.inputs(), ", ")?;
};
match f.closure_style {
ClosureStyle::ImplFn => write!(f, ")")?,
ClosureStyle::RANotation => write!(f, "|")?,
_ => unreachable!(),
}
if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() {
write!(f, " -> ")?;
sig.output().hir_fmt(f)?;
}
let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe);
let sig = sig.skip_binder();
let InternedClosure(def, _) = db.lookup_intern_closure(id);
let infer = InferenceResult::for_body(db, def);
let (_, kind) = infer.closure_info(id);
match f.closure_style {
ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
ClosureStyle::RANotation => write!(f, "|")?,
_ => unreachable!(),
}
if sig.inputs().is_empty() {
} else if f.should_truncate() {
write!(f, "{TYPE_HINT_TRUNCATION}")?;
} else {
write!(f, "{{closure}}")?;
f.write_joined(sig.inputs(), ", ")?;
};
match f.closure_style {
ClosureStyle::ImplFn => write!(f, ")")?,
ClosureStyle::RANotation => write!(f, "|")?,
_ => unreachable!(),
}
if f.closure_style == ClosureStyle::RANotation || !sig.output().is_unit() {
write!(f, " -> ")?;
sig.output().hir_fmt(f)?;
}
}
TyKind::CoroutineClosure(id, args) => {
Expand Down
11 changes: 10 additions & 1 deletion crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ impl<'db> InferenceContext<'_, 'db> {
let ClosureSignatures { bound_sig, liberated_sig } =
self.sig_of_closure(arg_types, ret_type, expected_sig);
let body_ret_ty = bound_sig.output().skip_binder();
let sig_ty = Ty::new_fn_ptr(interner, bound_sig);

let parent_args = GenericArgs::identity_for_item(interner, self.generic_def.into());
// FIXME: Make this an infer var and infer it later.
Expand Down Expand Up @@ -117,6 +116,16 @@ impl<'db> InferenceContext<'_, 'db> {
}
None => {}
};
let sig = bound_sig.map_bound(|sig| {
interner.mk_fn_sig(
[Ty::new_tup(interner, sig.inputs())],
sig.output(),
sig.c_variadic,
sig.safety,
sig.abi,
)
});
let sig_ty = Ty::new_fn_ptr(interner, sig);
// FIXME: Infer the kind later if needed.
let parts = ClosureArgsParts {
parent_args: parent_args.as_slice(),
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/infer/closure/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use hir_def::{
};
use rustc_ast_ir::Mutability;
use rustc_hash::{FxHashMap, FxHashSet};
use rustc_type_ir::inherent::{IntoKind, Ty as _};
use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, Ty as _};
use smallvec::{SmallVec, smallvec};
use stdx::{format_to, never};
use syntax::utils::is_raw_identifier;
Expand Down Expand Up @@ -103,7 +103,7 @@ impl CapturedItem {

pub fn ty<'db>(&self, db: &'db dyn HirDatabase, subst: GenericArgs<'db>) -> Ty<'db> {
let interner = DbInterner::new_no_crate(db);
self.ty.get().instantiate(interner, subst.split_closure_args_untupled().parent_args)
self.ty.get().instantiate(interner, subst.as_closure().parent_args())
}

pub fn kind(&self) -> CaptureKind {
Expand Down
38 changes: 22 additions & 16 deletions crates/hir-ty/src/infer/coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ use rustc_type_ir::{
BoundVar, DebruijnIndex, TyVid, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt,
error::TypeError,
inherent::{Const as _, GenericArg as _, IntoKind, Safety, SliceLike, Ty as _},
inherent::{
Const as _, GenericArg as _, GenericArgs as _, IntoKind, Safety as _, SliceLike, Ty as _,
},
};
use smallvec::{SmallVec, smallvec};
use tracing::{debug, instrument};
Expand All @@ -63,6 +65,7 @@ use crate::{
Canonical, ClauseKind, CoercePredicate, Const, ConstKind, DbInterner, ErrorGuaranteed,
GenericArgs, ParamEnv, PolyFnSig, PredicateKind, Region, RegionKind, TraitRef, Ty, TyKind,
TypingMode,
abi::Safety,
infer::{
DbInternerInferExt, InferCtxt, InferOk, InferResult,
relate::RelateResult,
Expand Down Expand Up @@ -921,10 +924,8 @@ where
// or
// `unsafe fn(arg0,arg1,...) -> _`
let safety = hdr.safety;
let closure_sig = args_a.closure_sig_untupled().map_bound(|mut sig| {
sig.safety = hdr.safety;
sig
});
let closure_sig =
self.interner().signature_unclosure(args_a.as_closure().sig(), safety);
let pointer_ty = Ty::new_fn_ptr(self.interner(), closure_sig);
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
self.unify_and(
Expand Down Expand Up @@ -1125,23 +1126,28 @@ impl<'db> InferenceContext<'_, 'db> {
}
(TyKind::Closure(_, args), TyKind::FnDef(..)) => {
let b_sig = new_ty.fn_sig(self.table.interner());
let a_sig = args.closure_sig_untupled().map_bound(|mut sig| {
sig.safety = b_sig.safety();
sig
});
let a_sig = self
.interner()
.signature_unclosure(args.as_closure().sig(), b_sig.safety());
(Some(a_sig), Some(b_sig))
}
(TyKind::FnDef(..), TyKind::Closure(_, args)) => {
let a_sig = prev_ty.fn_sig(self.table.interner());
let b_sig = args.closure_sig_untupled().map_bound(|mut sig| {
sig.safety = a_sig.safety();
sig
});
let b_sig = self
.interner()
.signature_unclosure(args.as_closure().sig(), a_sig.safety());
(Some(a_sig), Some(b_sig))
}
(TyKind::Closure(_, args_a), TyKind::Closure(_, args_b)) => {
(Some(args_a.closure_sig_untupled()), Some(args_b.closure_sig_untupled()))
}
(TyKind::Closure(_, args_a), TyKind::Closure(_, args_b)) => (
Some(
self.interner()
.signature_unclosure(args_a.as_closure().sig(), Safety::Safe),
),
Some(
self.interner()
.signature_unclosure(args_b.as_closure().sig(), Safety::Safe),
),
),
_ => (None, None),
}
}
Expand Down
10 changes: 5 additions & 5 deletions crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use rustc_abi::{
TargetDataLayout, WrappingRange,
};
use rustc_index::IndexVec;
use rustc_type_ir::{FloatTy, IntTy, UintTy, inherent::IntoKind};
use rustc_type_ir::{
FloatTy, IntTy, UintTy,
inherent::{GenericArgs as _, IntoKind},
};
use triomphe::Arc;

use crate::{
Expand Down Expand Up @@ -335,10 +338,7 @@ pub fn layout_of_ty_query(
let fields = captures
.iter()
.map(|it| {
let ty = it
.ty
.get()
.instantiate(interner, args.split_closure_args_untupled().parent_args);
let ty = it.ty.get().instantiate(interner, args.as_closure().parent_args());
db.layout_of_ty(ty.store(), trait_env.clone())
})
.collect::<Result<Vec<_>, _>>()?;
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-ty/src/mir/borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::iter;
use hir_def::{DefWithBodyId, HasModule};
use la_arena::ArenaMap;
use rustc_hash::FxHashMap;
use rustc_type_ir::inherent::GenericArgs as _;
use stdx::never;
use triomphe::Arc;

Expand Down Expand Up @@ -123,7 +124,7 @@ fn make_fetch_closure_field<'db>(
let InternedClosure(def, _) = db.lookup_intern_closure(c);
let infer = InferenceResult::for_body(db, def);
let (captures, _) = infer.closure_info(c);
let parent_subst = subst.split_closure_args_untupled().parent_args;
let parent_subst = subst.as_closure().parent_args();
let interner = DbInterner::new_no_crate(db);
captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst)
}
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/mir/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc_ast_ir::Mutability;
use rustc_hash::{FxHashMap, FxHashSet};
use rustc_type_ir::{
AliasTyKind,
inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _},
inherent::{AdtDef, GenericArgs as _, IntoKind, Region as _, SliceLike, Ty as _},
};
use span::FileId;
use stdx::never;
Expand Down Expand Up @@ -731,7 +731,7 @@ impl<'db> Evaluator<'db> {
let InternedClosure(def, _) = self.db.lookup_intern_closure(c);
let infer = InferenceResult::for_body(self.db, def);
let (captures, _) = infer.closure_info(c);
let parent_subst = subst.split_closure_args_untupled().parent_args;
let parent_subst = subst.as_closure().parent_args();
captures
.get(f)
.expect("broken closure field")
Expand Down Expand Up @@ -2771,7 +2771,7 @@ impl<'db> Evaluator<'db> {
TyKind::Closure(closure, subst) => self.exec_closure(
closure.0,
func_data,
GenericArgs::new_from_slice(subst.split_closure_args_untupled().parent_args),
GenericArgs::new_from_slice(subst.as_closure().parent_args()),
destination,
&args[1..],
locals,
Expand Down
9 changes: 3 additions & 6 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use hir_expand::name::Name;
use la_arena::ArenaMap;
use rustc_apfloat::Float;
use rustc_hash::FxHashMap;
use rustc_type_ir::inherent::{Const as _, IntoKind, Ty as _};
use rustc_type_ir::inherent::{Const as _, GenericArgs as _, IntoKind, Ty as _};
use span::{Edition, FileId};
use syntax::TextRange;
use triomphe::Arc;
Expand All @@ -44,6 +44,7 @@ use crate::{
next_solver::{
Const, DbInterner, ParamConst, ParamEnv, Region, StoredGenericArgs, StoredTy, TyKind,
TypingMode, UnevaluatedConst,
abi::Safety,
infer::{DbInternerInferExt, InferCtxt},
},
traits::FnTrait,
Expand Down Expand Up @@ -2138,11 +2139,7 @@ pub fn mir_body_for_closure_query<'db>(
.store(),
});
ctx.result.param_locals.push(closure_local);
let Some(sig) =
substs.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.callable_sig(ctx.interner())
else {
implementation_error!("closure has not callable sig");
};
let sig = ctx.interner().signature_unclosure(substs.as_closure().sig(), Safety::Safe);
let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr);
let current = ctx.lower_params_and_bindings(
args.iter().zip(sig.skip_binder().inputs().iter()).map(|(it, y)| (*it, *y)),
Expand Down
58 changes: 6 additions & 52 deletions crates/hir-ty/src/next_solver/generic_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@ use std::{hint::unreachable_unchecked, marker::PhantomData, ptr::NonNull};
use hir_def::{GenericDefId, GenericParamId};
use intern::InternedRef;
use rustc_type_ir::{
ClosureArgs, ConstVid, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder, FnSigTys,
GenericTypeVisitable, Interner, TyKind, TyVid, TypeFoldable, TypeFolder, TypeVisitable,
TypeVisitor, Variance,
ClosureArgs, ConstVid, CoroutineArgs, CoroutineClosureArgs, FallibleTypeFolder,
GenericTypeVisitable, Interner, TyVid, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
Variance,
inherent::{GenericArg as _, GenericsOf, IntoKind, SliceLike, Term as _, Ty as _},
relate::{Relate, VarianceDiagInfo},
walk::TypeWalker,
};
use smallvec::SmallVec;

use crate::next_solver::{
ConstInterned, PolyFnSig, RegionInterned, TyInterned, impl_foldable_for_interned_slice,
interned_slice,
ConstInterned, RegionInterned, TyInterned, impl_foldable_for_interned_slice, interned_slice,
};

use super::{
Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, Tys,
Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty,
generics::Generics,
};

Expand Down Expand Up @@ -566,33 +565,6 @@ impl<'db> GenericArgs<'db> {
}
}

pub fn closure_sig_untupled(self) -> PolyFnSig<'db> {
let TyKind::FnPtr(inputs_and_output, hdr) =
self.split_closure_args_untupled().closure_sig_as_fn_ptr_ty.kind()
else {
unreachable!("not a function pointer")
};
inputs_and_output.with(hdr)
}

/// A "sensible" `.split_closure_args()`, where the arguments are not in a tuple.
pub fn split_closure_args_untupled(self) -> rustc_type_ir::ClosureArgsParts<DbInterner<'db>> {
// FIXME: should use `ClosureSubst` when possible
match self.as_slice() {
[parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => {
rustc_type_ir::ClosureArgsParts {
parent_args,
closure_sig_as_fn_ptr_ty: sig_ty.expect_ty(),
closure_kind_ty: closure_kind_ty.expect_ty(),
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
}
}
_ => {
unreachable!("unexpected closure sig");
}
}
}

pub fn types(self) -> impl Iterator<Item = Ty<'db>> {
self.iter().filter_map(|it| it.as_type())
}
Expand Down Expand Up @@ -688,27 +660,9 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
// FIXME: should use `ClosureSubst` when possible
match self.as_slice() {
[parent_args @ .., closure_kind_ty, sig_ty, tupled_upvars_ty] => {
let interner = DbInterner::conjure();
// This is stupid, but the next solver expects the first input to actually be a tuple
let sig_ty = match sig_ty.expect_ty().kind() {
TyKind::FnPtr(sig_tys, header) => Ty::new(
interner,
TyKind::FnPtr(
sig_tys.map_bound(|s| {
let inputs = Ty::new_tup(interner, s.inputs());
let output = s.output();
FnSigTys {
inputs_and_output: Tys::new_from_slice(&[inputs, output]),
}
}),
header,
),
),
_ => unreachable!("sig_ty should be last"),
};
rustc_type_ir::ClosureArgsParts {
parent_args,
closure_sig_as_fn_ptr_ty: sig_ty,
closure_sig_as_fn_ptr_ty: sig_ty.expect_ty(),
closure_kind_ty: closure_kind_ty.expect_ty(),
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
}
Expand Down
Loading