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

JuliaLang / julia / #37917

27 Sep 2024 02:34AM UTC coverage: 87.243% (-0.5%) from 87.72%
#37917

push

local

web-flow
inference: add missing `TypeVar` handling for `instanceof_tfunc` (#55884)

I thought these sort of problems had been addressed by d60f92c, but it
seems some were missed. Specifically, `t.a` and `t.b` from `t::Union`
could be `TypeVar`, and if they are passed to a subroutine or recursed
without being unwrapped or rewrapped, errors like JuliaLang/julia#55882
could occur.

This commit resolves the issue by calling `unwraptv` in the `Union`
handling within `instanceof_tfunc`. I also found a similar issue inside
`nfields_tfunc`, so that has also been fixed, and test cases have been
added. While I haven't been able to make up a test case specifically for
the fix in `instanceof_tfunc`, I have confirmed that this commit
certainly fixes the issue reported in JuliaLang/julia#55882.

- fixes JuliaLang/julia#55882

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

448 existing lines in 25 files now uncovered.

77170 of 88454 relevant lines covered (87.24%)

16041082.61 hits per line

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

86.0
/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()) =
33,104✔
15
        new(content, meta)
16
end
17

18
public MD
19

20
MD(xs...) = MD(vcat(xs...))
10,152✔
21

22
function MD(cfg::Config, xs...)
23
    md = MD(xs...)
9,889✔
24
    md.meta[:config] = cfg
9,889✔
25
    return md
9,889✔
26
end
27

28
config(md::MD) = md.meta[:config]::Config
42,888✔
29

30
# Forward some array methods
31

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

41
==(a::MD, b::MD) = (html(a) == html(b))
9✔
42

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

52
# Inner parsing
53

54
function parseinline(stream::IO, md::MD, parsers::Vector{Function})
47,675✔
55
    for parser in parsers
47,675✔
56
        inner = parser(stream, md)
54,782✔
57
        inner ≡ nothing || return inner
98,697✔
58
    end
10,867✔
59
end
60

61
function parseinline(stream::IO, md::MD, config::Config)
25,130✔
62
    content = []
25,130✔
63
    buffer = IOBuffer()
25,130✔
64
    while !eof(stream)
1,720,980✔
65
        char = peek(stream, Char)
1,695,850✔
66
        if haskey(config.inner, char) &&
1,743,525✔
67
                (inner = parseinline(stream, md, config.inner[char])) !== nothing
68
            c = String(take!(buffer))
78,991✔
69
            !isempty(c) && push!(content, c)
43,915✔
70
            buffer = IOBuffer()
43,915✔
71
            push!(content, inner)
43,915✔
72
        else
73
            write(buffer, read(stream, Char))
1,651,935✔
74
        end
75
    end
1,695,850✔
76
    c = String(take!(buffer))
43,067✔
77
    !isempty(c) && push!(content, c)
25,130✔
78
    return content
25,130✔
79
end
80

81
parseinline(s::AbstractString, md::MD, c::Config) =
7,516✔
82
    parseinline(IOBuffer(s), md, c)
83

84
parseinline(s, md::MD) = parseinline(s, md, config(md))
25,130✔
85

86
# Block parsing
87

88
function parse(stream::IO, block::MD, config::Config; breaking = false)
108,866✔
89
    skipblank(stream)
54,433✔
90
    eof(stream) && return false
54,433✔
91
    for parser in (breaking ? config.breaking : [config.breaking; config.regular])
44,544✔
92
        parser(stream, block) && return true
343,664✔
93
    end
315,032✔
94
    return false
15,912✔
95
end
96

97
parse(stream::IO, block::MD; breaking = false) =
32,746✔
98
    parse(stream, block, config(block), breaking = breaking)
99

100
function parse(stream::IO; flavor = julia)
19,778✔
101
    isa(flavor, Symbol) && (flavor = flavors[flavor])
80✔
102
    markdown = MD(flavor)
9,889✔
103
    while parse(stream, markdown, flavor) end
38,060✔
104
    return markdown
9,889✔
105
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

© 2025 Coveralls, Inc