# Understanding behavior of function extension in 1.12

**URL:** <https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451>\
**Category:** General Usage\
**Created:** [October 27, 2025, 10:03am UTC](https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451 "2025-10-27T10:03:06Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [October 27, 2025, 10:03am UTC](https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451/1 "2025-10-27T10:03:06Z")

</div>

In one of my packages i get the following warning:

```julia-auto
┌ GraphMakie
│ WARNING: Constructor for type "Pointf" was extended in `GraphMakie` without explicit qualification or import.
│ NOTE: Assumed "Pointf" refers to `GeometryBasics.Pointf`. This behavior is deprecated and may differ in future versions.`
│ NOTE: This behavior may have differed in Julia versions prior to 1.12.
│ Hint: If you intended to create a new generic function of the same name, use `function Pointf end`.
│ Hint: To silence the warning, qualify `Pointf` as `GeometryBasics.Pointf` in the method signature or explicitly `import GeometryBasics: Pointf`.
└  

```

I am a bit confused by that. I think I introduced that function `Pointf` before it was exported from GeometryBasics. So I is (was) actually introduced as a module local binding. That behavior should not change when GeometryBasics introduced and exported a `Pointf` binding, because the docs are pretty clear about the fact that in order to extend a method you have to explicitly `import` it.

The warning however implies, that the code

```julia-auto
Pointf(p::StaticVector{N, T}) where {N,T} = Point{N, Float32}(p)

```

now extends `GeometryBasics.Pointf`, which would be type piracy.

What happend here? Also, the warning explicitly calls the method a “Constructor”, is the behavior different for functions which happens to have the same name as a struct and functions which don’t? I allways assumed that outer “constructors” are not special in any way.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 27, 2025, 10:18am UTC](https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451/2 "2025-10-27T10:18:18Z")

</div>

To make a MWE separate from your packages, this is what happens for typical functions:

```julia-auto
julia> module A
        export f
        function f end
       end
Main.A

julia> module B
        using ..A
        f() = "B"
       end
Main.B

julia> A.f === B.f
false

```

and this is what happens for typical types:

```julia-auto
julia> module A
        export f
        struct f end
       end
Main.A

julia> module B
        using ..A
        f() = "B"
       end
WARNING: Constructor for type "f" was extended in `B` without explicit qualification or import.
  NOTE: Assumed "f" refers to `A.f`. This behavior is deprecated and may differ in future versions.`
  NOTE: This behavior may have differed in Julia versions prior to 1.12.
  Hint: If you intended to create a new generic function of the same name, use `function f end`.
  Hint: To silence the warning, qualify `f` as `A.f` in the method signature or explicitly `import A: f`.
Main.B

julia> A.f === B.f
[ Warning: f is defined in Main.A and is not public in Main.B
true

```

`B.f` does not extend or “refer to” `A.f` either way in 1.11.7, so it’s strange it occurs now only to be “deprecated”.

---

<div class="post-metadata">

**Author:** ![hexaeder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hexaeder/32/24403_2.png) [@hexaeder](https://discourse.julialang.org/u/hexaeder)\
**Post date:** [October 27, 2025, 10:45am UTC](https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451/3 "2025-10-27T10:45:39Z")

</div>

Oh wow so it is actually both, a breaking change in 1.12 and a special handling of “constructor”-type functions.  
Well, yet another reason to never use implicit imports. In new packages I already use ExplicitImports.jl, but I guess we should be really updating all our packages..

Issue [#25744](https://github.com/JuliaLang/julia/issues/25744) implies, that “constructor” type methods could have been overwritten before without implicit import. But the MWE said otherwise:

```julia-auto
module A
    export Foo
    struct Foo
        x
    end
end
module B
    using ..A
    Foo(x::String) = "🏴‍☠️"
end

using ..A
using ..B
Foo("are you pirated?") # yes in 1.12, no in 1.11

```

EDIT: Reading [Add a warning for auto-import of types by Keno · Pull Request #57311 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/57311) it seems like a breakage was necessary in one or the other way, well, ExplicitImports will fix this.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 27, 2025, 11:33am UTC](https://discourse.julialang.org/t/understanding-behavior-of-function-extension-in-1-12/133451/4 "2025-10-27T11:33:40Z")

</div>

Yeah it’s bizarre. One thing with method definitions scattered across modules is already unusual, and it didn’t help that the import system and practices weren’t fully thought out by v1. It really bothers me that “all case 2” wasn’t chosen, but that’s the consequence of complexity and ambiguity.

This isn’t the only weird practical change with the `const` redefinition era. Although it being involved in world age was wanted forever, it also means that implicitly imported names via `using` are now reassigned by a local function definition instead of erroring:

```julia-auto
  | | |_| | | | (_| | | Version 1.11.7 (2025-09-08)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |

julia> module B
         export g
         g(x) = 1
       end; using .B

julia> g(0)
1

julia> g(x) = 10
ERROR: invalid method definition in Main: function B.g must be explicitly imported to be extended

```

```julia-auto
  | | |_| | | | (_| | | Version 1.12.1 (2025-10-17)
 _/ |\ __'_|_|_|\__'_| | Official https://julialang.org release
|__/ |

julia> module B
         export g
         g(x) = 1
       end; using .B

julia> g(0)
1

julia> g(x) = 10
g (generic function with 1 method)

julia> g(0), B.g(0) # changes to const variables are allowed now
(10, 1)

```

Explicit import via `using` still errors. Implicit imports are pretty necessary for end-users’ interactive work, but I can’t really justify method extensions or reassignments via imported names without qualifying the module object anymore, even interactively or with distinct renames. This was a common principle before to prevent unintended interference of local method definitions and an imported name, introduced in either order, but it just seems too dangerous now. Hopefully that makes it somehow into [2.0: just one import keyword · Issue #39235 · JuliaLang/julia](https://github.com/JuliaLang/julia/issues/39235), even if that stays hypothetical.
