Updating tests in the style of
https://github.com/carbon-language/carbon-lang/pull/5455.
I'm leaving adapter_conversion.carbon pretty much as-is because of the
`adapt_i32.carbon` test, which I'm not clear how critical `i32` is there
but feels specific enough that maybe it can't be `min_prelude`. Other
tests felt all pretty reasonable to adjust to `min_prelude` and a single
file (`basics.carbon`).
Updating tests in the style of #5455.
array indexing requires integers, so this is a more prelude-dependent
area than some. But as it turns out, writing something like `3` never
references `Core.IntLiteral` so seeing if I can roll with more minimal
preludes.
This requires:
* Making `FunctionDecl` mutable since generating code
(`HandleTopLevelDecl()`) requires a mutable declaration and since we
manually add `used` attribute to force code generation.
* Passing the file system to `Lower` since it's needed by Clang code
generation.
* Creating an internal Clang LLVM module and link it against the Carbon
LLVM module.
Demo:
```c++
// hello_world.h
extern int puts;
inline void hello_world() {
((int (*)(const char*))&puts)("hello world");
}
```
```carbon
// main.carbon
library "Main";
import Cpp library "hello_world.h";
fn Run() -> i32 {
Cpp.hello_world();
return 0;
}
```
```shell
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link main.o --output=demo
$ ./demo
hello world
```
Based on https://github.com/carbon-language/carbon-lang/pull/5406.
Part of #5405.
- Track the `VarPattern` instruction on the `VarStorage` instruction so
that it's available for name mangling.
- Mangle global variables based on the first binding name within their
pattern.
- Give global variables external rather than internal linkage, except if
they have no bindings whatsoever in their pattern.
- To support lowering references to bindings nested within a global var,
such as for `var (x: i32, b: i32)`, add some basic initial support for
reference constant expressions. Treat a global `var` as a reference
constant, and treat an aggregate access into a reference constant as a
reference constant.
Taking a stab at restructuring towards allowing better reuse. Some of
that is with `AnyAggregateInit` and `AnyImportRef`. Some with
`FormatDeclRhs`.
This adds a `FormatArg` dispatch table so that `FormatInstRhs` doesn't
rely as heavily on templating. I'm mixed on the intermediate result -- a
step further might be to change `FormatArg` to dispatch to a
`FormatArgAndKind` that could use a switch. But, figured I'd check in on
the general direction.
Note this kind of direction opens up changing `FormatInst` to not be
templated, too, removing the `#define CARBON_SEM_IR_INST_KIND(InstT)`
variant of `FormatInst`.
I'm trying to make the offsetting a little easier to understand, and
also get a better `requires` structure on calls. The second is for an
attempt to refactor the `Formatter` API, but also changing the `InstId`
`derived_from` requires seems helpful for clarity on what's really
happening.
We make 5 changes:
- Allow `require Self impls I` in an `interface` or `constraint` scope
to omit the `Self`, so it can be written `require impls I`.
- Rename `extend I` to `extend require impls I` in an `interface` or
`constraint` scope.
- Define `extend impl as I` and `extend final impl as I` in an
`interface` scope to copy the members of `I` and define an `impl` of `I`
in terms of the extending interface.
- Allow a non-final `impl` to overlap a final `impl` as long as it isn't
subsumed by the final `impl`. The final `impl` will be given priority on
the overlap.
- Allow `final` on a `match_first` block, used to declare overlapping
final impls.
These features work together to allow a form of interface extension
where:
- Types only need to `impl` the extending interface to also get an
`impl` of the extended interface.
- Multiple interfaces can extend the same interface.
- An interface can extend multiple interfaces.
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This proposal re-affirms (with additional rationale) that a `var`
pattern
declares a durable complete object, and refines the terminology for
binding
patterns in a `var` pattern to be more explicit about the intended
semantics. It
also makes several other changes and clarifications to the semantics of
pattern
matching on objects:
- The storage for a variable pattern is initialized eagerly, rather than
being
deferred until the end of pattern matching.
- Any initializing expressions in the scrutinee of a `match` statement
are
materialized before matching the `case`s.
- An initializing expression can only initialize temporary storage or a
single
variable pattern, not a tuple/struct pattern or a subobject of a
variable
pattern. Removing this limitation is left as future work.
Finally, as a drive-by fix, it clarifies what parts of the `match`
design are
still placeholders.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
As far as I'm aware, the the devcontainers aren't in frequent use, which
is why they fall out of date. Comparing with
https://github.com/llvm/llvm-project/, I don't see devcontainer configs
maintained as part of llvm
(https://github.com/llvm/llvm-project/issues?q=devcontainer doesn't have
much either) so I think we should trim these instead of investing in
maintenance.
These configs aren't being maintained. In the docker configs, note `RUN
bazel build //explorer` is broken. Also, #5496 noted the clang version
is out of date.
Closes#5496
InstValueKind is really just wrapping HasTypeIdMember. Rather than
exposing this as an enum, expose it as a bool since it better reflects
what's going on.
In eval.cpp, AddImportedConstant should never be called on an untyped
instruction.
In FormatInstLhs, we can also depend on whether InstNamer has assigned a
name in order to decide whether to print an instruction. This should
avoid some divergence with CollectNamesInBlock.
We also discussed restoring InstValueKind::Untyped, but that's mainly
motivated by the formatter, and the InstNamer approach gives a more
localized implementation.
This restructures the import and merge logic to support parameter
patterns in a more scalable way.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
* Add // === headlines on group of file shards.
* Rename shard files to shorten given the file context them and add
`todo` where appropriate and group them together..
Doing a few things here, to sound people out on a broader test cleanup:
1. Adding `--dump-sem-ir-ranges=<value>` to all files.
- The default is currently `if-present`. I'd like to change the default
to `only` in tests. Always setting it both makes it clear which tests
have been looked at as part of cleanup, and makes changing the default a
simpler "remove" action (versus "find changed tests and add lines").
- I'm only using `if-present` in import tests; ranges would hide
imported instructions, but I think the imported instructions are more
relevant in those.
2. Removing `--no-dump-sem-ir` uses.
- `--dump-sem-ir-ranges=only` has similar results to `--no-dump-sem-ir`,
so this is partly consolidating.
- Relying on the "only" value allows for easier combining of test files
into splits.
3. Evaluating where splits may be used.
- Historically, we had to have each test be an individual file.
4. Preferring files with a split named `fail_` over files that use the
default name.
- I think this makes test files a little more consistently named, and
should ease the path if people want to add more split tests (vs pushing
people towards adding files).
- But I can switch back for single-split tests if the leaning is more
that we shouldn't repeat.
Specific to an `alias`, significant notes:
1. Consolidates several tests into a `basics.carbon` test.
- In there, adds a simple alias test; I didn't immediately see a trivial
test like that.
2. The "aliased_name_in_diag" test was no longer testing what it was
supposed to; however, there's "preserve_in_type_printing" so I'm
removing it as duplicative (vs switching to a min_prelude test).
3. Moves out a control flow test that didn't appear related to `alias`.
This is making two inter-related changes:
- Change `file` to reuse the formatter logic of `constants` and
`imports`, meaning empty `file` scopes will be omitted
- Mark `<elided>` sections in blocks (not in non-block scopes, because
they're not as sequential)
Trying to make repeated `std::same_as` easier to write. Calling it
"concepts.h" because I figure we'll maybe have a couple more things like
this.
Was looking at this because I may add a couple more similar constructs.
The `FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` flag is a standard flag
proposed by LibFuzzer that is meant to inform compiled code that it is
being built for fuzzing, as described here:
https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode
We add the flag to our `fuzzing` feature/config, and enable DCHECKs when
under fuzzing so that we can catch bugs that currently are caught on the
other side of DCHECK, even if they don't cause ASAN to trap a read/write
beyond the capacity of a value store.
When a `LookupImplWitness` instruction is created in a generic function
for a witness obtained from a `BindSymbolicName`, it stores the
`BindSymbolicName` as the query self type along with the interface it
obtained from it.
Later, when an argument is substituted into the `LookupImplWitness` in
deduction, and it is re-evaluated, the `BindSymbolicName` in the query
interface's specific arguments was being substituted, but the same
`BindSymbolicName` in the query self type was not. This was because we
did not substitute into the type of `BindSymbolicName`. In this case the
type is a `FacetType` which has inside it one or more specific
interfaces. The same substitution needs to be applied to both the
interfaces in the self type as to the interfaces in the query.
This issue was found by a fuzzer - though in a weirder and more invalid
way, by putting all of the code for our test case inside an `interface`,
which creates an implicit generic `Self` in the enclosing context and
yet makes it concrete inside a function body.
And update tests to clarify that we should be able to do lookup into a
runtime facet value for an associated constant if the FacetType itself
provides that constant (with a `where` clause), but should not be able
to if it does not.
This fixes a fuzzer-found crash.
A fuzzer found that converting a pointer to a `FunctionTypeWithSelfType`
to `type` does an impl lookup and ends up in TypeIterator with the
`FunctionTypeWithSelfType` being iterated over in the self type, where
we crash. It's a valid type, so the iterator should be able to walk over
and return it.
We also constructed a similar example for `FunctionType`.
* Add // === headlines on group of file shards.
* Rename shard files to shorten given the file context them and add
`todo` where appropriate.
Not splitting this file for now.
Part of #5150.
The Ubuntu 24 builders have a newer GLIBC than is present on the
compiler-explorer machines:
https://github.com/compiler-explorer/compiler-explorer/issues/7636#issuecomment-2880962252.
This results in the following error when running Carbon nightly:
```
/opt/compiler-explorer/carbon-trunk/bin/carbon: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by /opt/compiler-explorer/carbon-trunk/bin/carbon)
```
To resolve this, we need to build Carbon in a sysroot with a compatible
glibc version, and the most straightforward way to do that is to bump
our builders back down to Ubuntu 22.
To do that, we can't use apt.llvm.org again, since Ubuntu 22 is no
longer supported there. So we revert back to pulling a Linux X64 tarball
from the LLVM GitHub Releases page. Instead of getting an
ubuntu-specific tarball (which does not exist), we grab the generic
Linux one, which seems to work fine.
Note that the binaries in the LLVM release package appear to depend on
glibc version 2.34, as determined by `objdump -T bin/clang|grep GLIBC_|
sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | sort -Vu`, so these binaries should
hopefully be okay to package with the Carbon toolchain for the
compiler-explorer machines as well.
* Split to 4 files: `function_param_int16`, `function_param_int32`,
`function_param_unsupported.carbon`, `function_return`.
* Add // === headlines on group of file shards.
* Rename shard files to shorten them and make them more consistent given
the file context.
* Deduplicate identical .h files and group their tests.
Potential future improvements:
* Split further. For example, pointers and references might be somewhat
separate from int primitives.
* Remove `import_` shard file prefix, as it repeats itself, but leaving
for now as it makes it more explicit.
Part of #5263
I think this would probably have prevented the missed include in #5469
-- it would've just failed completely with a "missing prelude"
diagnostic.
Also note this excludes the included IR from output, because it's
probably low-value to print.
Instead of wrapping `ClassStart` with `StartOnly` or `StartWithEnd`,
provide both `ClassStart` and `ClassStartOnly`. Use inheritance to share
the fields. Initializing the subclass as an aggregate is still possible,
but requires an extra set of curlies.
This flattens the switch in TypeStructureBuilder::Build to a single
level.
Since this puts 19 elements in the Any variant, we need to extend the
CARBON_KIND_SWITCH support to more than 12 elements, so we bump it up to
24.
This was suggested by @jonmeow here:
https://github.com/carbon-language/carbon-lang/pull/5430#discussion_r2078444685
Teach CARBON_KIND_SWITCH to handle mutable lvalues and rvalues, and
CARBON_KIND to forward along rvalues so that it's possible to write
`case CARBON_KIND(const T& t)`, `case CARBON_KIND(T& t)`, and `case
CARBON_KIND(T&& t)`, depending on the type that was passed to
CARBON_KIND_SWITCH.
Replace all uses of VariantMatch with their equivalent of a switch using
CARBON_KIND_SWITCH, and remove the VariantMatch helper from the
codebase.
We were importing all impls as non-final, since we forgot to set the new
field when constructing the imported Impl. Adds a test that fails before
this PR, since the imported Impl is treated as non-final.
We use CARBON_KIND_SWITCH for handling the output of TypeIterator in the
TypeStructureBuilder
Here is how the errors look when it is misused:
- If you don't cover ever type in the variant with a case
```
Enumeration value 'VariantTypeT1NotHandledInSwitch' not handled in
switch
```
Is attached to the CARBON_KIND_SWITCH() usage, the `T1` being a 0-based
index into the std::variant's type list, indicating which type was
missed.
- If you have a case for a type that is not in the variant
```
In template: constraints not satisfied for class template
'ValidCaseType' [with T = char]
... bunch of instantiation stuff ...
kind_switch.h(124, 12): Because 'char' does not satisfy
'TypeFoundInVariant'
```
Where `char` was the type I put in the `CARBON_KIND` macro, which was
not in the variant.
- If you have too many types in your variant (currently > 12)
```
In template: static assertion failed due to requirement 'sizeof...(Ts)
<= 12': CARBON_KIND_SWITCH supports std::variant with up to 12 types.
Add more if needed.
```
Is attached to the CARBON_KIND_SWITCH() usage.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>