refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
parent
1cae70145c
commit
d45c8c3e7c
@ -70,7 +70,7 @@ pub(crate) fn get_function_sig<'tcx>(
|
||||
default_call_conv: CallConv,
|
||||
inst: Instance<'tcx>,
|
||||
) -> Signature {
|
||||
assert!(!inst.substs.has_infer());
|
||||
assert!(!inst.args.has_infer());
|
||||
clif_sig_from_fn_abi(
|
||||
tcx,
|
||||
default_call_conv,
|
||||
@ -377,16 +377,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
let ret_place = codegen_place(fx, destination);
|
||||
|
||||
// Handle special calls like intrinsics and empty drop glue.
|
||||
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
|
||||
let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() {
|
||||
let instance =
|
||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args)
|
||||
.polymorphize(fx.tcx);
|
||||
|
||||
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
|
||||
crate::intrinsics::codegen_llvm_intrinsic_call(
|
||||
fx,
|
||||
&fx.tcx.symbol_name(instance).name,
|
||||
substs,
|
||||
fn_args,
|
||||
args,
|
||||
ret_place,
|
||||
target,
|
||||
@ -611,7 +611,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||
// `Instance::resolve_drop_in_place`?
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||
substs: drop_instance.substs,
|
||||
args: drop_instance.args,
|
||||
};
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
@ -648,7 +648,7 @@ pub(crate) fn codegen_drop<'tcx>(
|
||||
|
||||
let virtual_drop = Instance {
|
||||
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
|
||||
substs: drop_instance.substs,
|
||||
args: drop_instance.args,
|
||||
};
|
||||
let fn_abi =
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
|
||||
|
10
src/base.rs
10
src/base.rs
@ -28,7 +28,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
module: &mut dyn Module,
|
||||
instance: Instance<'tcx>,
|
||||
) -> CodegenedFunction {
|
||||
debug_assert!(!instance.substs.has_infer());
|
||||
debug_assert!(!instance.args.has_infer());
|
||||
|
||||
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
||||
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);
|
||||
@ -578,13 +578,13 @@ fn codegen_stmt<'tcx>(
|
||||
let from_ty = fx.monomorphize(operand.ty(&fx.mir.local_decls, fx.tcx));
|
||||
let to_layout = fx.layout_of(fx.monomorphize(to_ty));
|
||||
match *from_ty.kind() {
|
||||
ty::FnDef(def_id, substs) => {
|
||||
ty::FnDef(def_id, args) => {
|
||||
let func_ref = fx.get_function_ref(
|
||||
Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap()
|
||||
.polymorphize(fx.tcx),
|
||||
@ -668,11 +668,11 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
) => {
|
||||
let operand = codegen_operand(fx, operand);
|
||||
match *operand.layout().ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
ty::Closure(def_id, args) => {
|
||||
let instance = Instance::resolve_closure(
|
||||
fx.tcx,
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen")
|
||||
|
@ -57,7 +57,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
|
||||
let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
|
||||
let instance = ty::Instance {
|
||||
def: ty::InstanceDef::ThreadLocalShim(def_id),
|
||||
substs: ty::InternalSubsts::empty(),
|
||||
args: ty::GenericArgs::empty(),
|
||||
};
|
||||
let func_ref = fx.get_function_ref(instance);
|
||||
let call = fx.bcx.ins().call(func_ref, &[]);
|
||||
|
@ -42,7 +42,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
||||
InlineAsmOperand::SymFn { anon_const } => {
|
||||
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
|
||||
let instance = match ty.kind() {
|
||||
&ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
|
||||
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||
_ => span_bug!(op_sp, "asm sym is not a function"),
|
||||
};
|
||||
let symbol = tcx.symbol_name(instance);
|
||||
|
@ -254,12 +254,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
}
|
||||
InlineAsmOperand::SymFn { ref value } => {
|
||||
let literal = fx.monomorphize(value.literal);
|
||||
if let ty::FnDef(def_id, substs) = *literal.ty().kind() {
|
||||
if let ty::FnDef(def_id, args) = *literal.ty().kind() {
|
||||
let instance = ty::Instance::resolve_for_fn_ptr(
|
||||
fx.tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
substs,
|
||||
args,
|
||||
)
|
||||
.unwrap();
|
||||
let symbol = fx.tcx.symbol_name(instance);
|
||||
|
@ -3,23 +3,35 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
substs: SubstsRef<'tcx>,
|
||||
generic_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
) {
|
||||
if intrinsic.starts_with("llvm.aarch64") {
|
||||
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
||||
fx, intrinsic, substs, args, ret, target,
|
||||
fx,
|
||||
intrinsic,
|
||||
generic_args,
|
||||
args,
|
||||
ret,
|
||||
target,
|
||||
);
|
||||
}
|
||||
if intrinsic.starts_with("llvm.x86") {
|
||||
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
|
||||
return llvm_x86::codegen_x86_llvm_intrinsic_call(
|
||||
fx,
|
||||
intrinsic,
|
||||
generic_args,
|
||||
args,
|
||||
ret,
|
||||
target,
|
||||
);
|
||||
}
|
||||
|
||||
match intrinsic {
|
||||
|
@ -3,12 +3,12 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
|
@ -3,12 +3,12 @@
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
|
@ -24,7 +24,7 @@ macro_rules! intrinsic_args {
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
use crate::prelude::*;
|
||||
@ -213,13 +213,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||
source_info: mir::SourceInfo,
|
||||
) {
|
||||
let intrinsic = fx.tcx.item_name(instance.def_id());
|
||||
let substs = instance.substs;
|
||||
let instance_args = instance.args;
|
||||
|
||||
if intrinsic.as_str().starts_with("simd_") {
|
||||
self::simd::codegen_simd_intrinsic_call(
|
||||
fx,
|
||||
intrinsic,
|
||||
substs,
|
||||
instance_args,
|
||||
args,
|
||||
destination,
|
||||
target.expect("target for simd intrinsic"),
|
||||
@ -233,7 +233,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||
fx,
|
||||
instance,
|
||||
intrinsic,
|
||||
substs,
|
||||
instance_args,
|
||||
args,
|
||||
destination,
|
||||
target,
|
||||
@ -365,7 +365,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
intrinsic: Symbol,
|
||||
substs: SubstsRef<'tcx>,
|
||||
generic_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
destination: Option<BasicBlock>,
|
||||
@ -394,7 +394,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let dst = dst.load_scalar(fx);
|
||||
let count = count.load_scalar(fx);
|
||||
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_ty = generic_args.type_at(0);
|
||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||
assert_eq!(args.len(), 3);
|
||||
let byte_amount =
|
||||
@ -410,7 +410,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let src = src.load_scalar(fx);
|
||||
let count = count.load_scalar(fx);
|
||||
|
||||
let elem_ty = substs.type_at(0);
|
||||
let elem_ty = generic_args.type_at(0);
|
||||
let elem_size: u64 = fx.layout_of(elem_ty).size.bytes();
|
||||
assert_eq!(args.len(), 3);
|
||||
let byte_amount =
|
||||
@ -428,7 +428,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::size_of_val => {
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let layout = fx.layout_of(generic_args.type_at(0));
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
@ -443,7 +443,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::min_align_of_val => {
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let layout = fx.layout_of(generic_args.type_at(0));
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
@ -602,7 +602,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
|
||||
intrinsic_args!(fx, args => (); intrinsic);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
|
||||
let requirement = ValidityRequirement::from_intrinsic(intrinsic);
|
||||
|
||||
@ -674,7 +674,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr, base); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
let base = base.load_scalar(fx);
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
|
||||
let pointee_size: u64 = fx.layout_of(ty).size.bytes();
|
||||
let diff_bytes = fx.bcx.ins().isub(ptr, base);
|
||||
@ -720,7 +720,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
match ty.kind() {
|
||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||
// FIXME implement 128bit atomics
|
||||
@ -751,7 +751,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
intrinsic_args!(fx, args => (ptr, val); intrinsic);
|
||||
let ptr = ptr.load_scalar(fx);
|
||||
|
||||
let ty = substs.type_at(0);
|
||||
let ty = generic_args.type_at(0);
|
||||
match ty.kind() {
|
||||
ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => {
|
||||
// FIXME implement 128bit atomics
|
||||
@ -1128,7 +1128,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
let lhs_ref = lhs_ref.load_scalar(fx);
|
||||
let rhs_ref = rhs_ref.load_scalar(fx);
|
||||
|
||||
let size = fx.layout_of(substs.type_at(0)).layout.size();
|
||||
let size = fx.layout_of(generic_args.type_at(0)).layout.size();
|
||||
// FIXME add and use emit_small_memcmp
|
||||
let is_eq_value = if size == Size::ZERO {
|
||||
// No bytes means they're trivially equal
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Codegen `extern "platform-intrinsic"` intrinsics.
|
||||
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::abi::Endian;
|
||||
|
||||
@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
|
||||
pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: Symbol,
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_args: GenericArgsRef<'tcx>,
|
||||
args: &[mir::Operand<'tcx>],
|
||||
ret: CPlace<'tcx>,
|
||||
target: BasicBlock,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::subst::GenericArg;
|
||||
use rustc_middle::ty::AssocKind;
|
||||
use rustc_middle::ty::GenericArg;
|
||||
use rustc_session::config::{sigpipe, EntryFnType};
|
||||
use rustc_span::symbol::Ident;
|
||||
|
||||
@ -119,7 +119,7 @@ fn create_entry_fn(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
report.def_id,
|
||||
tcx.mk_substs(&[GenericArg::from(main_ret_ty)]),
|
||||
tcx.mk_args(&[GenericArg::from(main_ret_ty)]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@ -146,7 +146,7 @@ fn create_entry_fn(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
tcx.mk_substs(&[main_ret_ty.into()]),
|
||||
tcx.mk_args(&[main_ret_ty.into()]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
|
@ -9,7 +9,7 @@
|
||||
//!
|
||||
//! function u0:22(i64) -> i8, i8 system_v {
|
||||
//! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd517c453d67c0915E
|
||||
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), substs: [ReErased, ReErased] }
|
||||
//! ; instance Instance { def: Item(WithOptConstParam { did: DefId(0:42 ~ example[4e51]::{impl#0}::call_once), const_param_did: None }), args: [ReErased, ReErased] }
|
||||
//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, abi: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, variants: Single { index: 0 } } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false }
|
||||
//!
|
||||
//! ; kind loc.idx param pass mode ty
|
||||
@ -25,7 +25,7 @@
|
||||
//!
|
||||
//! ss0 = explicit_slot 16
|
||||
//! sig0 = (i64, i64) -> i8, i8 system_v
|
||||
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), substs: [ReErased, ReErased] }
|
||||
//! fn0 = colocated u0:23 sig0 ; Instance { def: Item(WithOptConstParam { did: DefId(0:46 ~ example[4e51]::{impl#1}::call_mut), const_param_did: None }), args: [ReErased, ReErased] }
|
||||
//!
|
||||
//! block0(v0: i64):
|
||||
//! nop
|
||||
@ -261,7 +261,7 @@ pub(crate) fn write_clif_file(
|
||||
|
||||
impl fmt::Debug for FunctionCx<'_, '_, '_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{:?}", self.instance.substs)?;
|
||||
writeln!(f, "{:?}", self.instance.args)?;
|
||||
writeln!(f, "{:?}", self.local_map)?;
|
||||
|
||||
let mut clif = String::new();
|
||||
|
@ -850,11 +850,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
|
||||
(&ty::Adt(adt_def_a, args_a), &ty::Adt(adt_def_b, args_b))
|
||||
if adt_def_a.did() == adt_def_b.did() =>
|
||||
{
|
||||
let mut types_a = substs_a.types();
|
||||
let mut types_b = substs_b.types();
|
||||
let mut types_a = args_a.types();
|
||||
let mut types_b = args_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
@ -864,11 +864,11 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
}
|
||||
}
|
||||
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
|
||||
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
|
||||
(&ty::Closure(def_id_a, args_a), &ty::Closure(def_id_b, args_b))
|
||||
if def_id_a == def_id_b =>
|
||||
{
|
||||
let mut types_a = substs_a.types();
|
||||
let mut types_b = substs_b.types();
|
||||
let mut types_a = args_a.types();
|
||||
let mut types_b = args_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
|
Loading…
Reference in New Issue
Block a user