Than McIntosh [Thu, 16 Apr 2020 12:29:43 +0000 (08:29 -0400)]
[dev.link] cmd/link: set direct fn address in dwarf gen where possible
If we are internal linking a static executable, and address assignment
has happened, then when emitting some parts of DWARF we can just emit
a function address directly instead of generating a relocation. For
external linking or other build modes, we are generating a relocatable
binary so we still need to emit relocations.
This CL inspired by Cherry's similar CL for pclntab at
https://go-review.googlesource.com/c/go/+/228478.
Than McIntosh [Tue, 14 Apr 2020 19:14:54 +0000 (15:14 -0400)]
[dev.link] cmd/link: begin splitting up dodata()
Begin refactoring dodata to try to convert it from a single giant blob
to something more hierarchical, with descriptive function names for
sub-parts.
Add a state object to hold things like "data" and "dataMaxAlign"
arrays that are used throughout dodata. Extract out the code that
allocates data symbols to sections into a separate method (this
method is still too big, probably needs to be refactored again).
Robert Griesemer [Tue, 14 Apr 2020 04:57:41 +0000 (21:57 -0700)]
go/types: use same local variable consistently (minor cleanup)
Currently this CL has no effect because V == x.typ in the affected
code. But if we should ever manipulate V (e.g., to support some form
of lazy evaluation of the type), not using V consistently would
lead to a subtle bug.
Change-Id: I465e72d18bbd2b6cd8fcbd746e0d28d14f758c03
Reviewed-on: https://go-review.googlesource.com/c/go/+/228105
Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
time: quote original value in errors returned by ParseDuration
Quote original values passed as substring of ParseError.Message.
Improves the user experience of ParseDuration by making it
quote its original argument, for example:
_, err := time.ParseDuration("for breakfast")
will now produce an error, which when printed out is:
Adapt test cases for format.Parse and format.ParseDuration.
Fixes #38295
Change-Id: Ife322c8f3c859e1e4e8dd546d4cf0d519b4bfa81
Reviewed-on: https://go-review.googlesource.com/c/go/+/227878
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Ian Lance Taylor [Mon, 13 Apr 2020 23:26:39 +0000 (23:26 +0000)]
Revert "time/tzdata: new package"
This reverts CL 224588.
Reason for revert: Test failing on secondary platforms.
Change-Id: Ic15fdc73a0d2b860e776733abb82c58809e13160
Reviewed-on: https://go-review.googlesource.com/c/go/+/228200 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Eric [Mon, 13 Apr 2020 21:28:47 +0000 (21:28 +0000)]
io: simplify Examples
- CopyN: 5 creates ambiguity with respect to whitespace and upperbound
- TeeReader less boilerplate and displays a common usage of it
- SectionReader_* all sections unified to 5:17 for clarity
- SectionReader_Seek uses io.Copy to stdout like other examples
- Seeker_Seek remove useless prints
- Pipe print reader like other examples
Updates #36417
Change-Id: Ibd01761d5a5786cdb1ea934f7a98f8302430c8a5
GitHub-Last-Rev: 4c17f9a8e32d89743b7eaec7c52032256972cc0a
GitHub-Pull-Request: golang/go#38379
Reviewed-on: https://go-review.googlesource.com/c/go/+/227868
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
cmd/link: don't split container symbols when write blocks
We split the output into blocks and write them in parallel. The
block boundary is placed at symbol boundary. In the case of outer
symbols and sub symbols, currently we may split an outer symbol
into two blocks. This will be bad, as the two blocks will have
overlapping address range, since outer symbol and its sub symbols
occupies the same address range.
Make sure we place block boundary only at top-level symbol
boundaries.
Cherry Zhang [Fri, 24 Jan 2020 15:43:09 +0000 (10:43 -0500)]
cmd/compile: debug rewrite
If -d=ssa/PASS/debug=N is specified (N >= 2) for a rewrite pass
(e.g. lower), when a Value (or Block) is rewritten, print the
Value (or Block) before and after.
Ian Lance Taylor [Sun, 22 Mar 2020 01:28:16 +0000 (18:28 -0700)]
time/tzdata: new package
Importing the time/tzdata package will embed a copy of the IANA
timezone database into the program. This will let the program work
correctly when the timezone database is not available on the system.
It will increase the size of the binary by about 800K.
You can also build a program with -tags timetzdata to embed the
timezone database in the program being built.
Michael Pratt [Tue, 7 Apr 2020 19:17:25 +0000 (15:17 -0400)]
runtime/pprof: clarify recursive inline heuristic
Following CL 226818, the compiler will allow inlining a single cycle in
an inline chain. Immediately-recursive functions are still disallowed,
which is what this heuristic refers to.
Add a regression test for this case.
Note that in addition to this check, if the compiler were to inline
multiple cycles via a loop (i.e., rather than appending duplicate code),
much more work would be required here to handle a single address
appearing in multiple different inline frames.
Updates #29737
Change-Id: I88de15cfbeabb9c04381e1c12cc36778623132a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/227346
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Michael Pratt [Tue, 7 Apr 2020 16:12:44 +0000 (12:12 -0400)]
runtime/pprof: try to use real stack in TestTryAdd
TestTryAdd is particularly brittle because it tests some real cases by
constructing fake sample stack frames. If those frames don't correctly
represent what the runtime would generate then they may fail to catch
regressions.
Instead, call runtime.Callers at the bottom of real function calls to
generate real frames as a base for truncation, etc in tests. Several of
these tests still have to fake parts of the frames to test the right
thing, but this is a bit less fragile.
This change is equivalent to the original 0dfb0513ec6a0e97db166bd91a2dc0a1ceb154f7 (golang.org/cl/227484), except
that the test skips if the test functions aren't inline (e.g., noopt
builders).
Change-Id: Ie9e32b5660cfe28a924f9cfcddcd887ea2effd66
Reviewed-on: https://go-review.googlesource.com/c/go/+/227922
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
lib.Textp was used for text address assignment and trampoline
insertion. Now that it has been converted to using the loader,
no need to populate lib.Textp.
Port the logic of canonicalizing dupok symbol's package to the
loader.
unit.Textp was used for DWARF generation, which has also been
converted to using the loader.
Joel Sing [Mon, 13 Apr 2020 16:36:36 +0000 (02:36 +1000)]
cmd/compile: update TestIntendedInlining for riscv64
Mark nextFreeFast as not inline, as it is too expensive to inline on riscv64.
Also remove riscv64 from non-atomic inline architectures, as we now have
atomic intrisics.
Hana (Hyang-Ah) Kim [Fri, 10 Apr 2020 18:56:59 +0000 (14:56 -0400)]
cmd/trace: use the focustask mode for user task/region trace views
The taskid mode is based on the goroutine-oriented trace view,
which displays each goroutine as a separate row. This is good when
inspecting the interaction and timeline among related goroutines,
and the user region information (associated with each goroutine)
in detail, but when many goroutines are involved, this mode does
not scale.
The focustask mode is based on the default trace view with the
user task hierarchy at the top. Each row is a P and there are only
a handful number of Ps in most cases, so browsers can handle
this mode more gracefully. But, I had difficulty in displaying
the user region information (because a goroutine can start/stop/
migrate across Ps, and visualizing the stack of regions nicely
was complicated). It may be doable, but it's a work.
This CL surfaces the hidden focustask mode. Moreover, use it
as the default user task view mode. The taskid mode can be still
accessible through 'goroutine view' links.
Unlike taskid-based user annotation view that extends goroutine-based
trace view, the focustask view
Change-Id: Ib691a5e1dd14695fa70a0ae67bff62817025e8c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/227921 Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
HWCap and HWCap2 are no longer linknamed into package runtime. Also,
merge two sentences both starting with "These are..." and don't mention
any file name where archauxv is defined, as it become outdated if
support for a new $GOOS/$GOARCH combination is added. This is e.g.
already the case for arm64, where archauxv is also defined for
freebsd/arm64.
Change-Id: I9314a66633736b12e777869a832d8b79d442a6f8
Reviewed-on: https://go-review.googlesource.com/c/go/+/228057 Reviewed-by: Ian Lance Taylor <iant@golang.org>
The repository of delve has already switched from the personal
account github.com/derekparker/delve to the organization account
github.com/go-delve/delve. According to go-delve/delve#1456.
Change-Id: Ie64f72c2808a8aca5059a75e2c2f11d8691e66b3
GitHub-Last-Rev: f90120c3b33f2134a572a62aaf291aa2abe58749
GitHub-Pull-Request: golang/go#38387
Reviewed-on: https://go-review.googlesource.com/c/go/+/227999 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Joel Sing [Sun, 12 Apr 2020 16:47:11 +0000 (02:47 +1000)]
cmd/compile: run TestLogOpt for riscv64 on amd64
Run TestLogOpt for riscv64 on amd64, as is done for other architectures.
This would have caught the test failure on riscv64 introduced in 47ade08141b23cfeafed92943e16012d5dc5eb8b.
Change-Id: If29dea2ef383b087154d046728f6d1c96811f5a3
Reviewed-on: https://go-review.googlesource.com/c/go/+/227806
Run-TryBot: Joel Sing <joel@sing.id.au>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Than McIntosh [Sun, 12 Apr 2020 18:19:38 +0000 (14:19 -0400)]
[dev.link] cmd/link/internal/loader: get rid of the AttrContainer loader method
Remove the loader's AttrContainer method, since it is no longer
needed. All of the code in the linker that used s.Attr.Container() is
now upstream of loadlibfull(), and the code in question now uses local
bitmaps to keep track of container text symbols as opposed to loader
methods.
Than McIntosh [Fri, 10 Apr 2020 17:07:08 +0000 (13:07 -0400)]
[dev.link] cmd/link: convert inltree syms to anonymous in pclntab
The pclntab phase generates a series of "inltree.*" symbols with
inlining related pcdata; these symbols previously were given names and
enterered into the symbol lookup table, but there is no real reason to
do this, since they never need to be looked up when pcln generation is
done. Switch them over to anonymous symbols.
So as to insure that the later symtab phase picks them up correctly,
assign them a type of SGOFUNC instead of SRODATA, and change symtab to
look for this when assigning symbols to groups.
[dev.link] cmd/link: don't split container symbols when write blocks
We split the output into blocks and write them in parallel. The
block boundary is placed at symbol boundary. In the case of outer
symbols and sub symbols, currently we may split an outer symbol
into two blocks. This will be bad, as the two blocks will have
overlapping address range, since outer symbol and its sub symbols
occupies the same address range.
Make sure we place block boundary only at top-level symbol
boundaries.
cmd/compile: correct comment for len check when make slice
CL 226737 optimizes len check when make slice. The comment that cap is
constrainted to [0, 2^31) is not quite true, it's 31 or 63 depends on
whether it's 32/64-bit systems.
Change-Id: I6f54e41827ffe4d0b67a44975da3ce07b2fabbad
Reviewed-on: https://go-review.googlesource.com/c/go/+/227803
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Keith Randall [Fri, 10 Apr 2020 21:07:13 +0000 (14:07 -0700)]
cmd/link: turn ASLR off for netbsd+race
The race detector can't handle ASLR (adddress space layout randomization).
On some platforms it can re-exec the binary with ASLR off. But not NetBSD.
For NetBSD we have to introduce a special ELF header note that tells
the kernel not to use ASLR.
This works fine for internal linking. For external linking it also works,
but "readelf -n" shows multiple notes in the resulting binary. Maybe the
last one wins? Not sure, but it appears to work.
David Chase [Mon, 11 Nov 2019 18:18:38 +0000 (13:18 -0500)]
cmd/compile: add explanations to escape-analysis JSON/LSP logging
For 1.15.
From the test:
{"range":{"start":{"line":7,"character":13},"end":{...},"severity":3,"code":"leaks","source":"go compiler","message":"parameter z leaks to ~r2 with derefs=0","relatedInformation":[
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: flow: y = z:"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: from y = \u003cN\u003e (assign-pair)"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: flow: ~r1 = y:"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":4,"character":11},"end":{...}},"message":"inlineLoc"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: from y.b (dot of pointer)"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":4,"character":11},"end":{...}},"message":"inlineLoc"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: from \u0026y.b (address-of)"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":4,"character":9},"end":...}},"message":"inlineLoc"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":13},"end":{...}},"message":"escflow: from ~r1 = \u003cN\u003e (assign-pair)"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":3},"end":...}},"message":"escflow: flow: ~r2 = ~r1:"},
{"location":{"uri":"file://T/file.go","range":{"start":{"line":9,"character":3},"end":...}},"message":"escflow: from return (*int)(~r1) (return)"}]}
[dev.link] cmd/link: fix aux symbol handling in Funcdata
If a Go symbol is cloned to external, we should preserve its Aux
symbols for FuncInfo, etc.. We already do this in
loader.FuncInfo, but not in FuncInfo.Funcdata. Do it in the
latter as well. In fact, since FuncInfo and Funcdata should use
the same set of auxs, just record the auxs and reuse.
Should fix PPC64 build.
Change-Id: Iab9020eaca15d98fe3bb41f50f0d5bdb4999e8c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/227848 Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
Lynn Boger [Tue, 31 Mar 2020 14:08:29 +0000 (10:08 -0400)]
cmd/internal/obj/ppc64: add support for pcalign 32 on ppc64x
Previous PCALIGN support on ppc64x only accepted 8 and 16 byte
alignment since the default function alignment was 16. Now that
the function's alignment can be set to a larger value when needed,
PCALIGN can accept 32. When this happens then the function's
alignment will be changed to 32.
Test has been updated to recognized this new value.
Than McIntosh [Tue, 7 Apr 2020 21:08:00 +0000 (17:08 -0400)]
[dev.link] cmd/link: convert pcln linker phase to use loader APIs
Rework the linker's pcln phase to work with the new loader. As part of
this set of changes the handling of "go.file..." symbols has been
revised somewhat -- previously they were treated as always live in the
loader, and now we no longer do this.
The original plan had been to have the new implementation generate
nameless "inltree" symbols, however the plan now is to keep them
named for now and convert them to nameless in a subsequent patch.
Change-Id: If71c93ff1f146dbb63b6ee2546308acdc94b643c
Reviewed-on: https://go-review.googlesource.com/c/go/+/227759
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
Than McIntosh [Wed, 8 Apr 2020 15:56:43 +0000 (11:56 -0400)]
[dev.link] cmd/link/internal/loader: expand methods for FuncInfo
Expand the methods for the FuncInfo helper, to support reading the
contents of an object file FuncInfo aux symbol using the new style
(that is to say, incrementally and without allocating slices to hold
the various bits).
Andy Pan [Fri, 10 Apr 2020 02:45:58 +0000 (10:45 +0800)]
runtime: replace the type of netpollWakeSig from a uintptr to a uint32
There's no need for netpollWakeSig to use a uintptr type, a uint32 is enough.
Relevant CL: CL 212737
Change-Id: Ide24478b217a02bad62f7e000a9680c26a8c5366
Reviewed-on: https://go-review.googlesource.com/c/go/+/227798
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Keith Randall [Thu, 19 Mar 2020 23:25:08 +0000 (16:25 -0700)]
cmd/compile: start implementing strongly typed aux and auxint fields
Right now the Aux and AuxInt fields of ssa.Values are typed as
interface{} and int64, respectively. Each rule that uses these values
must cast them to the type they actually are (*obj.LSym, or int32, or
ValAndOff, etc.), use them, and then cast them back to interface{} or
int64.
We know for each opcode what the types of the Aux and AuxInt fields
should be. So let's modify the rule generator to declare the types to
be what we know they should be, autoconverting to and from the generic
types for us. That way we can make the rules more type safe.
It's difficult to make a single CL for this, so I've coopted the "=>"
token to indicate a rule that is strongly typed. "->" rules are
processed as before. That will let us migrate a few rules at a time in
separate CLs. Hopefully we can reach a state where all rules are
strongly typed and we can drop the distinction.
This CL changes just a few rules to get a feel for what this
transition would look like.
I've decided not to put explicit types in the rules. I think it
makes the rules somewhat clearer, but definitely more verbose.
In particular, the passthrough rules that don't modify the fields
in question are verbose for no real reason.
Change-Id: I63a1b789ac5702e7caf7934cd49f784235d1d73d
Reviewed-on: https://go-review.googlesource.com/c/go/+/190197
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
[dev.link] cmd/link: add methods for adding relocations in Reloc2 format
This is in prepration of removing the old loader.Reloc. This also
introduces a way of adding a slice of relocations more
efficiently (will be used in the next CL).
Than McIntosh [Fri, 13 Mar 2020 15:09:05 +0000 (11:09 -0400)]
test: deflaking measures for runtime gdb test
Tweak the runtime's GDB python test to try to reduce flake failures.
Background: the intent of the testpoint in question is to make sure
that python-supported commands like "info goroutines" or "goroutine 1
backtrace" work properly. The Go code being run under the debugger as
part of the test is single-threaded, but the test is written assuming
that in addition to the primary goroutine there will be other
background goroutines available (owned by the runtime). The flakiness
seems to crop up the most when requesting a backtrace for one of these
background goroutines; the speculation is that if we catch a
runtime-owned goroutine in an odd state, this could interfere with the
test.
The change in this patch is to explicitly start an additional
goroutine from the main thread, so that when the debugger stops the
main thread we can be sure that there is some other non-main goroutine
in a known state.
This change authored by Josh Bleecher Snyder <josharian@gmail.com>.
net: convert many Close tests to use parallel subtests
Also set a deadline in TestCloseWrite so that we can more easily
determine which kind of connection is getting stuck on the
darwin-arm64-corellium builder (#34837).
Change-Id: I8ccacbf436e8e493fb2298a79b17e0af8fc6eb81
Reviewed-on: https://go-review.googlesource.com/c/go/+/227588
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
cmd/compile: do not allocate bucket for non-escaping map
For map with hint larger than BUCKETSIZE, makemap ignore allocated
bucket and allocate buckets itself. So do not allocate bucket in
this case, save us the cost of zeroing+assignment to the bucket.
The previous change moved code around to create slicesym.
This change simplifies slicesym and its callsites
by accepting an int64 for lencap instead of a node,
and by removing all the calls to gdata.
It also stops modifying n,
which avoids the need to make a copy of it.
cmd/compile,runtime: pass only ptr and len to some runtime calls
Some runtime calls accept a slice, but only use ptr and len.
This change modifies most such routines to accept only ptr and len.
After this change, the only runtime calls that accept an unnecessary
cap arg are concatstrings and slicerunetostring.
Neither is particularly common, and both are complicated to modify.
Negligible compiler performance impact. Shrinks binaries a little.
There are only a few regressions; the one I investigated was
due to register allocation fluctuation.
Passes 'go test -race std cmd', modulo #38265 and #38266.
Wow, does that take a long time to run.
cmd/compile: handle some additional phis in shortcircuit
Prior to this change, the shortcircuit pass could only
handle blocks containing only a single phi control value,
possibly wrapped in some OpNot and OpCopy values.
This change partially lifts this limitation.
It handles some cases in which the block contains other phi values.
This appears to happen most commonly in cases in which
the conditionals being checked involve the memory state,
in which case there is a phi memory value in the block.
The general idea here is to use the information we have about
the CFG to (1) move the other phi values into other blocks
and/or (2) rewrite uses of the other phi values in other blocks.
For example, consider this CFG:
p q
\ /
b
/ \
t u
And consider a phi value v in block b.
We'll write v = Phi(p: x, q: y) to say that v has value x corresponding
to inbound block p, and value y for block q.
We will rewrite this CFG to:
p q
| /
| b
|/ \
t u
What should we do with v?
Any uses of v in u can be replaced with y. Why?
If we are in block u, we came from b, and before that from q.
If prior to b we came from p, then we would have gone to t, not u.
Since we came from q, we know that v took the value y.
Uses of v in t are a bit more complicated.
It is going to end up being a phi value: Phi(p: ?, b: ?).
Suppose, after the rewrite, we came from block p.
Then, before the rewrite, we would have gone to b,
where v would have the value x.
So we have Phi(p: x, b: ?).
Suppose, after the rewrite, we came from block b.
Then we must have come from block q.
If we come from block q, v has value y.
So we have Phi(p: x, b: y).
Uses of v in t can thus be replaced with a new phi value,
with the same values as v, but with altered predecessors.
Similar reasoning can be employed to rewrite or replace
other uses of v elsewhere in the CFG, so that v itself can be eliminated,
and the CFG rewrite can proceed.
This change sets up the infrastructure for such optimizations
and adds a few cheap ones. All optimizations in this change depend
only on the shape of the CFG; future changes may also depend on where
v's uses are. That analysis is more powerful but more expensive,
and should be done incrementally.
The use of closures here is perhaps a bit unusual,
but during development it proved critical to having readable code.
We must decide early on whether we can safely do the CFG modifications,
and then later fix up the phis if so.
Safely storing state and decisions across these two phases is hard to do readably.
Closures solve the problem neatly.
I manually instrumented the code paths in shortcircuitPhiPlan.
During make.bash there are nearly 6000 invocations.
The least-visited code path gets run 85 times,
so all the code in this CL is reasonably well-exercised.
Here is a concrete example of code improved by this change:
func f(e interface{}) int {
if x, ok := e.(int); ok {
return x
}
return 0
}
Omitting PCDATA, FUNCDATA, and the like, it used to compile to: