Skip to content
← Back

src/syntax/process/narrowing/dropped_narrowing.ghul

1
namespace Syntax.Process is
2
use LOCATION = Source.LOCATION
3
use Symbol = Semantic.Symbols.Symbol
4
use Type = Semantic.Types.Type
5
6
// Why a use that names a member, or reads through a value that may
7
// be absent, is failing: the narrowing it would have needed was
8
// dropped earlier in this body, at a call the effect relations
9
// could not show left the value alone. The kill ledger holds every
10
// such drop of the walk, so the question is only which of them this
11
// use is short of, and the answer goes on the error as related
12
// information at the call.
13
class DROPPED_NARROWING is
14
// The call that dropped a type narrowing which would have made
15
// this member reachable. A drop of some other fact about the
16
// same value, or of a narrowing the member is missing from too,
17
// explains nothing and is not offered.
18
for_member(target: Symbol?, path: ACCESS_PATH?, name: string, at: LOCATION) -> KILL? static is
19
if !target? /\ !path? then
20
return null
21
fi
22
23
let kill = KILL_LEDGER.last_dropped_before(target, path, false, at)
24
25
if !kill? then
26
return null
27
fi
28
29
if let narrowed = kill.narrowed_type /\ _has_member(narrowed, name) then
30
return kill
31
fi
32
33
return null
34
si
35
36
// The call that dropped the presence of this value.
37
for_presence(target: Symbol?, path: ACCESS_PATH?, at: LOCATION) -> KILL? static is
38
if !target? /\ !path? then
39
return null
40
fi
41
42
return KILL_LEDGER.last_dropped_before(target, path, true, at)
43
si
44
45
// What to say at the call. One wording for both domains: a
46
// presence fact narrows an optional to the type it holds, which
47
// is what was lost as much as a type test's own narrower type.
48
message(kill: KILL) -> string static is
49
let what = if let target = kill.target then target.name elif let path = kill.path then path.to_string() else "the value" fi
50
51
if let narrowed = kill.narrowed_type then
52
"the narrowing of {what} to {narrowed} ended at this call"
53
else
54
"the narrowing of {what} ended at this call"
55
fi
56
si
57
58
_has_member(type: Type, name: string) -> bool static is
59
if let named: Semantic.Types.NAMED = type then
60
return named.find_member(name)?
61
fi
62
63
return false
64
si
65
si
66
si