De-@ trans contexts.

This commit is contained in:
Eduard Burtescu 2014-03-06 18:47:24 +02:00
parent 869c96dbf0
commit 6c42ef31dc
14 changed files with 70 additions and 72 deletions

View File

@ -15,7 +15,6 @@ use middle::astencode;
use middle::ty;
use middle::typeck::astconv;
use middle;
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
use syntax::ast::*;
@ -335,7 +334,6 @@ pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
-> Result<const_val, ~str> {
use middle::ty;
fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
match e.node {
ExprUnary(UnNeg, inner) => {

View File

@ -136,14 +136,14 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
}
pub struct StatRecorder<'a> {
ccx: @CrateContext<'a>,
ccx: &'a CrateContext<'a>,
name: Option<~str>,
start: u64,
istart: uint,
}
impl<'a> StatRecorder<'a> {
pub fn new(ccx: @CrateContext<'a>, name: ~str) -> StatRecorder<'a> {
pub fn new(ccx: &'a CrateContext<'a>, name: ~str) -> StatRecorder<'a> {
let start = if ccx.sess().trans_stats() {
time::precise_time_ns()
} else {
@ -528,7 +528,7 @@ pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: ~str) {
}
pub fn get_res_dtor(ccx: @CrateContext,
pub fn get_res_dtor(ccx: &CrateContext,
did: ast::DefId,
parent_id: ast::DefId,
substs: &[ty::t])
@ -1225,7 +1225,7 @@ pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t)
//
// Be warned! You must call `init_function` before doing anything with the
// returned function context.
pub fn new_fn_ctxt<'a>(ccx: @CrateContext<'a>,
pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext<'a>,
llfndecl: ValueRef,
id: ast::NodeId,
has_env: bool,
@ -1443,15 +1443,15 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
// trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be
// returned.
pub fn trans_closure<'a>(ccx: @CrateContext,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: <'b> |&'b Block<'b>| -> &'b Block<'b>) {
pub fn trans_closure(ccx: &CrateContext,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: <'a> |&'a Block<'a>| -> &'a Block<'a>) {
ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);
let _icx = push_ctxt("trans_closure");
@ -1543,7 +1543,7 @@ pub fn trans_closure<'a>(ccx: @CrateContext,
// trans_fn: creates an LLVM function corresponding to a source language
// function.
pub fn trans_fn(ccx: @CrateContext,
pub fn trans_fn(ccx: &CrateContext,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
@ -1558,7 +1558,7 @@ pub fn trans_fn(ccx: @CrateContext,
param_substs, id, attrs, output_type, |bcx| bcx);
}
pub fn trans_enum_variant(ccx: @CrateContext,
pub fn trans_enum_variant(ccx: &CrateContext,
_enum_id: ast::NodeId,
variant: &ast::Variant,
_args: &[ast::VariantArg],
@ -1575,7 +1575,7 @@ pub fn trans_enum_variant(ccx: @CrateContext,
llfndecl);
}
pub fn trans_tuple_struct(ccx: @CrateContext,
pub fn trans_tuple_struct(ccx: &CrateContext,
_fields: &[ast::StructField],
ctor_id: ast::NodeId,
param_substs: Option<@param_substs>,
@ -1590,7 +1590,7 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
llfndecl);
}
fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
ctor_id: ast::NodeId,
disr: ty::Disr,
param_substs: Option<@param_substs>,
@ -1647,8 +1647,8 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
finish_fn(&fcx, bcx);
}
pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::EnumDef,
id: ast::NodeId, vi: @Vec<@ty::VariantInfo> ,
pub fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
id: ast::NodeId, vi: @Vec<@ty::VariantInfo>,
i: &mut uint) {
for &variant in enum_definition.variants.iter() {
let disr_val = vi.get(*i).disr_val;
@ -1671,7 +1671,7 @@ pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::EnumDef,
}
pub struct TransItemVisitor<'a> {
ccx: @CrateContext<'a>,
ccx: &'a CrateContext<'a>,
}
impl<'a> Visitor<()> for TransItemVisitor<'a> {
@ -1680,7 +1680,7 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> {
}
}
pub fn trans_item(ccx: @CrateContext, item: &ast::Item) {
pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
let _icx = push_ctxt("trans_item");
match item.node {
ast::ItemFn(decl, purity, _abis, ref generics, body) => {
@ -1757,7 +1757,7 @@ pub fn trans_item(ccx: @CrateContext, item: &ast::Item) {
}
}
pub fn trans_struct_def(ccx: @CrateContext, struct_def: @ast::StructDef) {
pub fn trans_struct_def(ccx: &CrateContext, struct_def: @ast::StructDef) {
// If this is a tuple-like struct, translate the constructor.
match struct_def.ctor_id {
// We only need to translate a constructor if there are fields;
@ -1776,14 +1776,14 @@ pub fn trans_struct_def(ccx: @CrateContext, struct_def: @ast::StructDef) {
// separate modules in the compiled program. That's because modules exist
// only as a convenience for humans working with the code, to organize names
// and control visibility.
pub fn trans_mod(ccx: @CrateContext, m: &ast::Mod) {
pub fn trans_mod(ccx: &CrateContext, m: &ast::Mod) {
let _icx = push_ctxt("trans_mod");
for item in m.items.iter() {
trans_item(ccx, *item);
}
}
fn finish_register_fn(ccx: @CrateContext, sp: Span, sym: ~str, node_id: ast::NodeId,
fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: ~str, node_id: ast::NodeId,
llfn: ValueRef) {
{
let mut item_symbols = ccx.item_symbols.borrow_mut();
@ -1802,7 +1802,7 @@ fn finish_register_fn(ccx: @CrateContext, sp: Span, sym: ~str, node_id: ast::Nod
}
}
fn register_fn(ccx: @CrateContext,
fn register_fn(ccx: &CrateContext,
sp: Span,
sym: ~str,
node_id: ast::NodeId,
@ -1826,7 +1826,7 @@ fn register_fn(ccx: @CrateContext,
}
// only use this for foreign function ABIs and glue, use `register_fn` for Rust functions
pub fn register_fn_llvmty(ccx: @CrateContext,
pub fn register_fn_llvmty(ccx: &CrateContext,
sp: Span,
sym: ~str,
node_id: ast::NodeId,
@ -1849,7 +1849,7 @@ pub fn is_entry_fn(sess: &Session, node_id: ast::NodeId) -> bool {
// Create a _rust_main(args: ~[str]) function which will be called from the
// runtime rust_start function
pub fn create_entry_wrapper(ccx: @CrateContext,
pub fn create_entry_wrapper(ccx: &CrateContext,
_sp: Span,
main_llfn: ValueRef) {
let et = ccx.sess().entry_type.get().unwrap();
@ -1861,7 +1861,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
session::EntryNone => {} // Do nothing.
}
fn create_entry_fn(ccx: @CrateContext,
fn create_entry_fn(ccx: &CrateContext,
rust_main: ValueRef,
use_start_lang_item: bool) {
let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()],
@ -1941,7 +1941,7 @@ fn exported_name(ccx: &CrateContext, id: ast::NodeId,
}
}
pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
debug!("get_item_val(id=`{:?}`)", id);
let val = {
@ -2194,7 +2194,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
}
}
fn register_method(ccx: @CrateContext, id: ast::NodeId,
fn register_method(ccx: &CrateContext, id: ast::NodeId,
m: &ast::Method) -> ValueRef {
let mty = ty::node_id_to_type(ccx.tcx, id);
@ -2444,7 +2444,7 @@ pub fn decl_crate_map(sess: &Session, mapmeta: LinkMeta,
return (sym_name, map);
}
pub fn fill_crate_map(ccx: @CrateContext, map: ValueRef) {
pub fn fill_crate_map(ccx: &CrateContext, map: ValueRef) {
let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() {
Some(did) => unsafe {
if is_local(did) {
@ -2551,7 +2551,7 @@ pub fn trans_crate(krate: ast::Crate,
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
let llmod_id = link_meta.crateid.name + ".rs";
let ccx = @CrateContext::new(llmod_id,
let ccx = &CrateContext::new(llmod_id,
&analysis.ty_cx,
analysis.exp_map2,
analysis.maps,

View File

@ -409,7 +409,7 @@ pub fn trans_expr_fn<'a>(
bcx
}
pub fn get_wrapper_for_bare_fn(ccx: @CrateContext,
pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
closure_ty: ty::t,
def: ast::Def,
fn_ptr: ValueRef,

View File

@ -286,7 +286,7 @@ pub struct FunctionContext<'a> {
block_arena: &'a TypedArena<Block<'a>>,
// This function's enclosing crate context.
ccx: @CrateContext<'a>,
ccx: &'a CrateContext<'a>,
// Used and maintained by the debuginfo module.
debug_context: debuginfo::FunctionDebugContext,
@ -435,7 +435,7 @@ impl<'a> Block<'a> {
})
}
pub fn ccx(&self) -> @CrateContext<'a> { self.fcx.ccx }
pub fn ccx(&self) -> &'a CrateContext<'a> { self.fcx.ccx }
pub fn tcx(&self) -> &'a ty::ctxt {
self.fcx.ccx.tcx
}

View File

@ -89,7 +89,7 @@ pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
}
}
fn const_vec(cx: @CrateContext, e: &ast::Expr,
fn const_vec(cx: &CrateContext, e: &ast::Expr,
es: &[@ast::Expr], is_local: bool) -> (ValueRef, Type, bool) {
let vec_ty = ty::expr_ty(cx.tcx, e);
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
@ -160,7 +160,7 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
}
}
pub fn get_const_val(cx: @CrateContext,
pub fn get_const_val(cx: &CrateContext,
mut def_id: ast::DefId) -> (ValueRef, bool) {
let contains_key = {
let const_values = cx.const_values.borrow();
@ -185,7 +185,7 @@ pub fn get_const_val(cx: @CrateContext,
!non_inlineable_statics.get().contains(&def_id.node))
}
pub fn const_expr(cx: @CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool) {
pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool) {
let (llconst, inlineable) = const_expr_unadjusted(cx, e, is_local);
let mut llconst = llconst;
let mut inlineable = inlineable;
@ -298,7 +298,7 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
// the bool returned is whether this expression can be inlined into other crates
// if it's assigned to a static.
fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
is_local: bool) -> (ValueRef, bool) {
let map_list = |exprs: &[@ast::Expr]| {
exprs.iter().map(|&e| const_expr(cx, e, is_local))
@ -694,7 +694,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
}
}
pub fn trans_const(ccx: @CrateContext, m: ast::Mutability, id: ast::NodeId) {
pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
unsafe {
let _icx = push_ctxt("trans_const");
let g = base::get_item_val(ccx, id);

View File

@ -709,7 +709,7 @@ impl<'a> DatumBlock<'a, Expr> {
self.datum.shallow_copy(self.bcx, dst)
}
pub fn ccx(&self) -> @CrateContext<'a> {
pub fn ccx(&self) -> &'a CrateContext<'a> {
self.bcx.ccx()
}

View File

@ -253,7 +253,7 @@ enum VariableKind {
}
/// Create any deferred debug metadata nodes
pub fn finalize(cx: @CrateContext) {
pub fn finalize(cx: &CrateContext) {
if cx.dbg_cx.is_none() {
return;
}

View File

@ -548,7 +548,7 @@ fn trans_def<'a>(bcx: &'a Block<'a>,
ast::DefStatic(did, _) => {
let const_ty = expr_ty(bcx, ref_expr);
fn get_did(ccx: @CrateContext, did: ast::DefId)
fn get_did(ccx: &CrateContext, did: ast::DefId)
-> ast::DefId {
if did.krate != ast::LOCAL_CRATE {
inline::maybe_instantiate_inline(ccx, did)

View File

@ -132,8 +132,8 @@ pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
}
}
pub fn register_static(ccx: @CrateContext,
foreign_item: @ast::ForeignItem) -> ValueRef {
pub fn register_static(ccx: &CrateContext,
foreign_item: &ast::ForeignItem) -> ValueRef {
let ty = ty::node_id_to_type(ccx.tcx, foreign_item.id);
let llty = type_of::type_of(ccx, ty);
@ -145,7 +145,7 @@ pub fn register_static(ccx: @CrateContext,
// library then we've already declared the crate map
// so use that instead.
if attr::contains_name(foreign_item.attrs.as_slice(), "crate_map") {
return if ccx.sess.building_library.get() {
return if ccx.sess().building_library.get() {
let s = "_rust_crate_map_toplevel";
let g = unsafe {
s.with_c_str(|buf| {
@ -171,15 +171,15 @@ pub fn register_static(ccx: @CrateContext,
let linkage = match llvm_linkage_by_name(name.get()) {
Some(linkage) => linkage,
None => {
ccx.sess.span_fatal(foreign_item.span,
"invalid linkage specified");
ccx.sess().span_fatal(foreign_item.span,
"invalid linkage specified");
}
};
let llty2 = match ty::get(ty).sty {
ty::ty_ptr(ref mt) => type_of::type_of(ccx, mt.ty),
_ => {
ccx.sess.span_fatal(foreign_item.span,
"must have type `*T` or `*mut T`");
ccx.sess().span_fatal(foreign_item.span,
"must have type `*T` or `*mut T`");
}
};
unsafe {
@ -205,8 +205,8 @@ pub fn register_static(ccx: @CrateContext,
}
}
pub fn register_foreign_item_fn(ccx: @CrateContext, abis: AbiSet,
foreign_item: @ast::ForeignItem) -> ValueRef {
pub fn register_foreign_item_fn(ccx: &CrateContext, abis: AbiSet,
foreign_item: &ast::ForeignItem) -> ValueRef {
/*!
* Registers a foreign function found in a library.
* Just adds a LLVM global.
@ -455,7 +455,7 @@ pub fn trans_native_call<'a>(
return bcx;
}
pub fn trans_foreign_mod(ccx: @CrateContext, foreign_mod: &ast::ForeignMod) {
pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
let _icx = push_ctxt("foreign::trans_foreign_mod");
for &foreign_item in foreign_mod.items.iter() {
match foreign_item.node {
@ -499,7 +499,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext, foreign_mod: &ast::ForeignMod) {
// inline the one into the other. Of course we could just generate the
// correct code in the first place, but this is much simpler.
pub fn register_rust_fn_with_foreign_abi(ccx: @CrateContext,
pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
sp: Span,
sym: ~str,
node_id: ast::NodeId)
@ -523,7 +523,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: @CrateContext,
llfn
}
pub fn trans_rust_fn_with_foreign_abi(ccx: @CrateContext,
pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
decl: &ast::FnDecl,
body: &ast::Block,
attrs: &[ast::Attribute],
@ -540,7 +540,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @CrateContext,
return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys);
}
fn build_rust_fn(ccx: @CrateContext,
fn build_rust_fn(ccx: &CrateContext,
decl: &ast::FnDecl,
body: &ast::Block,
attrs: &[ast::Attribute],
@ -584,7 +584,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @CrateContext,
llfn
}
unsafe fn build_wrap_fn(ccx: @CrateContext,
unsafe fn build_wrap_fn(ccx: &CrateContext,
llrustfn: ValueRef,
llwrapfn: ValueRef,
tys: &ForeignTypes) {
@ -824,7 +824,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @CrateContext,
// This code is kind of a confused mess and needs to be reworked given
// the massive simplifications that have occurred.
pub fn link_name(i: @ast::ForeignItem) -> InternedString {
pub fn link_name(i: &ast::ForeignItem) -> InternedString {
match attr::first_attr_value_str_by_name(i.attrs.as_slice(),
"link_name") {
None => token::get_ident(i.ident),

View File

@ -126,7 +126,7 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
drop_ty(bcx, vp, t)
}
pub fn get_drop_glue(ccx: @CrateContext, t: ty::t) -> ValueRef {
pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef {
let t = get_drop_glue_type(ccx, t);
{
let drop_glues = ccx.drop_glues.borrow();
@ -149,7 +149,7 @@ pub fn get_drop_glue(ccx: @CrateContext, t: ty::t) -> ValueRef {
glue
}
pub fn lazily_emit_visit_glue(ccx: @CrateContext, ti: @tydesc_info) {
pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: @tydesc_info) {
let _icx = push_ctxt("lazily_emit_visit_glue");
let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to());
@ -444,7 +444,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
return llfn;
}
fn make_generic_glue(ccx: @CrateContext,
fn make_generic_glue(ccx: &CrateContext,
t: ty::t,
llfn: ValueRef,
helper: <'a> |&'a Block<'a>, ValueRef, ty::t|
@ -478,7 +478,7 @@ fn make_generic_glue(ccx: @CrateContext,
llfn
}
pub fn emit_tydescs(ccx: @CrateContext) {
pub fn emit_tydescs(ccx: &CrateContext) {
let _icx = push_ctxt("emit_tydescs");
// As of this point, allow no more tydescs to be created.
ccx.finished_tydescs.set(true);

View File

@ -19,7 +19,7 @@ use syntax::ast;
use syntax::ast_util::local_def;
use syntax::attr;
pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::DefId)
pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
-> ast::DefId {
let _icx = push_ctxt("maybe_instantiate_inline");
{

View File

@ -31,7 +31,7 @@ use syntax::ast_map;
use syntax::parse::token;
use util::ppaux::ty_to_str;
pub fn get_simple_intrinsic(ccx: @CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
let name = match token::get_ident(item.ident).get() {
"sqrtf32" => "llvm.sqrt.f32",
"sqrtf64" => "llvm.sqrt.f64",
@ -83,7 +83,7 @@ pub fn get_simple_intrinsic(ccx: @CrateContext, item: &ast::ForeignItem) -> Opti
Some(ccx.intrinsics.get_copy(&name))
}
pub fn trans_intrinsic(ccx: @CrateContext,
pub fn trans_intrinsic(ccx: &CrateContext,
decl: ValueRef,
item: &ast::ForeignItem,
substs: @param_substs,

View File

@ -45,7 +45,7 @@ for non-monomorphized methods only. Other methods will
be generated once they are invoked with specific type parameters,
see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/
pub fn trans_impl(ccx: @CrateContext,
pub fn trans_impl(ccx: &CrateContext,
name: ast::Ident,
methods: &[@ast::Method],
generics: &ast::Generics,
@ -84,7 +84,7 @@ pub fn trans_impl(ccx: @CrateContext,
/// type parameters and so forth, else None
/// * `llfn`: the LLVM ValueRef for the method
///
pub fn trans_method(ccx: @CrateContext, method: &ast::Method,
pub fn trans_method(ccx: &CrateContext, method: &ast::Method,
param_substs: Option<@param_substs>,
llfn: ValueRef) -> ValueRef {
trans_fn(ccx, method.decl, method.body,
@ -445,7 +445,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
};
}
pub fn vtable_id(ccx: @CrateContext,
pub fn vtable_id(ccx: &CrateContext,
origin: &typeck::vtable_origin)
-> mono_id {
match origin {

View File

@ -28,7 +28,7 @@ use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::local_def;
pub fn monomorphic_fn(ccx: @CrateContext,
pub fn monomorphic_fn(ccx: &CrateContext,
fn_id: ast::DefId,
real_substs: &ty::substs,
vtables: Option<typeck::vtable_res>,
@ -294,7 +294,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
(lldecl, must_cast)
}
pub fn make_mono_id(ccx: @CrateContext,
pub fn make_mono_id(ccx: &CrateContext,
item: ast::DefId,
substs: &param_substs) -> mono_id {
// FIXME (possibly #5801): Need a lot of type hints to get