Skip to content

Do not access owner type in dispatch if it is not passed at runtime - #17424

Open
HertzDevil wants to merge 1 commit into
crystal-lang:masterfrom
HertzDevil:bug/dispatch-top-level-self
Open

HertzDevil wants to merge 1 commit into
crystal-lang:masterfrom
HertzDevil:bug/dispatch-top-level-self

Conversation

@HertzDevil

Copy link
Copy Markdown
Contributor

When a call triggering method dispatch has no receiver, Crystal always generates code that accesses the current scope's type ID, even when that type is not passed as an argument at all, and therefore could not possibly affect method dispatch at runtime. Often those types are the top-level scope or a file-private scope:

def foo(x : Int32)
end

def foo(x : String)
end

private def bar(x)
  foo(x) # implicit self is the file-private scope
end

foo(1 || "a") # implicit self is the top-level scope
bar(1 || "a")

The access manifests as unused loads of newly allocated type IDs for those scopes: (the environment variable CRYSTAL_DUMP_TYPE_ID=1 could also reveal those type IDs)

@"main:type_id" = internal constant i32 78
@"/Users/quinton/crystal/crystal/usr/small.cr:type_id" = internal constant i32 79

define internal void @__crystal_main(i32 %argc, ptr %argv) {
  ; ...
  %4 = load i32, ptr @"main:type_id", align 4
  %5 = load i32, ptr @"main:type_id", align 4
  ; ...
}

define internal void @"*/Users/quinton/crystal/crystal/usr/small.cr::bar<(Int32 | String)>:Nil"(%"(Int32 | String)" %x) #0 {
  ; ...
  %0 = load i32, ptr @"/Users/quinton/crystal/crystal/usr/small.cr:type_id", align 4
  %1 = load i32, ptr @"/Users/quinton/crystal/crystal/usr/small.cr:type_id", align 4
  ; ...
}

These loads are strictly unnecessary, and more importantly, new type IDs should not be allocated at all during LLVM IR generation (more on this later). This PR ensures that the loads and type IDs are gone.

@HertzDevil HertzDevil added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:codegen labels Sep 15, 2026
Comment thread spec/compiler/codegen/def_spec.cr
Comment thread spec/compiler/codegen/def_spec.cr
@straight-shoota straight-shoota added this to the 1.22.0 milestone Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:codegen

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants