• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / 1285

25 Sep 2025 09:41PM UTC coverage: 70.929% (-6.0%) from 76.923%
1285

push

buildkite

web-flow
Fix gcdx and lcm with mixed signed/unsigned arguments (#59628)

Add `gcdx(a::Signed, b::Unsigned)` and `gcdx(a::Unsigned, b::Signed)`
methods to fix #58025:
```julia
julia> gcdx(UInt16(100), Int8(-101))  # pr
(0x0001, 0xffff, 0xffff)

julia> gcdx(UInt16(100), Int8(-101))  # master, incorrect result
(0x0005, 0xf855, 0x0003)
```

Also add the equivalent methods for `lcm` to fix the systematic
`InexactError` when one argument is a negative `Signed` and the other is
any `Unsigned`:
```julia
julia> lcm(UInt16(100), Int8(-101))  # pr
0x2774

julia> lcm(UInt16(100), Int8(-101))  # master, error
ERROR: InexactError: trunc(UInt16, -101)
Stacktrace:
 [1] throw_inexacterror(func::Symbol, to::Type, val::Int8)
   @ Core ./boot.jl:866
 [2] check_sign_bit
   @ ./boot.jl:872 [inlined]
 [3] toUInt16
   @ ./boot.jl:958 [inlined]
 [4] UInt16
   @ ./boot.jl:1011 [inlined]
 [5] convert
   @ ./number.jl:7 [inlined]
 [6] _promote
   @ ./promotion.jl:379 [inlined]
 [7] promote
   @ ./promotion.jl:404 [inlined]
 [8] lcm(a::UInt16, b::Int8)
   @ Base ./intfuncs.jl:152
 [9] top-level scope
   @ REPL[62]:1
```

Inspired by
https://github.com/JuliaLang/julia/pull/59487#issuecomment-3258209203.
The difference is that the solution proposed in this PR keeps the
current correct result type for inputs such as `(::Int16, ::UInt8)`.

10 of 10 new or added lines in 1 file covered. (100.0%)

4780 existing lines in 122 files now uncovered.

50633 of 71385 relevant lines covered (70.93%)

7422080.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.78
/stdlib/Markdown/src/parse/parse.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    MD
5

6
`MD` represents a Markdown document. Note that the `MD` constructor should not generally be
7
used directly, since it constructs the internal data structures. Instead, you can construct
8
`MD` objects using the exported macros [`@md_str`](@ref) and [`@doc_str`](@ref).
9
"""
10
mutable struct MD
11
    content::Vector{Any}
12
    meta::Dict{Symbol, Any}
13

14
    MD(content::AbstractVector, meta::Dict = Dict()) =
40✔
15
        new(content, meta)
16
end
17

18
MD(xs...) = MD(vcat(xs...))
6✔
19

20
function MD(cfg::Config, xs...)
3✔
21
    md = MD(xs...)
3✔
22
    md.meta[:config] = cfg
3✔
23
    return md
3✔
24
end
25

26
config(md::MD) = md.meta[:config]::Config
3✔
27

28
# Forward some array methods
29

30
Base.push!(md::MD, x) = push!(md.content, x)
3✔
31
Base.getindex(md::MD, args...) = md.content[args...]
×
32
Base.setindex!(md::MD, args...) = setindex!(md.content, args...)
×
33
Base.lastindex(md::MD) = lastindex(md.content)
×
34
Base.firstindex(md::MD) = firstindex(md.content)
×
UNCOV
35
Base.length(md::MD) = length(md.content)
×
UNCOV
36
Base.isempty(md::MD) = isempty(md.content)
×
UNCOV
37
Base.copy(md::MD) = MD(copy(md.content), copy(md.meta))
×
38

UNCOV
39
==(a::MD, b::MD) = (html(a) == html(b))
×
40

41
# Parser functions:
42
#   md – should be modified appropriately
43
#   return – basically, true if parse was successful
44
#     false uses the next parser in the queue, true
45
#     goes back to the beginning
46
#
47
# Inner parsers:
48
#   return – element to use or nothing
49

50
# Inner parsing
51

UNCOV
52
function parseinline(stream::IO, md::MD, parsers::Vector{Function})
×
UNCOV
53
    for parser in parsers
×
UNCOV
54
        inner = parser(stream, md)
×
UNCOV
55
        inner ≡ nothing || return inner
×
UNCOV
56
    end
×
57
end
58

59
function parseinline(stream::IO, md::MD, config::Config)
3✔
60
    content = []
3✔
61
    buffer = IOBuffer()
3✔
62
    while !eof(stream)
37✔
63
        char = peek(stream, Char)
34✔
64
        if haskey(config.inner, char) &&
34✔
65
                (inner = parseinline(stream, md, config.inner[char])) !== nothing
UNCOV
66
            c = takestring!(buffer)
×
UNCOV
67
            !isempty(c) && push!(content, c)
×
UNCOV
68
            buffer = IOBuffer()
×
UNCOV
69
            push!(content, inner)
×
70
        else
71
            write(buffer, read(stream, Char))
34✔
72
        end
73
    end
34✔
74
    c = takestring!(buffer)
3✔
75
    !isempty(c) && push!(content, c)
3✔
76
    return content
3✔
77
end
78

UNCOV
79
parseinline(s::AbstractString, md::MD, c::Config) =
×
80
    parseinline(IOBuffer(s), md, c)
81

82
parseinline(s, md::MD) = parseinline(s, md, config(md))
3✔
83

84
# Block parsing
85

86
function _parse(stream::IO, block::MD, config::Config; breaking = false)
12✔
87
    skipblank(stream)
6✔
88
    eof(stream) && return false
6✔
89
    for parser in (breaking ? config.breaking : [config.breaking; config.regular])
3✔
90
        parser(stream, block) && return true
39✔
91
    end
36✔
UNCOV
92
    return false
×
93
end
94

UNCOV
95
_parse(stream::IO, block::MD; breaking = false) =
×
96
    _parse(stream, block, config(block), breaking = breaking)
97

98
"""
99
    parse(stream::IO)::MD
100

101
Parse the content of `stream` as Julia-flavored Markdown text and return the corresponding `MD` object.
102
"""
103
function parse(stream::IO; flavor = julia)
3✔
104
    isa(flavor, Symbol) && (flavor = flavors[flavor])
3✔
105
    markdown = MD(flavor)
3✔
106
    while _parse(stream, markdown, flavor) end
6✔
107
    return markdown
3✔
108
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc