Compare commits

...
Author SHA1 Message Date
Chandler Carruth 08a11ff3ef Avoid passing -unwindlib on macOS where it isn't needed (#7825)
Removes some warnings from our links on macs when the flag is ignored.
2026-09-24 13:51:02 +00:00
Christopher Di Bella f7cd39428e Add Destroy.SubobjectDestroy as a temporary replacement for Destroy.Op (#7773)
This change partially implements [PR #7362], which revises how objects
are destroyed. It is a partial implementation for two reasons:

1. This change moves `Destroy.Op`'s current behaviour into
`Destroy.SubobjectDestroy`, but it doesn't add support for objects with
non-trivial destruction.
2. `Destroy.SubobjectDestroy` is a workaround for `require impls
SubobjectDestroy`. We aren't able to use the latter until the dependents
add their requirements' implementations to their own witness tables.

[PR #7362]: https://github.com/carbon-language/carbon-lang/pulls/7362
2026-09-24 00:06:28 +00:00
Richard Smith 03939a9223 Add language server support for SemIR in testdata. (#7803)
Add hover cards and jump to declaration / definition / reference for the
formatted SemIR that appears in check tests. This is done by adding a
heuristic "parser" for SemIR to the language server. The
cross-references are strictly best-effort, since this is just a tool for
Carbon developers, not a user-facing facility.

A couple of other changes made along the way:

* file_test tests with an AUTOUPDATE-SPLIT no longer look for CHECK:
lines outside that split. This was motivated by the tests for this new
facility including CHECK: lines as part of the test input.
* An agent skill for working on the language server, tracking some
things that cost Claude time when working on this.

Assisted-by: Claude via Antigravity
2026-09-23 23:44:32 +00:00
Chandler Carruth 652e0ce7d0 Fix the jj_push.sh script to work on macOS (#7820)
It had a few subtle GNU extensions in it that didn't work on macOS.
There are simple portable alternatives so it was easy to adapt.

Assisted-by: Antigravity with Gemini
2026-09-23 22:47:02 +00:00
Dana Jansens c832d7c11c Skill file for reviewing filetest output changes (#7815)
When an LLM tool is used to prototype a change, one of the major tasks
it must undertake is validating filetest output changes. This skill
helps to ground that validation in some best practices and explain what
sorts of changes should or should not be expected, and how to judge
STDOUT vs STDERR changes.

Assisted-by: Opus 5
2026-09-23 19:18:59 +00:00
Dana Jansens 15e3eeaca9 Only look in facet types for name scopes when they have constraints (#7819)
This falls back to diagnosing that values of type `type` can not be used
for name lookup more consistently.
2026-09-23 17:50:34 +00:00
Richard Smith efbe1d2489 Add default fns and final fns to the eval block for a generic impl (#7817)
When a generic impl uses a default or final fn, it picks the specific
function value out of the interface to put in the witness table.
However, because this is done by modifying an existing instruction
block, the generics machinery has no hook to convert the function
constant into an attached constant, and because it was found in a
specific for a different generic, the constant inst will be unattached.
Fix this by manually mapping to an attached constant inst in the current
generic when building the witness table.
2026-09-23 01:19:28 +00:00
Lucile Rose Nihlen 53b7cfbaba Add basic caller-side support for default values in check (#7800)
Modifies the arity check to include a lower-bound for arguments.
Adds logic to pattern matching to supply default arguments for
missing parameters.
2026-09-22 22:07:35 +00:00
Dana Jansens 795729bb4a Fix git path globs in summarize testdata changes SKILL (#7818)
When there's a wildcard in a path, git treats the path as matching
exactly, unless the path also ends in a wildcard. So
`toolchain/*/testdata` only matches the testdata directory names,
whereas `toolchain/*/testdata/*` matches all the files under them.
2026-09-22 17:23:11 +00:00
Dana Jansens fcae9610bd Make SemIR::TypeType be an empty FacetType instruction (#7813)
The type `type` is now a `FacetType` inst with no constraints. This
brings the model implemented in the toolchain into better alignment with
the language design. The `SemIR::TypeType` struct remains as a scope for
holding the `TypeInstId`, `ConstantId`, and `TypeId` constants, but is
not an `InstKind` anymore.

The `TypeType` inst looks a lot like singletons, but there are many
`FacetType` insts so it doesn't quite fit that model. So we put it
alongside singletons with a fixed inst id but refer to it as a more
general "builtin" inst that is not a singleton.
`Namespace::PackageInstId` is similar, and we group it with `TypeType`
conceptually as another builtin instruction with a fixed id.

No conversion is needed anymore to use a `type` as a facet, since types
also have a `FacetType` type. This simplifies and removes a number of
helpers and branches throughout the code.

The `TypeType` inst is now part of the constant store, so we end up
printing it in the constants block in every test. But it's also named
`type` rather than `%type` to preserve the majority of existing
formatting behaviour, though this does look different from other
constants.

Assisted-by: Opus 5 was used to generate a first draft and validate the
refactoring. Though nearly everything non-trivial the tool wrote has
been modified or rewritten.
2026-09-22 15:04:40 +00:00
Lucile Rose Nihlen 83ca5b71e3 Move default value inst ids to a dedicated value store. (#7810)
Per #7737 we move the default value `InstId` storage from
a block in the `SemIR::Function` data structure to a
`SemIR::File` scoped `ValueStore`.

Moves the default value consistency checking to the general
merge argument pattern matching logic, which changes the
error message issued to the generic one.
2026-09-21 18:27:01 +00:00
Dana Jansens fa12d9ded2 Skill file docs about how to write prose, names, and to prioritize the data model (#7814)
Largely about writing less, and defining what is worth talking about and
what is not.
2026-09-21 17:48:35 +00:00
1010 changed files with 65413 additions and 23830 deletions
+81
View File
@@ -33,6 +33,87 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- **Python**: Use `pre-commit run black --files <file.py>` to format Python
files.
## Comments
- **Describe the code that is there.** A comment should explain what the
current code does or why it is the way it is, not narrate what the code used
to be. Do not add a comment to justify a deletion or explain that something
is no longer necessary; a reader of the new code has no idea what is being
contrasted against, and the comment rots as soon as the old shape is
forgotten. Put that reasoning in the commit message instead.
- **Do not introduce a local variable just to host a comment.** If a call
argument reads clearly on its own, inline it rather than naming it so that a
comment has somewhere to attach.
- **Lead with a plain summary.** Start a doc comment with a direct statement
of what the function does or returns, such as "Returns true if the InstKind
is a singleton." Put nuance in a following sentence rather than qualifying
the summary into something harder to read.
- **Re-read a comment before updating it.** When a symbol is renamed or
changes meaning, a comment that mentions it is not automatically stale. Work
out what the comment actually asserts first: it may be describing what the
code _uses_, which is still true, and rewriting it loses information.
## Documentation
This covers standalone prose: `/docs`, `README.md` files, and the skill files
under `.agents/skills`.
- **Be true of the tree it lands in.** Documentation shipping in the same
commit as the code it describes should name that code freely. Documentation
that lands separately must not: a reader who greps for an identifier from an
unlanded change finds nothing, and a claim that only holds after that change
is false until it lands. This is easy to get wrong when writing up a lesson
while the change that taught it is still in flight.
- **Use placeholders for illustrations.** When an example only needs to show a
shape, name it `Foo` rather than reaching for a real symbol. Save real
identifiers for documenting that identifier, where going stale is at least
detectable.
- **Make each point stand alone.** A reader has none of the discussion that
produced it. State the rule, and enough of the reason to apply it, without
assuming knowledge of the change that motivated it.
## Naming
- **A name is a claim, so keep it true.** When a change invalidates the
invariant a name describes, rename it in the same change. A factory called
`MakeSingletonFooId` has to be renamed once `Foo` is no longer a singleton,
even though nothing forces you to.
- **Types in a signature are part of the claim.** A function returning the id
of a namespace should return `InstId`, not `TypeInstId`, because a namespace
is not a type. Do not let a convenient wider or narrower id type imply
something false.
- **Delete a predicate whose name stops distinguishing anything.** If a change
widens a test so that it no longer says what its name implies, remove it and
let callers use the underlying test, rather than keeping a wrapper that
sounds meaningful. What callers actually want is often the inverse, and is
worth adding under its own name.
- **Name a variable for its role, not its representation.** If the role a
value plays is unchanged, keep its name even when a change means it is now
held or spelled differently.
## Commit descriptions
- **Say what the change is, not how you made it.** Describe the resulting
code. Only describe process when the process is more interesting than the
change, as with a large mechanical transformation.
- **Do not narrate your own work.** Statements like "each such site was
audited" or "we investigated every caller" describe effort, not the change.
- **Omit routine mechanical steps.** Do not mention running the testdata
autoupdater or the formatter. Every change is expected to include those.
- **Do not enumerate each edit.** Describe the change as a whole rather than
listing every function or file touched; the diff already lists them.
- **Use the project's terms precisely.** Reach for the term of art the
codebase uses. Calling something a "type alias" or a "namespace" when it is
a named scope misleads, and is worse than a vaguer but accurate word.
- **Scope claims to what changed.** Say the specific thing that is now true,
rather than a broader statement that happens to contain it.
## Design
- **Do not distort the data model to improve output.** If printed or golden
output is undesirable, change the printer, not the data structures that
feed it.
## Style Guides
- **C++ style**: Follow the
+197
View File
@@ -0,0 +1,197 @@
---
name: Language server
description:
Instructions for working on Carbon's LSP language server, including its
architecture, its file_test-based tests, and the VS Code extension.
---
# Language server
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## Introduction
This skill covers [`toolchain/language_server/`](/toolchain/language_server/),
which implements `carbon language-server`, and
[`utils/vscode/`](/utils/vscode/), the VS Code extension that launches it.
## Architecture
The server is built on clangd's LSP transport (`clang::clangd`), not on a
Carbon-specific one. That means clangd's `Protocol.h` types (`Position`,
`Range`, `Location`, `Hover`, `MarkupContent`) are the interface currency.
- `server.cpp` / `incoming_messages.cpp`: message dispatch. A handler must be
registered in `incoming_messages.cpp` before it can be called.
- `handle_*.cpp`: one file per request family, each declaring its entry point
in `handle.h`.
- `handle_initialize.cpp`: the advertised capabilities. **Adding a capability
changes `Content-Length` in every test that calls `initialize`**, so expect
a large autoupdate diff.
- `context.h` / `context.cpp`: `Context::File` per open document, plus the
compile driver. `Context::File::unit()` has a `CARBON_CHECK` on the compile
driver, so any handler that reaches for the parse tree must first rule out
documents that were never compiled.
- `position.h`, `sem_ir_index.h`: mapping source positions to SemIR
instructions for real Carbon files.
- `sem_ir_text.h`, `handle_sem_ir_text.h`: navigation within the *formatted
SemIR* in a test file's `// CHECK:STDOUT:` lines. This is a heuristic text
index, deliberately independent of the real SemIR data structures. See
[the SemIR text reader](#the-semir-text-reader).
### Document kinds
The server handles two kinds of document, distinguished by the `languageId`
from `textDocument/didOpen`, with a content sniff as a fallback:
- `carbon`: a real Carbon file. Compiled; diagnostics published.
- `carbon-testdata`: a test file. **Not compiled**, because we lack logic to
split it into one file per `// ---` split marker.
> [!IMPORTANT]
> A handler that assumes every file was compiled will crash on a test file.
> When adding one, give the test-file path an explicit early return.
## Tests
There is **no language-server-specific test target**.
`toolchain/language_server/BUILD` only declares
`filegroup(name = "testdata")`, which is pulled into
`//toolchain/testing:all_testdata` and run by `//toolchain/testing:file_test`.
```bash
# Run just the language server tests (or any subset).
bazelisk test //toolchain/testing:file_test \
--test_arg=--file_tests=toolchain/language_server/testdata/position/hover_and_goto.carbon
# See the raw output, which is much easier to read than a test failure.
bazelisk run //toolchain/testing:file_test -- --dump_output \
--file_tests=toolchain/language_server/testdata/position/hover_and_goto.carbon
# Update expectations. Never hand-write CHECK lines.
./toolchain/autoupdate_testdata.py toolchain/language_server/testdata/...
```
These tests run serially, because clangd's logging is a global singleton.
### Test file shape
The request stream is a `// --- STDIN` split written with the `[[@LSP-*]]`
keywords, and the responses land in a trailing `// --- AUTOUPDATE-SPLIT`.
Documents come from other splits by way of `"text": "FROM_FILE_SPLIT"`, which
is substituted with the content of the split whose name matches the `uri`.
```carbon
// --- position.carbon
fn Abs(n: i32) -> i32 { return n; }
// --- STDIN
[[@LSP-CALL:initialize:"capabilities": {}]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {
"uri": "file:/position.carbon",
"languageId": "carbon",
"text": "FROM_FILE_SPLIT"
}
]]
[[@LSP-CALL:textDocument/hover:
"textDocument": {"uri": "file:/position.carbon"},
"position": {"line": 0, "character": 3}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
```
Full keyword documentation is in
[`testing/file_test/README.md`](/testing/file_test/README.md).
### Traps
> [!WARNING]
> **A blank line inside the `STDIN` split breaks the JSON transport.** It
> terminates a header block, so clangd logs a timestamped
> `Warning: Missing Content-Length header, or zero-length message.` The
> timestamp makes the test unreproducible, so it fails on the next run.
> Comment lines between messages are fine; blank lines are not. A single blank
> line immediately before `// --- AUTOUPDATE-SPLIT` is also fine.
Other things worth knowing:
- **`positionEncoding` is UTF-16.** A `character` is a UTF-16 code unit
offset, not a byte offset.
- **Line and character numbers in requests are 0-based**, while the `locN_M`
suffixes in SemIR output are 1-based. Off-by-ones here are silent: the
request succeeds and returns the wrong thing.
- **A split can hold a document that itself contains `// CHECK:STDOUT:`
lines**, because `CHECK` lines only form expectations inside the
`AUTOUPDATE-SPLIT`. Such a document still can't contain a literal `// ---`
line, which would split the enclosing test file; write it as
`[[@0x2f]]/ --- name.carbon`.
## The SemIR text reader
`sem_ir_text.cpp` indexes the formatted SemIR inside a test file's
`// CHECK:STDOUT:` lines so that hover and go-to-definition work on operand
names. It is a heuristic reader, not a parser, and its correctness rests on
facts about `toolchain/sem_ir/formatter.cpp` and
`toolchain/sem_ir/inst_namer.cpp`. Re-check these if the formatter changes:
- There are exactly four scope keywords: `file`, `generated`, `imports`, and
`constants` (`InstNamer::GetScopeName`). Everything else is `@entityname`.
- A reference is `%name` within its own scope and `scope.%name` otherwise
(`InstNamer::GetNameFor`). Names may contain `.` and may _start_ with one,
as in `%.Self.frozen`.
- **Type annotations are printed in the `constants` scope.**
`Formatter::FormatTypeOfInst` does
`llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeId::Constants)`,
so in `%x: %foo = ...` a bare `%foo` means `constants.%foo`. This does not
apply to ordinary operands or to `[concrete = ...]` annotations.
- **`*_decl` braces hold the declared entity's scope.** The braces of
`%F.decl: ... = fn_decl @F [...] { ... } { ... }` are lexically inside
`file { }`, but their names belong to `@F`.
- **`!with Self:` switches scope without a brace**, until `!members:`
switches it back. Brace counting alone cannot see this.
- A `specific @F(args) { }` block uses `@F`'s scope and defines nothing; each
`%name => value` row references an instruction of the generic.
### Validating a change to the reader
The unit tests only cover a handful of cases. To check a change against the
real corpus, drive the server over a sample of check testdata, hovering on
every `%name`, and compare the resolved fraction before and after. Roughly 99%
of names resolve; the residue are names the formatter references but never
emits a definition line for, such as `%I.WithSelf.F`, which only ever appears
inside a `[symbolic = ...]` annotation.
Two things to get right in such a harness:
- Feed the request stream from a **file**, not a pipe. The server reads stdin
as a file and reports `error: Input/output error` on a pipe.
- Read the output as **bytes**. Python's `text=True` rewrites the `\r\n`
framing, and `Content-Length` counts bytes.
## VS Code extension
[`utils/vscode/`](/utils/vscode/) declares three languages in `package.json`:
| Language id | Applies to |
| ---------------- | --------------------------------- |
| `carbon` | `*.carbon` |
| `carbon-testdata`| `**/testdata/**/*.carbon` |
| `semir` | `*.semir` |
> [!NOTE]
> The TextMate _scope_ for SemIR is `source.carbon-semir`, but the
> _language id_ is `semir`. Markdown code fences in hover text resolve language
> ids, so a fence must say ` ```semir `.
`extension.ts` launches the server over stdio, using the `carbonPath` setting
(default `./bazel-bin/toolchain/carbon`). Its `documentSelector` controls which
files are sent to the server at all; a new document kind has to be added there
as well as in the server.
@@ -0,0 +1,366 @@
---
name: Review testdata changes
description:
Instructions for judging whether changes to file test output
(`// CHECK:STDOUT:` and `// CHECK:STDERR:` lines) are correct, which
changes are acceptable churn, and which are regressions in disguise.
---
# Review testdata changes
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## Introduction
Most toolchain work moves file test output. `./toolchain/autoupdate_testdata.py`
rewrites the `// CHECK:STDOUT:` and `// CHECK:STDERR:` lines in
`toolchain/*/testdata/` to match current behavior, so after running it the tests
pass again whether or not the new behavior is right. Deciding that the new
output is the output you wanted is a separate, manual step, and it is the step
this skill covers.
Three skills divide the work:
- [Toolchain tests](../toolchain_tests/SKILL.md): how to _author_ tests and
generate their output.
- This skill: how to _judge_ an output diff.
- [Summarize testdata changes](../summarize_testdata_changes/SKILL.md): how to
_report_ an output diff once you believe it is correct.
> [!IMPORTANT] Never hand-edit `// CHECK:STDOUT:` or `// CHECK:STDERR:` lines.
> Everything below is about changing the _code_ until the generated output is
> right, never about editing the output to match the code.
## The rule that generates all the others
**Every line of testdata churn must have a cause you can name.** Not "it is
similar to the other changes", not "the tests pass now" — an actual sentence
saying which code change produced it and why that is the intended result.
A diff you cannot narrate is a diff you have not reviewed. Changes you cannot
explain are where regressions hide, because a regression and an intended change
look exactly alike once the autoupdater has written them down.
> [!CAUTION] Autoupdating is destructive to your evidence. Once the autoupdater
> has run, the previous expectations are gone from the working copy. Read the
> diff after _every_ autoupdate run, and if something changed for a reason you
> cannot name, fix the code before autoupdating again. Recovering the old
> expectations later means reverting and re-running.
## STDERR and STDOUT are different kinds of evidence
Treat them separately; they have different standards of proof.
**STDERR is user-visible behavior.** These are the diagnostics a Carbon
programmer sees. A change here is a change to the language implementation as
users experience it, so each one needs an individual justification. For a
refactoring, the expected STDERR diff is empty.
**STDOUT is internal representation.** SemIR dumps, parse trees, LLVM IR. Users
never see it. Churn here is normal and often unavoidable, so the standard is not
"no change" but "no change I cannot account for".
For a change that is supposed to preserve behavior, write the list of accepted
STDERR changes down _before_ you autoupdate, and keep it current. Order matters
more than form: written first, the list is a prediction the diff can falsify;
written afterwards, it is a description of whatever happened, and describes a
regression exactly as well as an intended change.
The list does not have to be a deliverable. Scratch notes you never publish do
the job, because the work is in committing to the list, not in presenting it.
What a reader needs is not the list but its exceptions: diagnostics that changed
without being predicted, and predictions that did not occur. Both are findings.
The matches are not, and reporting them buries the two entries that matter.
## Judging STDOUT churn
Sort each STDOUT change into mechanical or structural.
### Mechanical churn
Expected, and cheap to accept in bulk once you have confirmed the pattern:
- **Renaming.** An instruction, type, or scope prints under a new name.
- **Positional name renumbering.** Names like `%x.loc18_46.3` embed a line,
column, and disambiguating index. Two different events move them:
- Adding or removing an instruction at a location renumbers the rest, so a
_single_ removed instruction can show up as many changed lines in the
same block. Confirm the cascade is a cascade before accepting it as one.
- Adding or removing a _diagnostic_ moves the source lines themselves, so
the line component changes everywhere below it in the file. See
[Autoupdate to a fixed point](#autoupdate-to-a-fixed-point).
- **Fingerprint-derived names.** Mangled names and some scope names are
derived from a hash of their inputs. If you changed a hashed input, these
move. Confirm that each such difference is _only_ the fingerprint, and not a
fingerprint difference concealing a structural one.
> [!TIP] Mechanical churn is usually wide and shallow: the same substitution,
> repeated across many files. If a "mechanical" pattern needs a different
> explanation in each file, it is not mechanical.
### Structural churn
Each of these needs its own explanation:
- Instructions appearing or disappearing.
- Changed `[concrete = ...]`, `[symbolic = ...]`, or other constant-value
annotations.
- Changed types on existing instructions.
- Changed control flow: new or removed blocks, changed branch targets.
- Raw instruction ids renumbering in `--dump-raw-sem-ir` output when you did
not intend to change the id layout.
## Fewer instructions is not automatically better
A diff that removes instructions looks like an optimization. Whether it is one
depends on what the changed function owes its caller, and two functions can
produce the same shrinking diff for opposite reasons:
- A function that only needs a constant value, but built instructions on the
way to it, was doing wasted work. Dropping them and using the constant
directly is correct, and the shorter output reflects that.
- A function whose caller needs a **non-canonical instruction** can be made
shorter the same way, by using the constant instead of creating an
instruction of its own — and that is wrong. The instruction carries location
information, and symbolic constant substitution operates on it; the constant
value alone loses both.
The instruction count is identical evidence in both cases, so it cannot be the
thing you judge. Decide what the function is required to produce; the count
follows from that.
The same reasoning runs in reverse: a diff that _adds_ instructions is not
automatically a regression.
## Judging STDERR churn
### A diagnostic's authority depends on the file's prefix
The `fail_` and `todo_` prefixes (see
[Toolchain tests](../toolchain_tests/SKILL.md)) say how much the recorded
diagnostics are worth:
- **`fail_...`** — the test should and does produce errors. The recorded
diagnostic **is the specification**. Changing it is a user-visible behavior
change and needs justification on its own merits.
- **`fail_todo_...`** — the test produces errors (or crashes) but shouldn't,
or produces the wrong errors. The recorded diagnostic is explicitly **not**
the specification; the file exists to record that today's behavior is wrong.
Changing it replaces one wrong answer with another. That is acceptable when
you can say why the new message follows from your change and why it is no
further from the intended eventual behavior — which, for many such files, is
no diagnostic at all.
- **`todo_fail_...`** — the test should produce errors but does not. Gaining a
diagnostic here may be _progress_, not a regression. Either way the file
must be renamed, since the framework requires a `fail_` prefix on any file
that errors: `fail_...` if it now produces the right error, `fail_todo_...`
if the error is the wrong one. Both renames make the test pass, so record
which case it is instead of letting the rename settle it.
- **`todo_...`** — behavior is wrong but produces no errors, and shouldn't.
Gaining a diagnostic here is a regression unless you can argue otherwise.
> [!IMPORTANT] This is a reason to look at the _filename_ before judging a
> diagnostic change, not a license to ignore `todo_` files. "It was already
> broken" does not excuse making it differently broken for no reason.
### Reclassifying tests
If your change moves a test between the states above, the prefix must move with
it: when the test is fixed, when it starts failing, and when it starts failing
differently. The correspondence between the `fail_` prefix and whether
compilation actually failed is enforced by the test framework, not by the
autoupdater, so it surfaces when you run `bazelisk test` and not when you
autoupdate. **Autoupdating is not a substitute for running the tests.**
Only that half of the name is checked. Nothing enforces `todo_`, so a file whose
behavior you have just fixed can keep its `todo_` prefix indefinitely and still
pass. A missing `fail_` stops the build; a stale `todo_` is silent, and is yours
to catch.
When a fix drops a file's prefix, also check that the file still belongs where
it is and that its comments do not still describe the old broken behavior.
### Vaguer diagnostics are a signal, not a verdict
When a diagnostic becomes less specific — a general "unsupported" message
replacing one that named the problem — that usually means a code path stopped
finding information it previously had. Sometimes that is correct: the
information was misleading, and the old message was confidently wrong.
Do not accept it silently and do not reject it reflexively. Say which direction
it moved and whether the new message is closer to or further from the eventual
intended behavior.
## Signals in the shape of the diff
### Zero churn is a result
If you removed something you believed was doing work and _no_ testdata moved,
that is not a missing test run — it is the proof that the thing was a no-op.
Say so explicitly; it is one of the strongest pieces of evidence a refactoring
can produce.
The converse is also informative. If you expected a path to churn and it didn't,
either your model of the code is wrong or that path is untested. Find out which,
and consider adding a test before continuing.
### Churn should be proportional to the change
- **Wide churn from a narrow change** means your model of the code is wrong.
Do not autoupdate over it. Find the structural mistake first.
- **Narrow churn from a sweeping change** means the affected paths are
probably untested.
Set a rough expectation for the size of the diff before you run the autoupdater,
and treat a large mismatch in either direction as a finding.
### Never make the diff smaller by weakening the test
Editing test _input_ (the Carbon source, not the CHECK lines) to make a diff
look better is a behavior change in disguise. Deleting a test that now produces
awkward output is worse. If a test's input has to change, that is a separate,
explicitly-justified change, not diff cleanup.
## What the autoupdater will not fix for you
- **`NOAUTOUPDATE` files.** Their expectations are maintained by hand. They
fail under `bazelisk test` rather than being silently rewritten.
- **Hand-written C++ expectations**, for example golden output asserted in a
`_test.cpp`. When several assertions in one of these break together, often
only the first failure is reported, so fixing it can reveal another. Re-run
until clean rather than assuming one fix was the whole repair.
- **Golden files outside `testdata/`**, and documentation that quotes compiler
output.
## Review loop
### Run the autoupdater
Autoupdate everything, then read the diff a directory at a time. Passing no
paths is the default and updates every file test in the toolchain:
```bash
./toolchain/autoupdate_testdata.py
```
Narrow the scope only while iterating on one subdirectory you know you are not
done with, where each round would otherwise regenerate output you have already
read:
```bash
./toolchain/autoupdate_testdata.py toolchain/check/testdata/SUBDIR/**/*
```
The globs are expanded by the shell; the script filters its arguments to
`.carbon` files under a `testdata/` directory.
> [!TIP] If intermediate states crash on `CARBON_CHECK` failures, pass
> `--non-fatal-checks` so you can see the full set of downstream damage in one
> run instead of one crash at a time.
> [!IMPORTANT] Return to the full scope before judging the diff. Whether churn
> is proportional to the change, and whether a change to one phase moved another
> phase's testdata, are only visible across everything.
### Autoupdate to a fixed point
One pass is not always enough, because the autoupdater's output is part of its
own input. `// CHECK:STDERR:` lines sit inline, immediately above the source
line they describe, and the compiler reads them as comments in the file.
Gaining or losing a diagnostic therefore moves every source line below it.
Within a single run, the compiler has already read the file as it was, so the
two kinds of output end up in different states:
- **STDERR is correct after one pass.** These lines locate themselves
relatively, as `[[@LINE+N]]`, and the autoupdater recomputes `N` as it
places them.
- **STDOUT is stale after one pass.** SemIR names like `%x.loc18_46.3` embed
an absolute line and column with no filename attached, and the autoupdater
only remaps `file.carbon:18`-style references. Nothing rewrites the `loc`,
so it still describes where the instruction was _before_ the diagnostic
lines moved it.
Running again compiles the shifted file and the names catch up. The diagnostic
set does not change this time, so nothing shifts again and a third run is a
no-op. Keep running the autoupdater until it stops changing files: one pass when
the diagnostics held still, two when they didn't.
> [!WARNING] The intermediate state is self-inconsistent, not just unfinished:
> its `loc` names describe a file layout that no longer exists. Keep reading the
> diff after every run — that rule does not change — but do not chase positional
> churn to a cause until the file has converged, and do not present the diff
> until then either.
The converging pass should be positional renumbering and nothing else. If it
moves an instruction, a type, or a constant value, then something other than a
`loc` name is sensitive to where lines fall in the file. Find out what before
accepting it.
The file tests do catch a file left unconverged, since each test re-runs the
autoupdate in memory and fails with
`Autoupdate would make changes to the file content` when the result differs. But
that arrives at `bazelisk test` time, after you have already read a diff that
was describing a file which had moved out from under it.
### Inspect the diff
Inspect the diagnostics first, since that is the acceptance criterion:
```bash
# STDERR-only view, with jj.
jj --no-pager diff --git 'glob:toolchain/*/testdata/**' \
| grep -E '^[-+].*CHECK:STDERR'
# The same, with git.
git diff -- 'toolchain/*/testdata/*' \
| grep -E '^[-+].*CHECK:STDERR'
```
For a structured view separating test input, STDERR, and STDOUT changes, use the
helper from the
[Summarize testdata changes](../summarize_testdata_changes/SKILL.md) skill:
```bash
jj --no-pager diff --git 'glob:toolchain/*/testdata/**' \
| python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
git diff -- 'toolchain/*/testdata/*' \
| python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
```
The argument after the tool name is not interchangeable: `glob:...` is a jj
fileset, `-- ...` is a git pathspec. `--git` and `--no-pager` are jj flags; git
already emits this format and skips the pager when piped.
### Run the tests
Then run the tests, which is what catches prefix mismatches and non-autoupdated
expectations:
```bash
bazelisk test //toolchain/...
```
See the [Bazel usage](../bazel/SKILL.md) skill.
## Checklist
Before presenting a testdata diff as finished:
- [ ] The autoupdater was run until it made no further changes, so no `loc`
name describes a stale line numbering.
- [ ] The list of accepted STDERR changes was written before autoupdating, and
every change either matches it or is reported as an exception.
- [ ] Every STDOUT change is either an instance of a named mechanical pattern
or has its own explanation.
- [ ] Instructions that appeared or disappeared are justified by what the
changed function owes its caller, not by the instruction count.
- [ ] Files whose prefix no longer matches their behavior have been renamed.
- [ ] No test input was changed, and no test was deleted, to make the diff
smaller.
- [ ] The size of the diff is proportional to the size of the change.
@@ -17,6 +17,10 @@ This skill provides instructions for creating a comprehensive report summarizing
changes to Carbon testdata files (`toolchain/*/testdata`) and associating them
with related code changes.
This skill is about _reporting_ a diff. For deciding whether the diff is correct
in the first place, see the
[Review testdata changes](../review_testdata_changes/SKILL.md) skill.
## Goals
Produce a report that:
@@ -40,10 +44,11 @@ input changes.
#### For Git Users:
- **Summarize code changes**: `git diff --stat -- ':!toolchain/*/testdata'`
- **Summarize code changes**: `git diff --stat -- ':!toolchain/*/testdata/*'`
- To see content of non-testdata changes:
`git diff -- ':!toolchain/*/testdata'`
- **Identify testdata changes**: `git diff --name-only 'toolchain/*/testdata'`
`git diff -- ':!toolchain/*/testdata/*'`
- **Identify testdata changes**:
`git diff --name-only 'toolchain/*/testdata/*'`
#### For Jujutsu (jj) Users:
@@ -80,7 +85,7 @@ STDOUT changes. This script reads a unified diff from stdin.
```bash
# For Git:
git diff -- 'toolchain/*/testdata' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
git diff -- 'toolchain/*/testdata/*' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
# For Jujutsu (jj):
jj diff --git 'toolchain/*/testdata' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
@@ -35,6 +35,10 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
([SKILL.md](../builtins/SKILL.md)) for guidelines on registering, mapping,
constant evaluating, and lowering compiler builtin primitives (e.g.
`"int.convert_float"`).
- **Language server**: Refer to the **Language server** skill
([SKILL.md](../language_server/SKILL.md)) before working on
`toolchain/language_server/` or `utils/vscode/`. Neither follows the
patterns described here.
- **Phases**: Lex -> Parse -> Check -> Lower.
- **Definitions**: Many kinds (tokens, parse nodes, SemIR instructions) are
defined in `.def` files and expanded by way of macros.
+9
View File
@@ -23,6 +23,11 @@ Toolchain tests evaluate Carbon source files through Lexing, Parsing, Checking,
and optionally Lowering. Output (for example SemIR dumps, Clang errors) is
captured and validated using inline CHECK records.
Language server tests also use `file_test`, but with quite different
conventions (an LSP message stream, `AUTOUPDATE-SPLIT`, `FROM_FILE_SPLIT`).
Refer to the **Language server** skill
([SKILL.md](../language_server/SKILL.md)) for those.
## Structure and Authoring
### File Layout and Headers
@@ -182,3 +187,7 @@ updater:
Review the updated test outputs (for example, by way of `git diff`). Ensure
logic paths are correctly tested rather than producing massive boilerplate
blocks.
Autoupdating makes the tests pass whether or not the new behavior is correct, so
deciding that the new output is the output you wanted is a separate step. See
the [Review testdata changes](../review_testdata_changes/SKILL.md) skill.
@@ -321,8 +321,13 @@ def libcxx_feature(llvm_bindir = None, clang_bindir = None):
"-unwindlib=libunwind",
])],
with_features = [
# libc++ is only used on non-Windows platforms.
with_feature_set(not_features = ["windows_target"]),
# libc++ is only used on non-Windows platforms, and macOS
# doesn't support a custom unwinding library (or need one)
# even when using libc++.
with_feature_set(not_features = [
"macos_target",
"windows_target",
]),
],
),
flag_set(
+25 -6
View File
@@ -1,16 +1,35 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
package Core library "prelude/destroy";
// TODO: Add `Destructor`, as in:
// interface Destructor {
// private fn Op(ref self);
// TODO: uncomment when `require impls` adds a witness table entry.
// interface SubobjectDestroy {
// final fn Op(ref self) = "subobject.destroy";
// }
// Destroys objects. This will invoke `Destructor` impls recursively on members;
// it does not deallocate memory.
interface Destroy {
// TODO: uncomment when `require impls` adds a witness table entry.
// require impls SubobjectDestroy;
// TODO: change `Self` to `partial Self`.
fn Op(ref self);
// TODO: remove when `require impls` adds a witness table entry.
final fn SubobjectDestroy(unused ref self) {
// This function body is ignored by the toolchain. We can't use
// a built-in because the compiler treats it as an error. We
// should address this at some point, but it's not a high
// priority right now.
}
final fn SelfDestruct(ref self) {
self.Op();
self.SubobjectDestroy();
}
}
// TODO: uncomment when `require impls` adds a witness table entry.
// impl forall [T: SubobjectDestroy] partial T as Destroy {
// alias Op = T.Op;
// }
+2 -2
View File
@@ -56,8 +56,8 @@ REMOTE="$(sed -n 's/^Changes to push to \(.*\):$/\1/p' <<<"$PLAN")"
# Each updated bookmark or tag reports the commit it moves to. Deletions have no
# such commit, and send nothing to check.
TARGETS="$(sed -n 's/^ \(bookmark\|tag\): .* to \([0-9a-f]\{8,\}\)\]$/\2/p' <<<"$PLAN" |
paste -sd '|')"
TARGETS="$(sed -E -n 's/^ (bookmark|tag): .* to ([0-9a-f]{8,})\]$/\2/p' <<<"$PLAN" |
paste -sd '|' -)"
# Nothing to check, so just push.
if [[ -z "$REMOTE" || -z "$TARGETS" ]]; then
+1
View File
@@ -86,6 +86,7 @@ Example usage:
"constant": "SemIR::MakeConstantId",
"constraint": "SemIR::MakeNamedConstraintId",
"declared_facet_type": "SemIR::MakeDeclaredFacetTypeId",
"default_value": "SemIR::MakeDefaultValueId",
"entity_name": "SemIR::MakeEntityNameId",
"function": "SemIR::MakeFunctionId",
"generated_function": "SemIR::MakeGeneratedFunctionId",
+7
View File
@@ -284,6 +284,13 @@ Supported comment markers are:
Output line matchers may contain `[[@LINE+offset]` and `{{regex}}` syntaxes,
similar to `FileCheck`.
When the file uses an `AUTOUPDATE-SPLIT`, only `CHECK` lines in that split
are matchers; elsewhere they are ordinary content. This is what allows a
split to hold a test file that itself contains `CHECK` lines, as the
language server's SemIR tests do. Note that such a split still can't contain
a `// ---` line, which would split the enclosing file; write the `/`
characters as `[[@0x2f]]` to avoid that.
- ```
// TIP: <tip>
```
+33 -9
View File
@@ -25,6 +25,9 @@ using ::testing::Matcher;
using ::testing::MatchesRegex;
using ::testing::StrEq;
// The name of the trailing split that autoupdate writes `CHECK` lines into.
static constexpr llvm::StringLiteral AutoupdateSplit = "AUTOUPDATE-SPLIT";
// Represents the different kinds of version-control conflict markers that are
// relevant for the autoupdater. One key concern here is the distinction between
// "snapshot" and "diff" conflict regions. Snapshot regions are the more
@@ -735,6 +738,22 @@ static auto TryConsumeSetFlag(llvm::StringRef line_trimmed,
return true;
}
// Returns whether the file uses a `// --- AUTOUPDATE-SPLIT` split.
//
// Autoupdate writes every `CHECK` into that split, so when one is present, a
// `CHECK` line anywhere else is part of the test input rather than an
// expectation. That's what allows a split to hold a test file that itself
// contains `CHECK` lines.
static auto UsesAutoupdateSplit(llvm::StringRef content) -> bool {
for (llvm::StringRef line : llvm::split(content, '\n')) {
llvm::StringRef trimmed = line.trim();
if (trimmed.consume_front("// ---") && trimmed.trim() == AutoupdateSplit) {
return true;
}
}
return false;
}
// Process content for either the main file (with `test_file` and
// `found_autoupdate` provided) or an included file (with those arguments null).
//
@@ -761,6 +780,8 @@ static auto ProcessFileContent(llvm::StringRef filename,
// Otherwise conflict markers are errors.
auto previous_conflict_marker = MarkerKind::None;
const bool uses_autoupdate_split = UsesAutoupdateSplit(content_cursor);
SplitState split_state;
while (!content_cursor.empty()) {
@@ -802,13 +823,18 @@ static auto ProcessFileContent(llvm::StringRef filename,
continue;
}
CARBON_ASSIGN_OR_RETURN(
is_consumed,
TryConsumeCheck(running_autoupdate, line_index, line, line_trimmed,
test_file ? &test_file->expected_stdout : nullptr,
test_file ? &test_file->expected_stderr : nullptr));
if (is_consumed) {
continue;
// `CHECK` lines are only expectations where autoupdate would write them.
// Everywhere else they're input, which is how a split can hold a test file
// that itself contains `CHECK` lines.
if (!uses_autoupdate_split || split_state.filename == AutoupdateSplit) {
CARBON_ASSIGN_OR_RETURN(
is_consumed,
TryConsumeCheck(running_autoupdate, line_index, line, line_trimmed,
test_file ? &test_file->expected_stdout : nullptr,
test_file ? &test_file->expected_stderr : nullptr));
if (is_consumed) {
continue;
}
}
if (test_file) {
@@ -895,8 +921,6 @@ auto ProcessTestFile(llvm::StringRef test_name, bool running_autoupdate)
return ErrorBuilder() << "Missing AUTOUPDATE/NOAUTOUPDATE setting";
}
constexpr llvm::StringLiteral AutoupdateSplit = "AUTOUPDATE-SPLIT";
// Validate AUTOUPDATE-SPLIT use, and remove it from test files if present.
if (test_file.has_splits) {
for (const auto& test_file :
@@ -0,0 +1,30 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //testing/file_test:file_test_base_test --test_arg=--file_tests=testing/file_test/testdata/check_outside_autoupdate_split.carbon
// TIP: To dump output, run:
// TIP: bazel run //testing/file_test:file_test_base_test -- --dump_output --file_tests=testing/file_test/testdata/check_outside_autoupdate_split.carbon
// When the file uses an `AUTOUPDATE-SPLIT`, `CHECK` lines elsewhere are
// content rather than expectations, so a split can hold a test file of its
// own. Such a split still can't contain a literal `// ---` line, so the `/`
// characters are written as `[[@0x2f]]`.
//
// The echoed line numbers below show that both lines are part of `a.carbon`:
// if the `CHECK` had been consumed it would be an unmatched expectation, and
// if the `// ---` had split, there would be a second file in the arguments.
// --- a.carbon
// CHECK:STDOUT: not an expectation
this line follows a CHECK line
[[@0x2f]][[@0x2f]] --- not a split
this line follows a split marker
// --- AUTOUPDATE-SPLIT
// CHECK:STDOUT: 2 args: `default_args`, `a.carbon`
// CHECK:STDOUT: a.carbon:2: this line follows a CHECK line
// CHECK:STDOUT: a.carbon:4: this line follows a split marker
+23 -10
View File
@@ -42,9 +42,13 @@ enum class EntityKind : uint8_t {
} // namespace
// Resolves the callee expression in a call to a specific callee, or diagnoses
// if no specific callee can be identified. This verifies the arity of the
// callee and determines any compile-time arguments, but doesn't check that the
// runtime arguments are convertible to the parameter types.
// if no specific callee can be identified. This determines any compile-time
// arguments, but doesn't check that the runtime arguments are convertible to
// the parameter types. It also verifies that the number of arguments is within
// the range [callee_arity - arity_lower_bound_margin, callee_arity]. This
// allows arity matching when the callee has default arguments for some
// subpatterns. In all other cases supply the default value `0` for exact arity
// checking.
//
// `self_id` and `arg_ids` are the self argument and explicit arguments in the
// call.
@@ -56,14 +60,21 @@ static auto ResolveCalleeInCall(Context& context, SemIR::LocId loc_id,
EntityKind entity_kind_for_diagnostic,
SemIR::SpecificId enclosing_specific_id,
SemIR::InstId self_id,
llvm::ArrayRef<SemIR::InstId> arg_ids)
llvm::ArrayRef<SemIR::InstId> arg_ids,
int32_t arity_lower_bound_margin = 0)
-> std::optional<SemIR::SpecificId> {
// Check that the arity matches the explicit arguments.
// Check that the arity exactly matches or is the upper bound of the explicit
// arguments.
auto param_patterns =
context.inst_blocks().GetOrEmpty(entity.param_patterns_id);
size_t expected_args_size =
param_patterns.size() - (self_id.has_value() ? 1 : 0);
if (arg_ids.size() != expected_args_size) {
CARBON_CHECK(static_cast<size_t>(arity_lower_bound_margin) <=
expected_args_size);
size_t size_lower_bound =
expected_args_size - static_cast<size_t>(arity_lower_bound_margin);
if (arg_ids.size() < size_lower_bound ||
arg_ids.size() > expected_args_size) {
CARBON_DIAGNOSTIC(CallArgCountMismatch, Error,
"{0} argument{0:s} passed to "
"{1:=0:function|=1:generic class|=2:generic "
@@ -219,11 +230,13 @@ auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
llvm::ArrayRef<SemIR::InstId> arg_ids,
bool is_desugared) -> SemIR::InstId {
// If the callee is a generic function, determine the generic argument values
// for the call.
// for the call. Also check the arity of the function against the arguments,
// with allowance for default argument values.
const auto& function = context.functions().Get(callee_function.function_id);
auto callee_specific_id = ResolveCalleeInCall(
context, loc_id, context.functions().Get(callee_function.function_id),
EntityKind::Function, callee_function.enclosing_specific_id,
callee_function.self_id, arg_ids);
context, loc_id, function, EntityKind::Function,
callee_function.enclosing_specific_id, callee_function.self_id, arg_ids,
function.default_value_arity);
if (!callee_specific_id) {
return SemIR::ErrorInst::InstId;
}
+3
View File
@@ -401,6 +401,9 @@ class Context {
auto declared_facet_types() -> SemIR::DeclaredFacetTypeStore& {
return sem_ir().declared_facet_types();
}
auto default_values() -> SemIR::DefaultValueStore& {
return sem_ir().default_values();
}
auto identified_facet_types() -> SemIR::IdentifiedFacetTypeStore& {
return sem_ir().identified_facet_types();
}
+3 -1
View File
@@ -157,7 +157,9 @@ static auto AddCleanups(Context& context, ScopeStack::CleanupScopeDepth depth)
// cleanup blocks, so we'll want to avoid this in the future.
BuildUnaryOperator(context,
context.insts().GetLocIdForDesugaring(destroy_id),
{.interface_name = CoreIdentifier::Destroy}, destroy_id);
{.interface_name = CoreIdentifier::Destroy,
.op_name = CoreIdentifier::SelfDestruct},
destroy_id);
}
}
+21 -26
View File
@@ -1195,15 +1195,14 @@ static auto CanRemoveQualifiers(SemIR::TypeQualifiers quals,
static auto DiagnoseConversionFailureToConstraintValue(
Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
SemIR::TypeId target_type_id) -> void {
CARBON_CHECK(context.types().IsFacetType(target_type_id));
CARBON_CHECK(context.types().Is<SemIR::FacetType>(target_type_id));
// If the source type is/has a facet value (converted with `as type` or
// otherwise), then we can include its `FacetType` in the diagnostic to help
// explain what interfaces the source type implements.
auto const_expr_id = GetCanonicalFacetOrTypeValue(context, expr_id);
// If the source is a facet with constraints (possibly converted to `type`),
// then we can include those constraints in the diagnostic.
auto const_expr_id = GetCanonicalFacet(context, expr_id);
auto const_expr_type_id = context.insts().Get(const_expr_id).type_id();
if (context.types().Is<SemIR::FacetType>(const_expr_type_id)) {
if (context.types().IsConstrainedFacetType(const_expr_type_id)) {
CARBON_DIAGNOSTIC(ConversionFailureFacetToFacet, Error,
"cannot convert type {0} that implements {1} into type "
"implementing {2}",
@@ -1556,7 +1555,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}
}
if (sem_ir.types().IsFacetType(target.type_id)) {
if (sem_ir.types().Is<SemIR::FacetType>(target.type_id)) {
auto type_value_id = SemIR::TypeInstId::None;
// A tuple of types converts to type `type`.
@@ -1574,7 +1573,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}
if (type_value_id != SemIR::InstId::None) {
if (sem_ir.types().Is<SemIR::FacetType>(target.type_id)) {
if (target.type_id != SemIR::TypeType::TypeId) {
// Use the converted `TypeType` value for converting to a facet.
value_id = type_value_id;
value_type_id = SemIR::TypeType::TypeId;
@@ -1585,21 +1584,18 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}
}
// FacetType converts to Type by wrapping the facet value in
// FacetAccessType.
// All facets convert to `type` by wrapping the facet in FacetAccessType.
if (target.type_id == SemIR::TypeType::TypeId &&
sem_ir.types().Is<SemIR::FacetType>(value_type_id)) {
sem_ir.types().IsConstrainedFacetType(value_type_id)) {
return AddInst<SemIR::FacetAccessType>(
context, loc_id,
{.type_id = target.type_id, .facet_value_inst_id = value_id});
}
// Type values can convert to facet values, and facet values can convert to
// other facet values, as long as they satisfy the required interfaces of the
// target `FacetType`.
if (sem_ir.types().Is<SemIR::FacetType>(target.type_id) &&
sem_ir.types().IsOneOf<SemIR::TypeType, SemIR::FacetType>(
value_type_id)) {
// All facets (including types) can convert into other facets, as long as they
// satisfy the constraints of the target `FacetType`.
if (sem_ir.types().IsConstrainedFacetType(target.type_id) &&
sem_ir.types().Is<SemIR::FacetType>(value_type_id)) {
// TODO: Runtime facet values should be allowed to convert based on their
// FacetTypes, but we assume constant values for impl lookup at the moment.
if (!context.constant_values().Get(value_id).is_constant()) {
@@ -1608,9 +1604,9 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
}
// Get the canonical type for which we want to attach a new set of witnesses
// to match the requirements of the target FacetType.
// to match the requirements of the target `FacetType`.
auto type_inst_id = SemIR::TypeInstId::None;
if (sem_ir.types().Is<SemIR::FacetType>(value_type_id)) {
if (value_type_id != SemIR::TypeType::TypeId) {
type_inst_id = AddTypeInst<SemIR::FacetAccessType>(
context, loc_id,
{.type_id = SemIR::TypeType::TypeId,
@@ -1627,8 +1623,7 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
// would evaluate back to the original SymbolicBinding as its canonical
// form. We can skip past the whole impl lookup step then and do that
// here.
auto facet_value_inst_id =
GetCanonicalFacetOrTypeValue(context, type_inst_id);
auto facet_value_inst_id = GetCanonicalFacet(context, type_inst_id);
if (sem_ir.insts().Get(facet_value_inst_id).type_id() == target.type_id) {
return facet_value_inst_id;
}
@@ -1742,8 +1737,7 @@ static auto PerformUserDefinedConversion(Context& context, SemIR::LocId loc_id,
target.kind == ConversionTarget::ExplicitAs ? 1
: target.kind == ConversionTarget::ExplicitUnsafeAs ? 2
: 0;
if (target.type_id == SemIR::TypeType::TypeId ||
context.types().Is<SemIR::FacetType>(target.type_id)) {
if (context.types().Is<SemIR::FacetType>(target.type_id)) {
CARBON_DIAGNOSTIC(
ConversionFailureNonTypeToFacet, Context,
"cannot{0:=0: implicitly|:} convert non-type value of type {1} "
@@ -2113,7 +2107,7 @@ static auto ConversionNeedsCompleteTarget(Context& context,
// We allow conversion to incomplete facet types, since their representation
// is fixed. This allows us to support using the `Self` of an interface inside
// its definition.
if (context.types().IsFacetType(target.type_id)) {
if (context.types().Is<SemIR::FacetType>(target.type_id)) {
return false;
}
@@ -2388,9 +2382,10 @@ auto ConvertCallArgs(Context& context, SemIR::InstId self_id,
SemIR::InstId return_arg_id, const SemIR::Function& callee,
SemIR::SpecificId callee_specific_id, bool is_desugared)
-> SemIR::InstBlockId {
// The caller should have ensured this callee has the right arity.
// The caller should have ensured this callee has the right arity, modulo
// default arguments.
CARBON_CHECK(
(self_id.has_value() ? 1 : 0) + arg_refs.size() ==
(self_id.has_value() ? 1 : 0) + arg_refs.size() <=
context.inst_blocks().GetOrEmpty(callee.param_patterns_id).size());
return CallerPatternMatch(context, callee_specific_id, callee.self_param_id,
+2
View File
@@ -76,9 +76,11 @@ CARBON_CORE_IDENTIFIER(Optional)
CARBON_CORE_IDENTIFIER(OrderedWith)
CARBON_CORE_IDENTIFIER(RightShiftAssignWith)
CARBON_CORE_IDENTIFIER(RightShiftWith)
CARBON_CORE_IDENTIFIER(SelfDestruct)
CARBON_CORE_IDENTIFIER(String)
CARBON_CORE_IDENTIFIER(SubAssignWith)
CARBON_CORE_IDENTIFIER(SubWith)
CARBON_CORE_IDENTIFIER(SubobjectDestroy)
CARBON_CORE_IDENTIFIER(UInt)
CARBON_CORE_IDENTIFIER(ULong32)
CARBON_CORE_IDENTIFIER(ULong64)
+3 -4
View File
@@ -30,10 +30,9 @@ namespace Carbon::Check {
static auto IsTemplateArg(Context& context, SemIR::InstId arg_id) -> bool {
auto arg_type_id = context.insts().Get(arg_id).type_id();
auto arg_type = context.types().GetAsInst(arg_type_id);
return arg_type
.IsOneOf<SemIR::TypeType, SemIR::FacetType, SemIR::CppTemplateNameType,
SemIR::GenericClassType, SemIR::GenericInterfaceType,
SemIR::GenericNamedConstraintType>();
return arg_type.IsOneOf<SemIR::FacetType, SemIR::CppTemplateNameType,
SemIR::GenericClassType, SemIR::GenericInterfaceType,
SemIR::GenericNamedConstraintType>();
}
// Splits a call argument list into a list of template arguments followed by a
+1 -2
View File
@@ -332,8 +332,7 @@ static auto ExportGenericBindings(Context& context, SemIR::LocId loc_id,
CARBON_CHECK(param_ident, "non-identifier param name {0}",
entity_name.name_id);
if (symbolic_binding.type_id != SemIR::TypeType::TypeId &&
!context.types().Is<SemIR::FacetType>(symbolic_binding.type_id)) {
if (!context.types().Is<SemIR::FacetType>(symbolic_binding.type_id)) {
context.TODO(loc_id, "binding maps to a non-type template parameter");
return nullptr;
}
+8 -5
View File
@@ -241,7 +241,7 @@ static auto BuildDefaultWitness(
query_specific_interface, {fn_id});
}
static auto BuildDestroyWitness(
static auto BuildCppDestroyWitness(
Context& context, SemIR::LocId loc_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId {
@@ -264,8 +264,11 @@ static auto BuildDestroyWitness(
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
return fn_id;
}
return BuildCustomWitness(context, loc_id, query_self_const_id,
query_specific_interface, {fn_id});
return BuildDestroyWitness(
context, loc_id,
GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id)),
query_self_const_id, query_specific_interface, {fn_id});
}
// Attempts to build a witness table entry for a C++ unary operator.
@@ -610,8 +613,8 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id,
return BuildDefaultWitness(context, loc_id, query_self_const_id,
query_specific_interface);
case SemIR::CoreInterface::Destroy:
return BuildDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface);
return BuildCppDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface);
case SemIR::CoreInterface::CppRangeForIterate:
return BuildCppRangeForIterateWitness(
-1
View File
@@ -1967,7 +1967,6 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
.call_param_patterns_id =
function_params_insts->call_param_patterns_id,
.call_params_id = function_params_insts->call_params_id,
.call_param_default_values_id = SemIR::InstBlockId::Empty,
.call_param_ranges = function_params_insts->param_ranges,
.return_type_inst_id = function_params_insts->return_type_inst_id,
.return_form_inst_id = function_params_insts->return_form_inst_id,
+2
View File
@@ -39,6 +39,8 @@ static auto GetClangOperatorKind(Context& context, SemIR::LocId loc_id,
switch (interface_name) {
// Unary operators.
case CoreIdentifier::Destroy:
case CoreIdentifier::SubobjectDestroy:
case CoreIdentifier::SelfDestruct:
case CoreIdentifier::As:
case CoreIdentifier::ImplicitAs:
case CoreIdentifier::Iterate:
+152 -50
View File
@@ -6,6 +6,7 @@
#include "llvm/ADT/APFloat.h"
#include "toolchain/base/kind_switch.h"
#include "toolchain/check/call.h"
#include "toolchain/check/convert.h"
#include "toolchain/check/eval.h"
#include "toolchain/check/facet_type.h"
@@ -15,37 +16,24 @@
#include "toolchain/check/impl_lookup.h"
#include "toolchain/check/import_ref.h"
#include "toolchain/check/inst.h"
#include "toolchain/check/member_access.h"
#include "toolchain/check/name_lookup.h"
#include "toolchain/check/operator.h"
#include "toolchain/check/return.h"
#include "toolchain/check/type.h"
#include "toolchain/check/type_completion.h"
#include "toolchain/diagnostics/format_providers.h"
#include "toolchain/sem_ir/associated_constant.h"
#include "toolchain/sem_ir/builtin_function_kind.h"
#include "toolchain/sem_ir/constant.h"
#include "toolchain/sem_ir/function.h"
#include "toolchain/sem_ir/generic.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/type_info.h"
#include "toolchain/sem_ir/typed_insts.h"
namespace Carbon::Check {
// Given a value whose type `IsFacetTypeOrError`, returns the corresponding
// type.
static auto GetFacetAsType(Context& context,
SemIR::ConstantId facet_or_type_const_id)
-> SemIR::TypeId {
auto facet_or_type_id =
context.constant_values().GetInstId(facet_or_type_const_id);
auto type_type_id = context.insts().Get(facet_or_type_id).type_id();
CARBON_CHECK(context.types().IsFacetTypeOrError(type_type_id));
if (context.types().Is<SemIR::FacetType>(type_type_id)) {
// It's a facet; access its type.
facet_or_type_id = context.types().GetTypeInstId(
GetFacetAccessType(context, facet_or_type_id));
}
return context.types().GetTypeIdForTypeInstId(facet_or_type_id);
}
// Make the CanonicalKey for a generated function `op_name_id` in the interface
// `core_specific_interface`.
static auto MakeGeneratedFunctionKey(
@@ -242,13 +230,13 @@ static auto CanDestroyType(Context& context, SemIR::LocId loc_id,
SemIR::SpecificInterface query_specific_interface)
-> DestroyFormat {
auto inst_id = context.constant_values().GetInstId(
GetCanonicalFacetOrTypeValue(context, query_self_const_id));
GetCanonicalFacet(context, query_self_const_id));
auto inst = context.insts().Get(inst_id);
if (context.types().Is<SemIR::FacetType>(inst.type_id())) {
// The value's type is a facet (whose type is a facet type). We don't
// provide a custom witness for symbolic values of type facet. The witness
// will be found from impl lookup.
if (context.types().IsConstrainedFacetType(inst.type_id())) {
// The value's type is a symbolic constrained facet. We don't provide a
// custom witness for constrained facets. The witness must be found in the
// constraints by impl lookup.
CARBON_CHECK(query_self_const_id.is_symbolic());
return DestroyFormat::NoDestroy;
}
@@ -360,7 +348,6 @@ static auto CanDestroyType(Context& context, SemIR::LocId loc_id,
case SemIR::IntLiteralType::Kind:
case SemIR::IntType::Kind:
case SemIR::PointerType::Kind:
case SemIR::TypeType::Kind:
// Trivially destructible.
return DestroyFormat::Trivial;
@@ -369,14 +356,14 @@ static auto CanDestroyType(Context& context, SemIR::LocId loc_id,
}
}
// Returns the body for `Destroy.Op`.
// Returns the body for `SubobjectDestroy.Op`.
//
// TODO: This is a placeholder still not actually destroying things, intended to
// maintain mostly-consistent behavior with current logic while working. That
// also means using `self`.
static auto MakeDestroyOpBody(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id,
SemIR::InstId self_param_id)
static auto MakeSubobjectDestroyOpBody(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id,
SemIR::InstId self_param_id)
-> SemIR::InstBlockId {
context.inst_block_stack().Push();
auto inst = context.types().GetAsInst(self_type_id);
@@ -393,7 +380,7 @@ static auto MakeDestroyOpBody(Context& context, SemIR::LocId loc_id,
// TODO: Implement destruction of the type.
break;
default:
CARBON_FATAL("Unexpected type for MakeDestroyOpBody: {0}", inst);
CARBON_FATAL("Unexpected type for MakeSubobjectDestroyOpBody: {0}", inst);
}
AddInst(context, loc_id, SemIR::Return{});
@@ -404,15 +391,48 @@ static auto MakeDestroyOpBody(Context& context, SemIR::LocId loc_id,
// to `self_type_id`.
static auto MakeDestroyOpFunction(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id,
SemIR::InterfaceId interface_id,
DestroyFormat format) -> SemIR::InstId {
SemIR::InterfaceId interface_id)
-> SemIR::InstId {
auto name_id = context.core_identifiers().AddNameId(CoreIdentifier::Op);
const auto& interface = context.interfaces().Get(interface_id);
auto specific_interface = MakeCoreSpecificInterface(
context, loc_id, interface_id, interface.generic_id, {});
auto canonical_key = MakeGeneratedFunctionKey(context, specific_interface,
self_type_id, name_id);
auto [decl_id, function_id] = TryGetGeneratedFunction(context, canonical_key);
if (!decl_id.has_value()) {
std::tie(decl_id, function_id) = MakeGeneratedFunctionDecl(
context, loc_id,
{.parent_scope_id = interface.scope_with_self_id,
.name_id = name_id,
.self_type_id = self_type_id,
.self_kind = ParamPatternKind::Ref});
auto& function = context.functions().Get(function_id);
function.SetGenerated(context.generated_functions().Add(
{.canonical_key = canonical_key,
.function_id = function_id,
.decl_id = decl_id,
.builtin_function_kind = SemIR::BuiltinFunctionKind::NoOp}));
}
return decl_id;
}
static auto MakeSubobjectDestroyOpFunction(
Context& context, SemIR::LocId loc_id, SemIR::TypeId self_type_id,
SemIR::InterfaceId interface_id, DestroyFormat format) -> SemIR::InstId {
// TODO: replace with `CoreIdentifier::Op` when `require impls` adds a witness
// table entry.
auto name_id =
context.core_identifiers().AddNameId(CoreIdentifier::SubobjectDestroy);
const auto& interface = context.interfaces().Get(interface_id);
auto specific_interface = MakeCoreSpecificInterface(
context, loc_id, interface_id, interface.generic_id, {});
auto canonical_key = MakeGeneratedFunctionKey(context, specific_interface,
self_type_id, name_id);
auto [decl_id, function_id] = TryGetGeneratedFunction(context, canonical_key);
if (!decl_id.has_value()) {
std::tie(decl_id, function_id) = MakeGeneratedFunctionDecl(
context, loc_id,
@@ -429,8 +449,8 @@ static auto MakeDestroyOpFunction(Context& context, SemIR::LocId loc_id,
builtin_kind = SemIR::BuiltinFunctionKind::NoOp;
break;
case DestroyFormat::NonTrivial: {
auto body_id = MakeDestroyOpBody(context, loc_id, self_type_id,
function.self_param_id);
auto body_id = MakeSubobjectDestroyOpBody(context, loc_id, self_type_id,
function.self_param_id);
function.body_block_ids.push_back(body_id);
break;
}
@@ -444,7 +464,54 @@ static auto MakeDestroyOpFunction(Context& context, SemIR::LocId loc_id,
.decl_id = decl_id,
.builtin_function_kind = builtin_kind}));
}
return decl_id;
}
// Returns a manufactured `Destroy.SelfDestruct` function with the `self`
// parameter typed to `self_type_id`.
static auto MakeDestroySelfDestructFunction(
Context& context, SemIR::LocId loc_id, SemIR::TypeId self_type_id,
SemIR::InterfaceId interface_id, SemIR::InstId op_id,
[[maybe_unused]] SemIR::InstId subobject_destroy_id) -> SemIR::InstId {
auto name_id =
context.core_identifiers().AddNameId(CoreIdentifier::SelfDestruct);
const auto& interface = context.interfaces().Get(interface_id);
auto specific_interface = MakeCoreSpecificInterface(
context, loc_id, interface_id, interface.generic_id, {});
auto canonical_key = MakeGeneratedFunctionKey(context, specific_interface,
self_type_id, name_id);
auto [decl_id, function_id] = TryGetGeneratedFunction(context, canonical_key);
if (!decl_id.has_value()) {
std::tie(decl_id, function_id) = MakeGeneratedFunctionDecl(
context, loc_id,
{.parent_scope_id = interface.scope_with_self_id,
.name_id = name_id,
.self_type_id = self_type_id,
.self_kind = ParamPatternKind::Ref});
auto& function = context.functions().Get(function_id);
context.inst_block_stack().Push();
StartFunctionDefinition(context, decl_id, function_id);
auto params = context.inst_blocks().Get(function.call_params_id);
CARBON_CHECK(
params.size() == 1,
"`Core.Destroy.SelfDestruct` should only have `ref self` as its "
"parameter");
op_id = PerformCall(context, loc_id, op_id, {params[0]}, true);
DiscardExpr(context, op_id);
subobject_destroy_id =
PerformCall(context, loc_id, subobject_destroy_id, {params[0]}, true);
DiscardExpr(context, subobject_destroy_id);
BuildReturnWithNoExpr(context, loc_id);
FinishFunctionDefinition(context, function_id);
context.inst_block_stack().Pop();
function.SetGenerated(context.generated_functions().Add(
{.canonical_key = canonical_key,
.function_id = function_id,
.decl_id = decl_id,
.builtin_function_kind = SemIR::BuiltinFunctionKind::None}));
}
return decl_id;
}
@@ -481,7 +548,8 @@ static auto GetTypesForSelfFacet(
query_specific_interface));
// The Self facet needs to point to a type value. If it's not one already,
// convert to type.
auto query_self_as_type_id = GetFacetAsType(context, query_self_const_id);
auto query_self_as_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id));
return {facet_type_for_query_specific_interface, query_self_as_type_id};
}
@@ -663,7 +731,8 @@ auto BuildPrimitiveCopyWitness(
Context& context, SemIR::LocId loc_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId {
auto self_type_id = GetFacetAsType(context, query_self_const_id);
auto self_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id));
auto op_id = MakeBuiltinOperatorFunction(
context, loc_id, {self_type_id}, self_type_id, CoreIdentifier::Op,
@@ -673,21 +742,49 @@ auto BuildPrimitiveCopyWitness(
query_specific_interface, {op_id});
}
auto BuildDestroyWitness(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface,
SemIR::InstId subobject_destroy_fn_id)
-> SemIR::InstId {
auto interface =
context.interfaces().Get(query_specific_interface.interface_id);
auto assoc_entities =
context.inst_blocks().Get(interface.associated_entities_id);
CARBON_CHECK(assoc_entities.size() == 3,
"{} only has {} associated functions",
context.names().GetAsStringIfIdentifier(interface.name_id),
assoc_entities.size());
auto op_id = MakeDestroyOpFunction(context, loc_id, self_type_id,
query_specific_interface.interface_id);
auto self_destruct_fn_id = MakeDestroySelfDestructFunction(
context, loc_id, self_type_id, query_specific_interface.interface_id,
op_id, subobject_destroy_fn_id);
return BuildCustomWitness(
context, loc_id, query_self_const_id, query_specific_interface,
{op_id, subobject_destroy_fn_id, self_destruct_fn_id});
}
// Builds and returns a custom witness that performs the specified kind of
// destruction for the given type.
static auto BuildDestroyWitness(
static auto BuildCarbonDestroyWitness(
Context& context, SemIR::LocId loc_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface, DestroyFormat format)
-> SemIR::InstId {
CARBON_CHECK(format != DestroyFormat::NoDestroy);
auto self_type_id = GetFacetAsType(context, query_self_const_id);
auto op_id =
MakeDestroyOpFunction(context, loc_id, self_type_id,
query_specific_interface.interface_id, format);
return BuildCustomWitness(context, loc_id, query_self_const_id,
query_specific_interface, {op_id});
auto self_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id));
auto subobject_destroy_op_id = MakeSubobjectDestroyOpFunction(
context, loc_id, self_type_id, query_specific_interface.interface_id,
format);
return BuildDestroyWitness(context, loc_id, self_type_id, query_self_const_id,
query_specific_interface, subobject_destroy_op_id);
}
// Returns the custom witness to use for destruction of the given type. See
@@ -708,16 +805,17 @@ static auto LookupDestroyWitness(
return SemIR::InstId::None;
}
return BuildDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface, format);
return BuildCarbonDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface, format);
}
auto BuildTrivialDestroyWitness(
Context& context, SemIR::LocId loc_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId {
return BuildDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface, DestroyFormat::Trivial);
return BuildCarbonDestroyWitness(context, loc_id, query_self_const_id,
query_specific_interface,
DestroyFormat::Trivial);
}
static auto MakeIntFitsInWitness(
@@ -740,8 +838,10 @@ static auto MakeIntFitsInWitness(
return std::nullopt;
}
auto src_type_id = GetFacetAsType(context, query_self_const_id);
auto dest_type_id = GetFacetAsType(context, dest_const_id);
auto src_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id));
auto dest_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(dest_const_id));
auto context_fn = [](DiagnosticContextBuilder& /*builder*/) -> void {};
if (!RequireCompleteType(context, src_type_id, loc_id, context_fn) ||
@@ -836,8 +936,10 @@ static auto MakeFloatFitsInWitness(
return std::nullopt;
}
auto src_type_id = GetFacetAsType(context, query_self_const_id);
auto dest_type_id = GetFacetAsType(context, dest_const_id);
auto src_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(query_self_const_id));
auto dest_type_id = GetFacetAccessType(
context, context.constant_values().GetInstId(dest_const_id));
auto context_fn = [](DiagnosticContextBuilder& /*builder*/) -> void {};
if (!RequireCompleteType(context, src_type_id, loc_id, context_fn) ||
+11
View File
@@ -67,6 +67,17 @@ auto LookupCustomWitness(Context& context, SemIR::LocId loc_id,
SemIR::SpecificInterface query_specific_interface,
bool build_witness) -> std::optional<SemIR::InstId>;
// Builds a witness for the `Destroy` interface.
//
// `op_id` refers to the synthesised `Destroy.Op` and is generated differently
// based on whether the specific is a Carbon type or a C++ type.
auto BuildDestroyWitness(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id,
SemIR::ConstantId query_self_const_id,
SemIR::SpecificInterface query_specific_interface,
SemIR::InstId subobject_destroy_fn_id)
-> SemIR::InstId;
} // namespace Carbon::Check
#endif // CARBON_TOOLCHAIN_CHECK_CUSTOM_WITNESS_H_
+3 -3
View File
@@ -306,11 +306,11 @@ auto DeductionContext::Deduce() -> bool {
if (context().types().Is<SemIR::PatternType>(param_type_id)) {
param_type_id =
SemIR::ExtractScrutineeType(context().sem_ir(), param_type_id);
} else if (context().types().IsFacetType(param_type_id)) {
} else if (context().types().Is<SemIR::FacetType>(param_type_id)) {
// Given `fn F[G: Interface](g: G)`, the type of `g` is `G as type`. For
// deduction, we want to ignore the `as type`, and check that the argument
// can convert to the FacetType of the canonical facet value.
param_id = GetCanonicalFacetOrTypeValue(context(), param_id);
// can convert to the FacetType of the canonical facet.
param_id = GetCanonicalFacet(context(), param_id);
param = context().insts().Get(param_id);
param_type_id = param.type_id();
}
+12 -6
View File
@@ -64,18 +64,24 @@ LLVM_DUMP_METHOD static auto Dump(const Context& context,
return SemIR::Dump(context.sem_ir(), const_id);
}
LLVM_DUMP_METHOD static auto Dump(const Context& context,
SemIR::EntityNameId entity_name_id)
-> std::string {
return SemIR::Dump(context.sem_ir(), entity_name_id);
}
LLVM_DUMP_METHOD static auto Dump(
const Context& context, SemIR::DeclaredFacetTypeId declared_facet_type_id)
-> std::string {
return SemIR::Dump(context.sem_ir(), declared_facet_type_id);
}
LLVM_DUMP_METHOD static auto Dump(const Context& context,
SemIR::DefaultValueId value_id)
-> std::string {
return SemIR::Dump(context.sem_ir(), value_id);
}
LLVM_DUMP_METHOD static auto Dump(const Context& context,
SemIR::EntityNameId entity_name_id)
-> std::string {
return SemIR::Dump(context.sem_ir(), entity_name_id);
}
LLVM_DUMP_METHOD static auto Dump(const Context& context,
SemIR::FunctionId function_id)
-> std::string {
+3 -3
View File
@@ -3340,15 +3340,15 @@ static auto AddRequirementImpls(Context& context, SemIR::RequirementImpls impls,
llvm::append_range(declared_facet_type->self_impls_named_constraints,
rhs.extend_named_constraints);
} else {
auto lhs_facet_or_type = GetCanonicalFacetOrTypeValue(context, lhs_id);
auto lhs_facet = GetCanonicalFacet(context, lhs_id);
auto extends_interface = [=](SemIR::SpecificInterface si)
-> SemIR::DeclaredFacetType::TypeImplsInterface {
return {lhs_facet_or_type, si};
return {lhs_facet, si};
};
auto extends_constraint = [=](SemIR::SpecificNamedConstraint sc)
-> SemIR::DeclaredFacetType::TypeImplsNamedConstraint {
return {lhs_facet_or_type, sc};
return {lhs_facet, sc};
};
// Extend constraints are copied over without replacing anything, but are
+22 -9
View File
@@ -214,24 +214,37 @@ auto EvalConstantInst(Context& context, SemIR::ExportDecl inst)
auto EvalConstantInst(Context& context, SemIR::FacetAccessType inst)
-> ConstantEvalResult {
if (auto facet_value = context.insts().TryGetAs<SemIR::FacetValue>(
inst.facet_value_inst_id)) {
auto facet = context.insts().Get(inst.facet_value_inst_id);
CARBON_CHECK(context.types().Is<SemIR::FacetType>(facet.type_id()));
// If the facet is a `type`, we can evaluate to the facet.
if (facet.type_id() == SemIR::TypeType::TypeId) {
return ConstantEvalResult::Existing(
context.constant_values().Get(inst.facet_value_inst_id));
}
// If the facet is a FacetValue, it wraps a `type`, and we can evaluate to
// that `type`.
if (auto facet_value = facet.TryAs<SemIR::FacetValue>()) {
return ConstantEvalResult::Existing(
context.constant_values().Get(facet_value->type_inst_id));
}
// The `facet_value_inst_id` is always a facet value (has type facet type).
CARBON_CHECK(context.types().Is<SemIR::FacetType>(
context.insts().Get(inst.facet_value_inst_id).type_id()));
// Other instructions (e.g. ImplWitnessAccess) of type FacetType can appear
// here, in which case the constant inst is a FacetAccessType until those
// Other instructions (e.g. ImplWitnessAccess) of type `FacetType` can appear
// here, in which case the constant inst is a `FacetAccessType` until those
// instructions resolve to one of the above.
return ConstantEvalResult::NewSamePhase(inst);
}
auto EvalConstantInst(Context& context, SemIR::FacetValue inst)
-> ConstantEvalResult {
// If the FacetValue is of type `type`, then it evaluates to the type inside
// it.
if (inst.type_id == SemIR::TypeType::TypeId) {
return ConstantEvalResult::Existing(
context.constant_values().Get(inst.type_inst_id));
}
// A FacetValue that just wraps a facet without adding/removing any witnesses
// (which means they have the same type) is evaluated to the facet itself.
if (auto access =
@@ -296,7 +309,7 @@ static auto TryFindValueInRewriteConstraints(
SemIR::ElementIndex interface_index, SemIR::InstId search_facet)
-> SemIR::ConstantId {
auto access_self_type_id = context.insts().Get(search_facet).type_id();
if (context.types().Is<SemIR::TypeType>(access_self_type_id)) {
if (access_self_type_id == SemIR::TypeType::TypeId) {
// A self facet of type `type` has no rewrite constraints to look in.
return SemIR::ConstantId::None;
}
-23
View File
@@ -467,29 +467,6 @@ auto ResolveFacetTypeRewriteConstraints(
return true;
}
auto GetEmptyFacetType(Context& context) -> SemIR::TypeId {
SemIR::DeclaredFacetTypeId declared_facet_type_id =
context.declared_facet_types().Add(SemIR::DeclaredFacetType{});
auto const_id = EvalOrAddInst<SemIR::FacetType>(
context, SemIR::LocId::None,
{.type_id = SemIR::TypeType::TypeId,
.declared_facet_type_id = declared_facet_type_id});
return context.types().GetTypeIdForTypeConstantId(const_id);
}
auto GetConstantFacetValueForType(Context& context,
SemIR::TypeInstId type_inst_id)
-> SemIR::ConstantId {
// We use an empty facet type because values of type `type` do not provide any
// witnesses of their own.
auto type_facet_type = GetEmptyFacetType(context);
return EvalOrAddInst<SemIR::FacetValue>(
context, SemIR::LocId::None,
{.type_id = type_facet_type,
.type_inst_id = type_inst_id,
.witnesses_block_id = SemIR::InstBlockId::Empty});
}
auto GetConstantFacetValueForTypeAndInterface(
Context& context, SemIR::TypeInstId type_inst_id,
SemIR::SpecificInterface specific_interface, SemIR::InstId witness_id)
-13
View File
@@ -58,19 +58,6 @@ auto ResolveFacetTypeRewriteConstraints(
llvm::SmallVector<SemIR::DeclaredFacetType::RewriteConstraint>& rewrites)
-> bool;
// Get a FacetType instruction for an empty FacetType. This is the facet
// equivalent to TypeType.
//
// TODO: We vaguely plan to replace TypeType with this FacetType in the future,
// though that's a big change.
auto GetEmptyFacetType(Context& context) -> SemIR::TypeId;
// Make a facet value for a type value, which has an empty FacetType as its
// type. Returns a constant value, whose instruction payload is a FacetValue.
auto GetConstantFacetValueForType(Context& context,
SemIR::TypeInstId type_inst_id)
-> SemIR::ConstantId;
// Make a facet value for a type value, which has a FacetType containing the
// `specific_interface` as its type. Returns a constant value, whose instruction
// payload is a FacetValue.
+15 -57
View File
@@ -81,6 +81,7 @@ class FullPatternStack {
bind_name_stack_.PushArray();
var_pattern_stack_.PushArray();
next_var_index_stack_.push_back(-1);
unspecified_default_values_stack_.PushArray();
}
// Marks the start of a new full-pattern for a name binding declaration.
@@ -89,6 +90,7 @@ class FullPatternStack {
bind_name_stack_.PushArray();
var_pattern_stack_.PushArray();
next_var_index_stack_.push_back(-1);
unspecified_default_values_stack_.PushArray();
}
// Marks the start of a new full-pattern for a class `var` declaration.
@@ -97,6 +99,7 @@ class FullPatternStack {
bind_name_stack_.PushArray();
var_pattern_stack_.PushArray();
next_var_index_stack_.push_back(-1);
unspecified_default_values_stack_.PushArray();
}
// Marks the start of the current parameterized entity's implicit parameter
@@ -121,8 +124,6 @@ class FullPatternStack {
CARBON_CHECK(kind_stack_.back() == Kind::NotInEitherParamList, "{0}",
kind_stack_.back());
kind_stack_.back() = Kind::ExplicitParamList;
raw_default_values_stack_.PushArray();
converted_default_values_stack_.PushArray();
}
// Marks the end of the current parameterized entity's explicit parameter
@@ -142,17 +143,14 @@ class FullPatternStack {
// Marks the end of checking and pattern matching for the current
// full-pattern.
auto PopFullPattern() -> void {
auto kind = kind_stack_.pop_back_val();
kind_stack_.pop_back();
bind_name_stack_.PopArray();
int index = next_var_index_stack_.pop_back_val();
CARBON_CHECK(index < 0 || static_cast<size_t>(index) ==
var_pattern_stack_.PeekArray().size(),
"`GetLocalVarStorage` not called for all var patterns");
var_pattern_stack_.PopArray();
if (kind == Kind::ExplicitParamList) {
raw_default_values_stack_.PopArray();
converted_default_values_stack_.PopArray();
}
unspecified_default_values_stack_.PopArray();
}
// Records that `name_id` was introduced by the current full-pattern.
@@ -207,51 +205,18 @@ class FullPatternStack {
kind_stack_.size());
}
// Adds the inst id for a default value for any subpattern in the
// full-pattern. We store these before the type of the pattern with this
// default value is known. Returns the index of the added instruction
// as a `DefaultValueId`. Note default values are only supported for
// explicit parameter lists.
auto AddRawDefaultValue(SemIR::InstId inst_id) -> SemIR::DefaultValueId {
CARBON_CHECK(kind_stack_.back() == Kind::ExplicitParamList);
return AddDefaultValue(inst_id, raw_default_values_stack_);
// Adds an unspecified pattern default value to the array at the top of the
// full pattern stack. We track these for possible later use in diagnostics.
auto AddUnspecifiedDefaultValue(SemIR::InstId inst_id) -> void {
unspecified_default_values_stack_.AppendToTop(inst_id);
}
// Adds the inst id for a default value after conversion to the pattern type.
// Returns the index of the added instruction as a `DefaultValueId`.
auto AddConvertedDefaultValue(SemIR::InstId inst_id)
-> SemIR::DefaultValueId {
return AddDefaultValue(inst_id, converted_default_values_stack_);
}
// Returns a reference to the array of raw default value inst ids at the top
// of the stack. Note default values are only supported for explicit parameter
// lists.
auto GetRawDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
return raw_default_values_stack_.empty()
? llvm::ArrayRef<SemIR::InstId>()
: raw_default_values_stack_.PeekArray();
}
// Returns a reference to the array of type-converted default value inst ids
// at the top of the stack.
auto GetConvertedDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
return converted_default_values_stack_.empty()
? llvm::ArrayRef<SemIR::InstId>()
: converted_default_values_stack_.PeekArray();
// Returns the unspecified default values array at the top of the stack.
auto GetUnspecifiedDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
return unspecified_default_values_stack_.PeekArray();
}
private:
// TODO: move default value InstIds to a value store and remove them from the
// pattern stack.
auto AddDefaultValue(SemIR::InstId inst_id, ArrayStack<SemIR::InstId>& stack)
-> SemIR::DefaultValueId {
auto index =
SemIR::DefaultValueId(static_cast<int32_t>(stack.PeekArray().size()));
stack.AppendToTop(inst_id);
return index;
}
LexicalLookup* lookup_;
// The stack of pending full-patterns is organized as a struct of arrays, with
@@ -283,16 +248,9 @@ class FullPatternStack {
// of that frame are not ready for consumption.
llvm::SmallVector<int> next_var_index_stack_;
// The stack of instructions specifying default values for subpatterns
// within this full-pattern. These instructions are as they are written by
// the developer, with no type conversions applied. They are indexed by
// `DefaultValueId` values.
ArrayStack<SemIR::InstId> raw_default_values_stack_;
// The stack of instructions for default values after the conversions to the
// type of the pattern have been applied. They are indexed by `DefaultValueId`
// values.
ArrayStack<SemIR::InstId> converted_default_values_stack_;
// For each full pattern we maintain a list of the InstIds of any
// unspecified default values, for use in diagnostics.
ArrayStack<SemIR::InstId> unspecified_default_values_stack_;
};
} // namespace Carbon::Check
-63
View File
@@ -91,7 +91,6 @@ struct FunctionSignatureInsts {
SemIR::InstBlockId param_patterns_id = SemIR::InstBlockId::None;
SemIR::InstBlockId call_param_patterns_id = SemIR::InstBlockId::None;
SemIR::InstBlockId call_params_id = SemIR::InstBlockId::None;
SemIR::InstBlockId call_param_default_values_id = SemIR::InstBlockId::Empty;
SemIR::Function::CallParamIndexRanges call_param_ranges =
SemIR::Function::CallParamIndexRanges::Empty;
SemIR::TypeInstId return_type_inst_id = SemIR::TypeInstId::None;
@@ -191,8 +190,6 @@ auto MakeGeneratedFunctionDecl(Context& context, SemIR::LocId loc_id,
{
.call_param_patterns_id = insts.call_param_patterns_id,
.call_params_id = insts.call_params_id,
.call_param_default_values_id =
insts.call_param_default_values_id,
.call_param_ranges = insts.call_param_ranges,
.return_type_inst_id = insts.return_type_inst_id,
.return_form_inst_id = insts.return_form_inst_id,
@@ -305,62 +302,6 @@ static auto CheckFunctionEvaluationModeMatches(
return false;
}
// Checks that if `new_id` has a specified value, it has the same value as
// specified by `prev_id`. If `diagnose` is true this will issue a diagnostic
// if it detects a difference. Returns true if the values are the same or
// `new_id` is unspecified.
//
// Note: this function is only called on the function's first owning
// declaration, as that is the declaration with this requirement.
static auto CheckDefaultValueIsSame(Context& context, SemIR::InstId new_id,
SemIR::InstId prev_id, bool diagnose)
-> bool {
CARBON_CHECK(!context.insts().Is<SemIR::UnspecifiedValue>(prev_id));
if (!context.insts().Is<SemIR::UnspecifiedValue>(new_id)) {
auto new_constant_id = context.constant_values().Get(new_id);
auto prev_constant_id = context.constant_values().Get(prev_id);
if (new_constant_id != prev_constant_id) {
if (diagnose) {
CARBON_DIAGNOSTIC(
PatternDefaultValueDiffers, Error,
"default value of {0} differs from the previously declared default "
"value of {1}",
InstIdAsConstant, InstIdAsConstant);
CARBON_DIAGNOSTIC(PatternDefaultValueDiffersNote, Note,
"different previous declaration here");
context.emitter()
.Build(new_id, PatternDefaultValueDiffers, new_id, prev_id)
.Note(prev_id, PatternDefaultValueDiffersNote)
.Emit();
}
return false;
}
}
return true;
}
// Checks every parameter in `prev_function` and `new_function`, that if they
// both specify a default value those values are identical. If `diagnose` is
// true, issues diagnostics when that condition is violated. Returns true if
// every parameter met the condition.
static auto CheckDefaultValueConsistency(Context& context,
const SemIR::Function& new_function,
const SemIR::Function& prev_function,
bool diagnose) -> bool {
auto new_default_value_ids = context.inst_blocks().GetOrEmpty(
new_function.call_param_default_values_id);
auto prev_default_value_ids = context.inst_blocks().GetOrEmpty(
prev_function.call_param_default_values_id);
return llvm::all_of(
llvm::zip_equal(new_default_value_ids, prev_default_value_ids),
[&context, diagnose](auto id_pair) -> bool {
auto [new_id, prev_id] = id_pair;
return CheckDefaultValueIsSame(context, new_id, prev_id, diagnose);
});
}
auto CheckFunctionTypeMatches(Context& context,
const SemIR::Function& new_function,
const SemIR::Function& prev_function,
@@ -379,10 +320,6 @@ auto CheckFunctionTypeMatches(Context& context,
diagnose)) {
return false;
}
if (!CheckDefaultValueConsistency(context, new_function, prev_function,
diagnose)) {
return false;
}
return true;
}
+3 -1
View File
@@ -858,7 +858,9 @@ auto MakeSpecificWithInnerSelf(Context& context, SemIR::LocId loc_id,
if (self_facet == SemIR::ErrorInst::ConstantId) {
args.push_back(SemIR::ErrorInst::InstId);
} else {
auto self_facet_inst_id = context.constant_values().GetInstId(self_facet);
// Use the canonical facet for self in order to produce fewer specifics.
auto self_facet_inst_id = context.constant_values().GetInstId(
GetCanonicalFacet(context, self_facet));
CARBON_CHECK(context.types().Is<SemIR::FacetType>(
context.insts().Get(self_facet_inst_id).type_id()));
args.push_back(self_facet_inst_id);
-1
View File
@@ -51,7 +51,6 @@ auto GlobalInit::Finalize() -> void {
.first_owning_decl_id = SemIR::InstId::None},
{.call_param_patterns_id = SemIR::InstBlockId::Empty,
.call_params_id = SemIR::InstBlockId::Empty,
.call_param_default_values_id = SemIR::InstBlockId::Empty,
.call_param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
.return_type_inst_id = SemIR::TypeInstId::None,
.return_form_inst_id = SemIR::InstId::None,
+1 -1
View File
@@ -613,7 +613,7 @@ auto HandleParseNode(Context& context,
// compile time binding. This is popped when handling the
// CompileTimeBindingPatternId.
context.scope_stack().PushForSameRegion();
MakePeriodSelfFacetValue(context, node_id, GetEmptyFacetType(context));
MakePeriodSelfFacetValue(context, node_id, SemIR::TypeType::TypeId);
context.node_stack().Push(
node_id, SemIR::ElementIndex(context.binding_type_where_count()));
return true;
+170 -162
View File
@@ -373,18 +373,13 @@ static auto DiagnosePositionalParams(Context& context,
function_info.param_patterns_id = SemIR::InstBlockId::Empty;
}
// Diagnoses that the default values for function parameters have been
// Diagnoses any default values for function parameters that have not been
// completely specified, which is a requirement on the first owning declaration
// of a function.
static auto CheckDefaultValuesCompletelySpecified(
Context& context, SemIR::Function& function_info) -> void {
auto unspecified_value_ids = llvm::make_filter_range(
context.inst_blocks().GetOrEmpty(
function_info.call_param_default_values_id),
[&context](auto inst_id) {
return context.insts().Is<SemIR::UnspecifiedValue>(inst_id);
});
for (auto inst_id : unspecified_value_ids) {
static auto DiagnoseDefaultValuesNotSpecified(
Context& context, llvm::ArrayRef<SemIR::InstId> unspecified_inst_ids)
-> void {
for (auto inst_id : unspecified_inst_ids) {
CARBON_DIAGNOSTIC(PatternDefaultValueNotSpecified, Error,
"found unspecified default parameter value in the "
"function's first owning declaration");
@@ -392,6 +387,152 @@ static auto CheckDefaultValuesCompletelySpecified(
}
}
// For the top-level parameter patterns list, and for any level of nested tuple
// patterns, ensure that if a subpattern provides a default value, all
// subsequent patterns at that level of nesting must provide a default value as
// well. Returns the number of default values provided at the top level of the
// function parameter, useful for efficient arity checking in callers later on.
//
// TODO: per https://github.com/carbon-language/carbon-lang/issues/7529, this
// should also consider automatically supplied defaults for fully-specified
// tuple subpatterns, and consider them as having a default for the purposes
// of the out-of-order detection. It will also need to detect the error
// condition when a default is also specified for those fully-specified tuple
// subpatterns.
static auto CheckDefaults(Context& context, SemIR::Function& function)
-> int32_t {
if (!function.param_patterns_id.has_value()) {
return 0;
}
struct PatternLevelState {
// The inst ids of the subpatterns on this level of tuple subpattern
// nesting, treated as a work list, so in reverse order of declaration.
llvm::SmallVector<SemIR::InstId> subpattern_ids;
// If patterns at this level of nesting have default values, this refers
// to the first instruction to specify a default, useful for diagnostics.
SemIR::InstId first_pattern_with_default = SemIR::InstId::None;
// If we encounter a tuple-pattern during processing, we suspend processing
// of this pattern level, in the middle of processing a single pattern from
// root to leaves. So we record the current state of processing of a single
// pattern to return to it after processing any tuple subpatterns.
// True if the current pattern being processed has a default value
// specified.
bool current_pattern_has_default = false;
// The current pattern we are processing, stored separately since it's been
// popped from the `pattern_work_list` and already processed, just may need
// subsequent processing.
SemIR::InstId current_id = SemIR::InstId::None;
// A work list of patterns to be processed at this level of nesting.
llvm::SmallVector<SemIR::InstId> pattern_work_list;
// A list of subpatterns missing required defaults, to coalesce error
// reporting into a single diagnostic.
llvm::SmallVector<SemIR::InstId> patterns_missing_defaults;
// A count of the number of patterns on this level that have defaults.
int32_t default_count = 0;
};
llvm::SmallVector<PatternLevelState> level_state_stack;
size_t default_count = 0;
level_state_stack.push_back({});
llvm::append_range(
level_state_stack.back().subpattern_ids,
llvm::reverse(context.inst_blocks().Get(function.param_patterns_id)));
while (!level_state_stack.empty()) {
PatternLevelState* state = &level_state_stack.back();
while (!state->subpattern_ids.empty() ||
!state->pattern_work_list.empty() || state->current_id.has_value()) {
// If we're not resuming processing a pattern from a nested state, start
// processing the next subpattern.
if (!state->current_id.has_value()) {
state->pattern_work_list.push_back(
state->subpattern_ids.pop_back_val());
state->current_pattern_has_default = false;
}
while (!state->pattern_work_list.empty()) {
state->current_id = state->pattern_work_list.pop_back_val();
auto inst = context.insts().Get(state->current_id);
CARBON_KIND_SWITCH(inst) {
case CARBON_KIND(SemIR::DefaultValuePattern default_value_pattern): {
state->current_pattern_has_default = true;
state->default_count += 1;
state->pattern_work_list.push_back(
default_value_pattern.subpattern_id);
break;
}
case CARBON_KIND(
SemIR::WrapperBindingPattern wrapper_binding_pattern): {
state->pattern_work_list.push_back(
wrapper_binding_pattern.subpattern_id);
break;
}
case CARBON_KIND(SemIR::TuplePattern tuple_pattern): {
auto elements =
context.inst_blocks().Get(tuple_pattern.elements_id);
if (!elements.empty()) {
// Start a new state for the nested tuple pattern elements.
level_state_stack.push_back({});
state = &level_state_stack.back();
llvm::append_range(state->subpattern_ids,
llvm::reverse(elements));
}
break;
}
default:
// We only process patterns containing subpatterns, so this is an
// intentional no-op.
break;
}
}
// Finished processing this subpattern, detect a missing default if
// required.
if (state->current_pattern_has_default &&
!state->first_pattern_with_default.has_value()) {
state->first_pattern_with_default = state->current_id;
} else if (!state->current_pattern_has_default &&
state->first_pattern_with_default.has_value()) {
state->patterns_missing_defaults.push_back(state->current_id);
}
state->current_id = SemIR::InstId::None;
}
// Finished processing this tuple-pattern, emit diagnostics if any.
if (!state->patterns_missing_defaults.empty()) {
CARBON_DIAGNOSTIC(RequiredPatternDefaultValueMissing, Error,
"this pattern is missing a required default value.");
CARBON_DIAGNOSTIC(RequiredPatternDefaultValueFirstDefault, Note,
"all patterns to the right of this first pattern with "
"a default value must also specify a default value.");
CARBON_DIAGNOSTIC(
RequiredPatternDefaultValueMissingAdditional, Note,
"this pattern is also missing a required default value.");
auto inst_ref = llvm::ArrayRef(state->patterns_missing_defaults);
auto builder = context.emitter().Build(
inst_ref.consume_front(), RequiredPatternDefaultValueMissing);
for (auto inst_id : inst_ref) {
builder.Note(inst_id, RequiredPatternDefaultValueMissingAdditional);
}
builder.Note(state->first_pattern_with_default,
RequiredPatternDefaultValueFirstDefault);
builder.Emit();
}
// Extract the count from the level we just completed, overwriting any
// nested level value extracted previously.
default_count = level_state_stack.back().default_count;
level_state_stack.pop_back();
}
return default_count;
}
// Build a FunctionDecl describing the signature of a function. This
// handles the common logic shared by function declaration syntax and function
// definition syntax.
@@ -455,30 +596,32 @@ static auto BuildFunctionDecl(Context& context,
// Build the function entity. This will be merged into an existing function if
// there is one, or otherwise added to the function store.
auto function_info = SemIR::Function{
name_context.MakeEntityWithParamsBase(name, decl_id, is_extern,
introducer.extern_library),
{
.call_param_patterns_id = name.call_param_patterns_id,
.call_params_id = name.call_params_id,
.call_param_default_values_id = name.call_param_default_values_id,
.call_param_ranges = name.param_ranges,
.return_type_inst_id = return_type_inst_id,
.return_form_inst_id = return_form_inst_id,
.return_pattern_id = return_pattern_id,
.virtual_modifier = virtual_modifier,
.evaluation_mode = evaluation_mode,
.interface_modifier = interface_modifier,
.self_param_id = self_param_id,
}};
auto function_info =
SemIR::Function{name_context.MakeEntityWithParamsBase(
name, decl_id, is_extern, introducer.extern_library),
{
.call_param_patterns_id = name.call_param_patterns_id,
.call_params_id = name.call_params_id,
.call_param_ranges = name.param_ranges,
.return_type_inst_id = return_type_inst_id,
.return_form_inst_id = return_form_inst_id,
.return_pattern_id = return_pattern_id,
.virtual_modifier = virtual_modifier,
.evaluation_mode = evaluation_mode,
.interface_modifier = interface_modifier,
.self_param_id = self_param_id,
}};
if (is_definition) {
function_info.definition_id = decl_id;
}
function_info.default_value_arity = CheckDefaults(context, function_info);
DiagnosePositionalParams(context, function_info);
if (name_context.state != DeclNameStack::NameContext::State::Poisoned &&
!name_context.prev_inst_id().has_value()) {
CheckDefaultValuesCompletelySpecified(context, function_info);
DiagnoseDefaultValuesNotSpecified(
context, context.inst_blocks().Get(name.unspecified_values_block_id));
}
TryMergeRedecl(
@@ -602,145 +745,10 @@ static auto DiagnoseUnusedMarkersWithoutDefinition(
}
}
// For the top-level parameter patterns list, and for any level of nested tuple
// patterns, ensure that if a subpattern provides a default value, all
// subsequent patterns at that level of nesting must provide a default value as
// well.
// TODO: per https://github.com/carbon-language/carbon-lang/issues/7529, this
// should also consider automatically supplied defaults for fully-specified
// tuple subpatterns, and consider them as having a default for the purposes
// of the out-of-order detection. It will also need to detect the error
// condition when a default is also specified for those fully-specified tuple
// subpatterns.
static auto DiagnoseOutOfOrderDefaults(Context& context,
SemIR::FunctionId function_id) -> void {
const auto& function = context.functions().Get(function_id);
if (!function.param_patterns_id.has_value()) {
return;
}
struct PatternLevelState {
// The inst ids of the subpatterns on this level of tuple subpattern
// nesting, treated as a work list, so in reverse order of declaration.
llvm::SmallVector<SemIR::InstId> subpattern_ids;
// If patterns at this level of nesting have default values, this refers
// to the first instruction to specify a default, useful for diagnostics.
SemIR::InstId first_pattern_with_default = SemIR::InstId::None;
// If we encounter a tuple-pattern during processing, we suspend processing
// of this pattern level, in the middle of processing a single pattern from
// root to leaves. So we record the current state of processing of a single
// pattern to return to it after processing any tuple subpatterns.
// True if the current pattern being processed has a default value
// specified.
bool current_pattern_has_default = false;
// The current pattern we are processing, stored separately since it's been
// popped from the `pattern_work_list` and already processed, just may need
// subsequent processing.
SemIR::InstId current_id = SemIR::InstId::None;
// A work list of patterns to be processed at this level of nesting.
llvm::SmallVector<SemIR::InstId> pattern_work_list;
// A list of subpatterns missing required defaults, to coalesce error
// reporting into a single diagnostic.
llvm::SmallVector<SemIR::InstId> patterns_missing_defaults;
};
llvm::SmallVector<PatternLevelState> level_state_stack;
level_state_stack.push_back({});
llvm::append_range(
level_state_stack.back().subpattern_ids,
llvm::reverse(context.inst_blocks().Get(function.param_patterns_id)));
while (!level_state_stack.empty()) {
PatternLevelState* state = &level_state_stack.back();
while (!state->subpattern_ids.empty() ||
!state->pattern_work_list.empty() || state->current_id.has_value()) {
// If we're not resuming processing a pattern from a nested state, start
// processing the next subpattern.
if (!state->current_id.has_value()) {
state->pattern_work_list.push_back(
state->subpattern_ids.pop_back_val());
state->current_pattern_has_default = false;
}
while (!state->pattern_work_list.empty()) {
state->current_id = state->pattern_work_list.pop_back_val();
auto inst = context.insts().Get(state->current_id);
CARBON_KIND_SWITCH(inst) {
case CARBON_KIND(SemIR::DefaultValuePattern default_value_pattern): {
state->current_pattern_has_default = true;
state->pattern_work_list.push_back(
default_value_pattern.subpattern_id);
break;
}
case CARBON_KIND(
SemIR::WrapperBindingPattern wrapper_binding_pattern): {
state->pattern_work_list.push_back(
wrapper_binding_pattern.subpattern_id);
break;
}
case CARBON_KIND(SemIR::TuplePattern tuple_pattern): {
auto elements =
context.inst_blocks().Get(tuple_pattern.elements_id);
if (!elements.empty()) {
// Start a new state for the nested tuple pattern elements.
level_state_stack.push_back({});
state = &level_state_stack.back();
llvm::append_range(state->subpattern_ids,
llvm::reverse(elements));
}
break;
}
default:
// We only process patterns containing subpatterns, so this is an
// intentional no-op.
break;
}
}
// Finished processing this subpattern, detect a missing default if
// required.
if (state->current_pattern_has_default &&
!state->first_pattern_with_default.has_value()) {
state->first_pattern_with_default = state->current_id;
} else if (!state->current_pattern_has_default &&
state->first_pattern_with_default.has_value()) {
state->patterns_missing_defaults.push_back(state->current_id);
}
state->current_id = SemIR::InstId::None;
}
// Finished processing this tuple-pattern, emit diagnostics if any.
if (!state->patterns_missing_defaults.empty()) {
CARBON_DIAGNOSTIC(RequiredPatternDefaultValueMissing, Error,
"this pattern is missing a required default value.");
CARBON_DIAGNOSTIC(RequiredPatternDefaultValueFirstDefault, Note,
"all patterns to the right of this first pattern with "
"a default value must also specify a default value.");
CARBON_DIAGNOSTIC(
RequiredPatternDefaultValueMissingAdditional, Note,
"this pattern is also missing a required default value.");
auto inst_ref = llvm::ArrayRef(state->patterns_missing_defaults);
auto builder = context.emitter().Build(
inst_ref.consume_front(), RequiredPatternDefaultValueMissing);
for (auto inst_id : inst_ref) {
builder.Note(inst_id, RequiredPatternDefaultValueMissingAdditional);
}
builder.Note(state->first_pattern_with_default,
RequiredPatternDefaultValueFirstDefault);
builder.Emit();
}
level_state_stack.pop_back();
}
}
auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
auto [function_id, decl_id] =
BuildFunctionDecl(context, node_id, /*is_definition=*/false);
DiagnoseUnusedMarkersWithoutDefinition(context, function_id);
DiagnoseOutOfOrderDefaults(context, function_id);
context.decl_name_stack().PopScope();
return true;
}
+2 -2
View File
@@ -200,9 +200,9 @@ static auto PopImplIntroducerAndParamsAsNameComponent(
.param_patterns_id = SemIR::InstBlockId::None,
.call_param_patterns_id = SemIR::InstBlockId::None,
.call_params_id = SemIR::InstBlockId::None,
.call_param_default_values_id = SemIR::InstBlockId::Empty,
.param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
.pattern_block_id = pattern_block_id};
.pattern_block_id = pattern_block_id,
.unspecified_values_block_id = SemIR::InstBlockId::Empty};
}
// Build an ImplDecl describing the signature of an impl. This handles the
+119 -1
View File
@@ -40,6 +40,92 @@ auto HandleParseNode(Context& context, Parse::InterfaceIntroducerId node_id)
return true;
}
static auto ValidateCoreInterfaceAssociatedFunction(
Context& context, SemIR::InstId decl_id, int index, CoreIdentifier name_id,
SemIR::Function::InterfaceModifier interface_modifier =
SemIR::Function::InterfaceModifier::None) -> bool {
auto loc_id = context.insts().GetCanonicalLocId(decl_id);
auto decl = context.insts().TryGetAs<SemIR::FunctionDecl>(decl_id);
if (!decl) {
context.TODO(loc_id, "associated entity must be a method");
return false;
}
auto fn = context.functions().Get(decl->function_id);
if (fn.name_id != context.core_identifiers().AddNameId(name_id)) {
context.TODO(loc_id,
llvm::formatv("associated function #{} must be named `{}`",
index, name_id));
return false;
}
auto call_params = context.inst_blocks().Get(fn.call_param_patterns_id);
// TODO: extend to support arbitrary parameters.
if (call_params.size() != 1) {
context.TODO(loc_id, "associated function must have exactly 1 parameter");
return false;
}
auto self = context.insts().TryGetAs<SemIR::RefParamPattern>(call_params[0]);
if (!self.has_value() || self->pretty_name_id != SemIR::NameId::SelfValue) {
context.TODO(loc_id,
"associated function must take `ref self` as its parameter");
return false;
}
// TODO: extend to support arbitrary return types.
if (fn.return_type_inst_id.has_value()) {
context.TODO(loc_id, "associated function must not have a return type");
return false;
}
if (fn.interface_modifier != interface_modifier) {
context.TODO(
loc_id,
interface_modifier == SemIR::Function::InterfaceModifier::None
? std::string(
"associated function must not have an interface modifier")
: llvm::formatv("associated function must be `{}`",
interface_modifier));
return false;
}
return true;
}
static auto ValidateCoreDestroy(Context& context, SemIR::LocId loc_id,
SemIR::InstBlockId associated_entities_id)
-> bool {
auto assoc_entities = context.inst_blocks().Get(associated_entities_id);
if (assoc_entities.size() != 3) {
context.TODO(
loc_id,
"interface `Core.Destroy` needs exactly 3 associated functions");
return false;
}
if (!ValidateCoreInterfaceAssociatedFunction(context, assoc_entities[0], 1,
CoreIdentifier::Op)) {
return false;
}
if (!ValidateCoreInterfaceAssociatedFunction(
context, assoc_entities[1], 2, CoreIdentifier::SubobjectDestroy,
SemIR::Function::InterfaceModifier::Final)) {
return false;
}
if (!ValidateCoreInterfaceAssociatedFunction(
context, assoc_entities[2], 3, CoreIdentifier::SelfDestruct,
SemIR::Function::InterfaceModifier::Final)) {
return false;
}
return true;
}
static auto BuildInterfaceDecl(Context& context,
Parse::AnyInterfaceDeclId node_id,
bool is_definition)
@@ -218,7 +304,7 @@ auto HandleParseNode(Context& context,
return true;
}
auto HandleParseNode(Context& context, Parse::InterfaceDefinitionId /*node_id*/)
auto HandleParseNode(Context& context, Parse::InterfaceDefinitionId node_id)
-> bool {
auto interface_id =
context.node_stack().Pop<Parse::NodeKind::InterfaceDefinitionStart>();
@@ -251,6 +337,38 @@ auto HandleParseNode(Context& context, Parse::InterfaceDefinitionId /*node_id*/)
// Finish the definition of interface-without-self.
FinishGenericDefinition(context, interface_info.generic_id);
if (context.sem_ir().package_id() == PackageNameId::Core) {
switch (interface_info.core_interface) {
case SemIR::CoreInterface::Destroy:
return ValidateCoreDestroy(context, node_id,
interface_info.associated_entities_id);
case SemIR::CoreInterface::AddAssignWith:
case SemIR::CoreInterface::AddWith:
case SemIR::CoreInterface::Copy:
case SemIR::CoreInterface::CppRangeForIterate:
case SemIR::CoreInterface::CppUnsafeDeref:
case SemIR::CoreInterface::Dec:
case SemIR::CoreInterface::Default:
case SemIR::CoreInterface::FloatFitsIn:
case SemIR::CoreInterface::DivAssignWith:
case SemIR::CoreInterface::DivWith:
case SemIR::CoreInterface::EqWith:
case SemIR::CoreInterface::Inc:
case SemIR::CoreInterface::IntFitsIn:
case SemIR::CoreInterface::ModAssignWith:
case SemIR::CoreInterface::ModWith:
case SemIR::CoreInterface::MulAssignWith:
case SemIR::CoreInterface::MulWith:
case SemIR::CoreInterface::Negate:
case SemIR::CoreInterface::OrderedWith:
case SemIR::CoreInterface::SubAssignWith:
case SemIR::CoreInterface::SubWith:
case SemIR::CoreInterface::Unknown:
// TODO: validate other core interfaces
return true;
}
}
// The decl_name_stack and scopes are popped by `ProcessNodeIds`.
return true;
}
+4 -6
View File
@@ -58,9 +58,8 @@ auto HandleParseNode(Context& context, Parse::ObserveEqualEqualId node_id)
context.args_type_info_stack().AddInstId(
AddInstInNoBlock<SemIR::ObserveEquivalent>(
context, node_id,
{.lhs_id = GetCanonicalFacetOrTypeValue(context, lhs_as_type.inst_id),
.rhs_id =
GetCanonicalFacetOrTypeValue(context, rhs_as_type.inst_id)}));
{.lhs_id = GetCanonicalFacet(context, lhs_as_type.inst_id),
.rhs_id = GetCanonicalFacet(context, rhs_as_type.inst_id)}));
return true;
}
@@ -90,9 +89,8 @@ auto HandleParseNode(Context& context, Parse::ObserveImplsId node_id) -> bool {
context.args_type_info_stack().AddInstId(
AddInstInNoBlock<SemIR::ObserveImpls>(
context, node_id,
{.lhs_id = GetCanonicalFacetOrTypeValue(context, lhs_as_type.inst_id),
.rhs_id =
GetCanonicalFacetOrTypeValue(context, rhs_as_type.inst_id)}));
{.lhs_id = GetCanonicalFacet(context, lhs_as_type.inst_id),
.rhs_id = GetCanonicalFacet(context, rhs_as_type.inst_id)}));
return true;
}
+15 -9
View File
@@ -154,11 +154,15 @@ auto HandleParseNode(Context& context, Parse::PatternListCommaId /*node_id*/)
auto HandleParseNode(Context& context, Parse::DefaultValueUnspecifiedId node_id)
-> bool {
context.node_stack().Push(
node_id, AddInst<SemIR::UnspecifiedValue>(
context, node_id,
{.type_id = GetSingletonType(
context, SemIR::UnspecifiedValueType::TypeInstId)}));
auto inst_id = AddInst<SemIR::UnspecifiedValue>(
context, node_id,
{.type_id =
GetSingletonType(context, SemIR::UnspecifiedValueType::TypeInstId)});
// Add the unspecified default value for later diagnostics checks.
context.full_pattern_stack().AddUnspecifiedDefaultValue(inst_id);
context.node_stack().Push(node_id, inst_id);
return true;
}
@@ -194,11 +198,13 @@ auto HandleParseNode(Context& context, Parse::DefaultValuePatternId node_id)
return false;
}
// Add the value to the default values array in the full pattern stack, for
// recovery later in the NameComponent. We store the raw value here for
// Add the value to the default values store. We store the raw value here for
// conversion during pattern matching once the type of the pattern is known.
auto default_value_id =
context.full_pattern_stack().AddRawDefaultValue(expr_inst_id);
auto default_value_id = context.default_values().Add(
{.raw_id = expr_inst_id,
.value_id = SemIR::InstId::None,
.is_unspecified =
context.insts().Is<SemIR::UnspecifiedValue>(expr_inst_id)});
// Next on the node stack should be the pattern for which this default was
// specified. We pop that so we can issue the DefaultValuePattern in its
+1 -6
View File
@@ -42,10 +42,6 @@ static auto GetPeriodSelfType(Context& context,
auto frozen_const_id =
FreezePeriodSelf(context, extended_id.AsConstantId());
return context.types().GetTypeIdForTypeConstantId(frozen_const_id);
} else if (facet_type_type_id == SemIR::TypeType::TypeId) {
// The self may be `TypeType` in `type where X impls Y`, so we use an empty
// facet type.
return GetEmptyFacetType(context);
} else {
CARBON_CHECK(facet_type_type_id == SemIR::ErrorInst::TypeId,
"unexpected .Self type {0}", facet_type_type_id);
@@ -435,8 +431,7 @@ auto HandleParseNode(Context& context, Parse::RequirementImplsId node_id)
// Check lhs is a facet and rhs is a facet type.
auto lhs_as_type = ExprAsType(context, lhs_node, lhs_id);
auto rhs_as_type = ExprAsType(context, rhs_node, rhs_id);
if (rhs_as_type.type_id != SemIR::ErrorInst::TypeId &&
!context.types().IsFacetType(rhs_as_type.type_id)) {
if (!context.types().IsFacetTypeOrError(rhs_as_type.type_id)) {
DiagnoseImplsOnNonFacetType(context, rhs_node);
rhs_as_type.type_id = SemIR::ErrorInst::TypeId;
rhs_as_type.inst_id = SemIR::ErrorInst::TypeInstId;
+10 -8
View File
@@ -528,10 +528,10 @@ auto AddImplWitnessForDeclaration(Context& context, SemIR::LocId loc_id,
// value to that type now we know the value of `Self`.
SemIR::TypeId assoc_const_type_id = assoc_constant_decl->type_id;
if (assoc_const_type_id.is_symbolic()) {
auto self_facet = GetConstantFacetValueForType(context, impl.self_id);
auto interface_with_self_specific_id = MakeSpecificWithInnerSelf(
context, loc_id, interface.generic_id, interface.generic_with_self_id,
impl.interface.specific_id, self_facet);
impl.interface.specific_id,
context.constant_values().Get(impl.self_id));
// Get the type of the associated constant in this interface with this
// value for `Self`.
@@ -736,7 +736,11 @@ auto FinishImplWitness(Context& context, const SemIR::Impl& impl) -> void {
}
if (fn.interface_modifier != InterfaceModifier::None) {
witness_value = decl_id;
// We are updating the impl witness table in-place, and we pulled this
// instruction out of a constant value in a different generic, so
// manually ensure the new value gets added to the eval block.
witness_value =
GetOrAddInstWithSpecificConstantValue(context, decl_id);
break;
} else {
CARBON_DIAGNOSTIC(
@@ -861,8 +865,8 @@ auto CheckRequireDeclsSatisfied(Context& context, SemIR::LocId loc_id,
// The IdentifiedFacetType canonicalizes the self facets, so we do the same
// for comparing with it.
auto self_const_id = GetCanonicalFacetOrTypeValue(
context, context.constant_values().Get(impl.self_id));
auto self_const_id =
GetCanonicalFacet(context, context.constant_values().Get(impl.self_id));
// We already identified the `impl.self_id` as the canonical
// `full_constraint_id`, so this should just be a cache lookup and can't fail.
@@ -932,11 +936,9 @@ auto CheckRequireDeclsSatisfied(Context& context, SemIR::LocId loc_id,
return;
}
// Make a facet value for the self type.
auto self_facet = GetConstantFacetValueForType(context, impl.self_id);
auto interface_with_self_specific_id = MakeSpecificWithInnerSelf(
context, loc_id, interface.generic_id, interface.generic_with_self_id,
impl.interface.specific_id, self_facet);
impl.interface.specific_id, context.constant_values().Get(impl.self_id));
for (auto require_id : require_ids) {
const auto& require = context.require_impls().Get(require_id);
+6 -8
View File
@@ -270,7 +270,7 @@ static auto TryGetSpecificWitnessIdForImpl(
// to the facet value here, and if the query was a FacetAccessType we did the
// same there so they still match.
auto deduced_self_const_id =
GetCanonicalFacetOrTypeValue(context, noncanonical_deduced_self_const_id);
GetCanonicalFacet(context, noncanonical_deduced_self_const_id);
if (query_self_const_id != deduced_self_const_id) {
return SemIR::ConstantId::None;
}
@@ -431,8 +431,7 @@ static auto CollectFacetWitnessSources(
// constraints.
const auto& impls = context.where_stack().back().impls;
for (auto [self_const_id, facet_type_const_id] : impls) {
auto canon_self_const_id =
GetCanonicalFacetOrTypeValue(context, self_const_id);
auto canon_self_const_id = GetCanonicalFacet(context, self_const_id);
// TypeType (and ErrorInst) is never stored in the impls stack, so we
// always have a FacetType in `facet_type_const_id`.
auto identified_id = TryToIdentifyFacetType(
@@ -983,8 +982,7 @@ auto LookupImplWitness(Context& context, SemIR::LocId loc_id,
context.insts()
.Get(context.constant_values().GetInstId(query_self_const_id))
.type_id();
CARBON_CHECK((context.types().IsOneOf<SemIR::TypeType, SemIR::FacetType>(
query_self_type_id)));
CARBON_CHECK(context.types().Is<SemIR::FacetType>(query_self_type_id));
// The query facet type value is indeed a facet type.
CARBON_CHECK(context.constant_values().InstIs<SemIR::FacetType>(
query_facet_type_const_id));
@@ -1122,8 +1120,8 @@ auto GetCanonicalQuerySelfForLookupImplWitness(Context& context,
// LookupImplWitness instruction, avoiding multiple constant values for
// `<facet value>` and `<facet value> as type`, which always have the same
// lookup result.
return GetCanonicalFacetOrTypeValue(
context, context.constant_values().Get(self_inst_id));
return GetCanonicalFacet(context,
context.constant_values().Get(self_inst_id));
}
// Record the query which found a final impl witness. It's illegal to
@@ -1171,7 +1169,7 @@ auto EvalLookupSingleFinalWitness(Context& context, SemIR::LocId loc_id,
context.specific_interfaces().Get(eval_query.query_specific_interface_id);
// Ensure specifics don't substitute in weird things for the query self.
CARBON_CHECK(context.types().IsFacetType(
CARBON_CHECK(context.types().Is<SemIR::FacetType>(
context.insts().Get(eval_query.query_self_inst_id).type_id()));
SemIR::ConstantId query_self_const_id =
context.constant_values().Get(eval_query.query_self_inst_id);
+34 -17
View File
@@ -38,6 +38,7 @@
#include "toolchain/sem_ir/inst_kind.h"
#include "toolchain/sem_ir/name_scope.h"
#include "toolchain/sem_ir/observe.h"
#include "toolchain/sem_ir/singleton_insts.h"
#include "toolchain/sem_ir/specific_interface.h"
#include "toolchain/sem_ir/specific_named_constraint.h"
#include "toolchain/sem_ir/type_info.h"
@@ -179,6 +180,9 @@ class ImportContext {
auto import_constant_values() -> const SemIR::ConstantValueStore& {
return import_ir().constant_values();
}
auto import_default_values() -> const SemIR::DefaultValueStore& {
return import_ir().default_values();
}
auto import_entity_names() -> const SemIR::EntityNameStore& {
return import_ir().entity_names();
}
@@ -267,6 +271,9 @@ class ImportContext {
auto local_constant_values() -> SemIR::ConstantValueStore& {
return local_ir().constant_values();
}
auto local_default_values() -> SemIR::DefaultValueStore& {
return local_ir().default_values();
}
auto local_entity_names() -> SemIR::EntityNameStore& {
return local_ir().entity_names();
}
@@ -2306,6 +2313,12 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::DefaultValuePattern inst)
-> ResolveResult {
auto subpattern = GetLocalImportRefInfo(resolver, inst.subpattern_id);
const auto& import_default_value =
resolver.import_default_values().Get(inst.default_value_id);
// We import the first owning declaration of a function, which must always
// have default values completely specified.
CARBON_CHECK(!import_default_value.is_unspecified);
auto value = GetLocalImportRefInfo(resolver, import_default_value.value_id);
if (resolver.HasNewWork()) {
return ResolveResult::Retry();
}
@@ -2316,7 +2329,10 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
.type_id = resolver.local_types().GetTypeIdForTypeConstantId(
subpattern.local_type_const_id),
.subpattern_id = AddLoadedImportRef(resolver, subpattern),
.default_value_id = inst.default_value_id,
.default_value_id = resolver.local_default_values().Add(
{.raw_id = SemIR::InstId::None,
.value_id = AddLoadedImportRef(resolver, value),
.is_unspecified = false}),
});
}
@@ -2425,7 +2441,6 @@ static auto ImportFunctionDecl(
{GetIncompleteLocalEntityBase(context, function_decl_id, import_function),
{.call_param_patterns_id = SemIR::InstBlockId::None,
.call_params_id = SemIR::InstBlockId::None,
.call_param_default_values_id = SemIR::InstBlockId::Empty,
.call_param_ranges = import_function.call_param_ranges,
.return_type_inst_id = SemIR::TypeInstId::None,
.return_form_inst_id = SemIR::InstId::None,
@@ -2571,8 +2586,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
auto call_param_patterns = GetLocalBlockImportRefInfo(
resolver, import_function.call_param_patterns_id);
auto call_param_default_values = GetLocalBlockImportRefInfo(
resolver, import_function.call_param_default_values_id);
auto return_type_const_id = SemIR::ConstantId::None;
if (import_function.return_type_inst_id.has_value()) {
return_type_const_id =
@@ -2627,10 +2640,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
// Add the function declaration.
new_function.call_param_patterns_id =
AddLoadedImportRefBlock(resolver, call_param_patterns);
if (call_param_default_values.has_value()) {
new_function.call_param_default_values_id =
AddLoadedImportRefBlock(resolver, *call_param_default_values);
}
new_function.parent_scope_id = parent_scope_id;
new_function.implicit_param_patterns_id =
AddLoadedImportRefBlock(resolver, implicit_param_patterns);
@@ -2652,6 +2661,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
if (import_function.definition_id.has_value()) {
new_function.definition_id = new_function.first_owning_decl_id;
}
new_function.default_value_arity = import_function.default_value_arity;
switch (import_function.special_function_kind) {
case SemIR::Function::SpecialFunctionKind::CppThunk:
@@ -4570,8 +4580,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
"Constant value of constant instruction should refer to "
"the same instruction");
if (SemIR::IsSingletonInstId(constant_inst_id)) {
// Constants for builtins can be directly copied.
if (SemIR::IsSingletonInstId(constant_inst_id) ||
constant_inst_id == SemIR::TypeType::TypeInstId) {
// Constants for singletons and TypeType can be directly copied.
return ResolveResult::Done(
resolver.local_constant_values().Get(constant_inst_id));
}
@@ -4977,15 +4988,21 @@ auto ImportRefResolver::ResolveType(SemIR::TypeId import_type_id)
auto import_type_const_id = import_ir().types().GetConstantId(import_type_id);
CARBON_CHECK(import_type_const_id.has_value());
if (auto import_type_inst_id = import_ir().types().GetAsTypeInstId(
import_ir().constant_values().GetInstId(import_type_const_id));
SemIR::IsSingletonInstId(import_type_inst_id)) {
// Builtins don't require constant resolution; we can use them directly.
auto import_type_inst_id = import_ir().types().GetAsTypeInstId(
import_ir().constant_values().GetInstId(import_type_const_id));
// Builtin types don't require constant resolution; we can use them directly.
if (SemIR::IsSingletonInstId(import_type_inst_id)) {
// Singletons are all types, and need to go through GetSingletonType to
// complete them.
return GetSingletonType(local_context(), import_type_inst_id);
} else {
return local_types().GetTypeIdForTypeConstantId(
ResolveConstant(import_type_id.AsConstantId()));
} else if (import_type_inst_id == SemIR::TypeType::TypeInstId) {
// TypeType is the other builtin type, and is already complete.
return SemIR::TypeType::TypeId;
}
return local_types().GetTypeIdForTypeConstantId(
ResolveConstant(import_type_id.AsConstantId()));
}
auto ImportRefResolver::HasNewWork() -> bool {
+21 -22
View File
@@ -148,22 +148,21 @@ static auto ScopeNeedsImplLookup(Context& context,
SemIR::InstId inst_id =
context.constant_values().GetInstId(name_scope_const_id);
CARBON_CHECK(inst_id.has_value());
SemIR::Inst inst = context.insts().Get(inst_id);
if (inst.Is<SemIR::FacetType>()) {
// Don't perform impl lookup if an associated entity is named as a member of
// a facet type.
return false;
}
if (inst.Is<SemIR::Namespace>()) {
if (context.insts().Is<SemIR::Namespace>(inst_id)) {
// Don't perform impl lookup if an associated entity is named as a namespace
// member.
// TODO: This case is not yet listed in the design.
return false;
}
auto type_id = context.types().GetTypeIdForTypeInstId(inst_id);
// Don't perform impl lookup if an associated entity is named as a member of
// a constrained facet type.
//
// Any other kind of scope is assumed to be a type that implements the
// interface containing the associated entity, and impl lookup is performed.
return true;
return !context.types().IsConstrainedFacetType(type_id);
}
static auto PerformImplWitnessAccessAndSubstitute(
@@ -490,9 +489,8 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
SemIR::InstId base_id, SemIR::NameId name_id,
bool required) -> SemIR::InstId {
// Unwrap the facet value in `base_id` if possible.
if (auto facet_value = TryGetCanonicalFacetValue(context, base_id);
facet_value.has_value()) {
base_id = facet_value;
if (auto facet = TryGetCanonicalFacet(context, base_id); facet.has_value()) {
base_id = facet;
}
// If the base is a name scope, such as a class or namespace, perform lookup
@@ -515,7 +513,7 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
// `base_id` (as part the class case above), as the `base_id` facet should
// have member names that directly name members of the `impl`.
auto base_type_id = context.insts().Get(base_id).type_id();
if (context.types().Is<SemIR::FacetType>(base_type_id)) {
if (context.types().IsConstrainedFacetType(base_type_id)) {
// Name lookup into a facet requires the facet type to be complete, so
// that any names available through the facet type are known for the
// facet.
@@ -589,15 +587,15 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
auto lookup_const_id =
context.types().GetConstantId(unqualified_base_type_id);
// TODO: If the type is a facet, we look through it into the facet's type (a
// FacetType) for names. According to the design, we shouldn't need to do
// this, as the facet should have member names that directly name members of
// the `impl`.
auto base_type_as_facet = GetCanonicalFacetOrTypeValue(
context, context.types().GetTypeInstId(base_type_id));
// TODO: If the type is a constrained facet, we look through it into the
// facet's type (a FacetType) for names. According to the design, we shouldn't
// need to do this, as the facet should have member names that directly name
// members of the `impl`.
auto base_type_as_facet =
GetCanonicalFacet(context, context.types().GetTypeInstId(base_type_id));
auto base_type_facet_type_id =
context.insts().Get(base_type_as_facet).type_id();
if (context.types().Is<SemIR::FacetType>(base_type_facet_type_id)) {
if (context.types().IsConstrainedFacetType(base_type_facet_type_id)) {
lookup_const_id = context.types().GetConstantId(base_type_facet_type_id);
}
@@ -606,11 +604,12 @@ static auto PerformActionHelper(Context& context, SemIR::LocId loc_id,
if (AppendLookupScopesForConstant(
context, loc_id, lookup_const_id,
// The `self_type_const_id` should be the type of `base_id` even if
// it's a facet.
// it's a constrained facet.
//
// TODO: This can be replaced with `lookup_const_id` once we stop
// having to look through the facet at its type for the scope.
context.types().GetConstantId(base_type_id), /*extended_scope=*/false,
// having to look through the constrained facet at its type for the
// scope.
base_type_id.AsConstantId(), /*extended_scope=*/false,
&lookup_scopes)) {
auto member_id = LookupMemberNameInScope(
context, loc_id, base_id, name_id, lookup_const_id, lookup_scopes,
+24 -5
View File
@@ -339,14 +339,33 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
auto prev_default_value_pattern =
prev_param_pattern.As<SemIR::DefaultValuePattern>();
// If the new pattern specified a default value, it must match the
// previously declared default value.
auto& new_default_value = context.default_values().Get(
new_default_value_pattern.default_value_id);
const auto& prev_default_value = context.default_values().Get(
prev_default_value_pattern.default_value_id);
if (!new_default_value.is_unspecified) {
// We require first owning declaration to always specify a default
// value.
CARBON_CHECK(!prev_default_value.is_unspecified);
auto new_constant_id =
context.constant_values().Get(new_default_value.value_id);
auto prev_constant_id =
context.constant_values().Get(prev_default_value.value_id);
if (new_constant_id != prev_constant_id) {
emit_general_diagnostic();
return false;
}
} else {
// If the new default value was left unspecified, we copy the previous
// processed default value into the new default value.
new_default_value.value_id = prev_default_value.value_id;
}
pattern_stack.push_back(
{.prev_id = prev_default_value_pattern.subpattern_id,
.new_id = new_default_value_pattern.subpattern_id});
// The node kind comparison should catch this on the mismatched patterns
// prior to this, so the indices should never mismatch.
CARBON_CHECK(prev_default_value_pattern.default_value_id.index ==
new_default_value_pattern.default_value_id.index);
break;
}
default: {
+16 -21
View File
@@ -45,10 +45,10 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
}
auto call_param_patterns_id = SemIR::InstBlockId::None;
auto call_param_default_values_id = SemIR::InstBlockId::Empty;
auto call_params_id = SemIR::InstBlockId::None;
auto param_ranges = SemIR::Function::CallParamIndexRanges::Empty;
auto pattern_block_id = SemIR::InstBlockId::None;
auto unspecified_values_block_id = SemIR::InstBlockId::Empty;
if (param_patterns_id->has_value() ||
implicit_param_patterns_id->has_value() ||
return_pattern_id.has_value()) {
@@ -57,11 +57,8 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
call_param_patterns_id = results.call_param_patterns_id;
call_params_id = results.call_params_id;
param_ranges = results.param_ranges;
CARBON_CHECK(
context.full_pattern_stack().GetRawDefaultValues().size() ==
context.full_pattern_stack().GetConvertedDefaultValues().size());
call_param_default_values_id = context.inst_blocks().Add(
context.full_pattern_stack().GetConvertedDefaultValues());
unspecified_values_block_id = context.inst_blocks().Add(
context.full_pattern_stack().GetUnspecifiedDefaultValues());
pattern_block_id = context.pattern_block_stack().Pop();
context.full_pattern_stack().PopFullPattern();
}
@@ -69,21 +66,19 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
auto [name_loc_id, name_id] =
context.node_stack().PopWithNodeId<Parse::NodeCategory::NonExprName>();
return {
.name_loc_id = name_loc_id,
.name_id = name_id,
.first_param_node_id = first_param_node_id,
.last_param_node_id = last_param_node_id,
.implicit_params_loc_id = implicit_params_node_id,
.implicit_param_patterns_id = *implicit_param_patterns_id,
.params_loc_id = params_node_id,
.param_patterns_id = *param_patterns_id,
.call_param_patterns_id = call_param_patterns_id,
.call_params_id = call_params_id,
.call_param_default_values_id = call_param_default_values_id,
.param_ranges = param_ranges,
.pattern_block_id = pattern_block_id,
};
return {.name_loc_id = name_loc_id,
.name_id = name_id,
.first_param_node_id = first_param_node_id,
.last_param_node_id = last_param_node_id,
.implicit_params_loc_id = implicit_params_node_id,
.implicit_param_patterns_id = *implicit_param_patterns_id,
.params_loc_id = params_node_id,
.param_patterns_id = *param_patterns_id,
.call_param_patterns_id = call_param_patterns_id,
.call_params_id = call_params_id,
.param_ranges = param_ranges,
.pattern_block_id = pattern_block_id,
.unspecified_values_block_id = unspecified_values_block_id};
}
// Pop the name of a declaration from the node stack, and diagnose if it has
+3 -2
View File
@@ -40,12 +40,13 @@ struct NameComponent {
// SemIR::EntityWithParamsBase).
SemIR::InstBlockId call_param_patterns_id;
SemIR::InstBlockId call_params_id;
// The pattern default values as extracted from the parameter list.
SemIR::InstBlockId call_param_default_values_id;
SemIR::Function::CallParamIndexRanges param_ranges;
// The pattern block.
SemIR::InstBlockId pattern_block_id;
// The `UnspecifiedValue` insts from the parameter default values, if any.
SemIR::InstBlockId unspecified_values_block_id;
};
// Pops a name component from the node stack (and pattern block stack, if it has
+32 -49
View File
@@ -9,7 +9,6 @@
#include "common/raw_string_ostream.h"
#include "toolchain/check/control_flow.h"
#include "toolchain/check/cpp/import.h"
#include "toolchain/check/facet_type.h"
#include "toolchain/check/generic.h"
#include "toolchain/check/import.h"
#include "toolchain/check/import_ref.h"
@@ -22,6 +21,7 @@
#include "toolchain/sem_ir/generic.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/name_scope.h"
#include "toolchain/sem_ir/typed_insts.h"
namespace Carbon::Check {
@@ -297,50 +297,24 @@ struct ProhibitedAccessInfo {
static auto GetSelfFacetForInterfaceFromLookupSelfType(
Context& context, const SemIR::GenericId generic_with_self_id,
SemIR::ConstantId self_type_const_id) -> SemIR::ConstantId {
if (!self_type_const_id.has_value()) {
// In a lookup into a non-lexical scope, there is no self-type from the
// lookup for the interface-with-self specific. So the self-type we use is
// the abstract symbolic Self from the self specific of the
// interface-with-self.
auto self_specific_args_id = context.specifics().GetArgsOrEmpty(
context.generics().GetSelfSpecific(generic_with_self_id));
auto self_specific_args = context.inst_blocks().Get(self_specific_args_id);
return context.constant_values().Get(self_specific_args.back());
if (self_type_const_id.has_value() &&
!context.constant_values().InstIs<SemIR::FacetType>(self_type_const_id)) {
// Extended name lookup into the type of `x`, such as in a member access
// `x.F`. We can find a facet type extended scope from the type of `x`.
return self_type_const_id;
}
if (context.constant_values().InstIs<SemIR::FacetType>(self_type_const_id)) {
// We are looking directly in a facet type, like `I.F` for an interface `I`,
// which means there is no self-type from the lookup for the
// interface-with-self specific. So the self-type we use is the abstract
// symbolic Self from the self specific of the interface-with-self.
auto self_specific_args_id = context.specifics().GetArgsOrEmpty(
context.generics().GetSelfSpecific(generic_with_self_id));
auto self_specific_args = context.inst_blocks().Get(self_specific_args_id);
return context.constant_values().Get(self_specific_args.back());
}
// Extended name lookup into a type, like `x.F`, can find a facet
// type extended scope from the type of `x`. The type of `x` maybe a
// facet converted to a type, so drop the `as type` conversion if
// so.
auto canonical_facet_or_type =
GetCanonicalFacetOrTypeValue(context, self_type_const_id);
auto type_of_canonical_facet_or_type =
context.insts()
.Get(context.constant_values().GetInstId(canonical_facet_or_type))
.type_id();
if (type_of_canonical_facet_or_type == SemIR::TypeType::TypeId) {
// If we still have a type, turn it into a facet for use in the
// interface-with-self specific.
return GetConstantFacetValueForType(
context, context.types().GetAsTypeInstId(
context.constant_values().GetInstId(self_type_const_id)));
}
// We have a facet for the self-type (or perhaps an ErrorInst), which we can
// use directly in the interface-with-self specific.
return canonical_facet_or_type;
// If `self_type_const_id` is None, we are doing lookup into a non-lexical
// scope. If it is a `FacetType`, then we are doing lookup directly on a facet
// type, such as `I.F` on an interface `I`.
//
// In these cases, there is no self-type from the lookup for the
// interface-with-self specific. So the self-type we use is the abstract
// symbolic Self from the self specific of the interface-with-self.
auto self_specific_args_id = context.specifics().GetArgsOrEmpty(
context.generics().GetSelfSpecific(generic_with_self_id));
auto self_specific_args = context.inst_blocks().Get(self_specific_args_id);
return context.constant_values().Get(self_specific_args.back());
}
auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
@@ -350,15 +324,16 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
llvm::SmallVector<LookupScope>* scopes)
-> bool {
auto lookup_inst_id = context.constant_values().GetInstId(lookup_const_id);
auto lookup = context.insts().Get(lookup_inst_id);
if (auto ns = lookup.TryAs<SemIR::Namespace>()) {
if (auto ns = context.insts().TryGetAs<SemIR::Namespace>(lookup_inst_id)) {
scopes->push_back(LookupScope{.name_scope_id = ns->name_scope_id,
.specific_id = SemIR::SpecificId::None,
.self_const_id = SemIR::ConstantId::None});
return true;
}
if (auto class_ty = lookup.TryAs<SemIR::ClassType>()) {
if (auto class_ty =
context.insts().TryGetAs<SemIR::ClassType>(lookup_inst_id)) {
if (!extended_scope) {
// TODO: Allow name lookup into classes that are being defined even if
// they are not complete.
@@ -378,8 +353,14 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
.self_const_id = self_type_const_id});
return true;
}
// Extended scopes may point to a FacetType.
if (auto facet_type = lookup.TryAs<SemIR::FacetType>()) {
// Extended scopes may point to a FacetType. If it has constraints, collect
// the extended ones as scopes.
auto lookup_type_id =
context.types().TryGetTypeIdForTypeInstId(lookup_inst_id);
if (lookup_type_id.has_value() &&
context.types().IsConstrainedFacetType(lookup_type_id)) {
auto facet_type = context.types().GetAs<SemIR::FacetType>(lookup_type_id);
if (!extended_scope) {
// TODO: Allow name lookup into facet types that are being defined even if
// they are not complete.
@@ -405,7 +386,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
}
auto declared_facet_type =
context.declared_facet_types().Get(facet_type->declared_facet_type_id);
context.declared_facet_types().Get(facet_type.declared_facet_type_id);
// Name lookup into "extend" constraints but not "self impls" constraints.
for (const auto& extend : declared_facet_type.extend_constraints) {
auto& interface = context.interfaces().Get(extend.interface_id);
@@ -440,6 +421,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
}
return true;
}
if (lookup_const_id == SemIR::ErrorInst::ConstantId) {
// Lookup into this scope should fail without producing an error.
scopes->push_back(LookupScope{.name_scope_id = SemIR::NameScopeId::None,
@@ -447,6 +429,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
.self_const_id = SemIR::ConstantId::None});
return true;
}
// TODO: Per the design, if `base_id` is any kind of type, then lookup should
// treat it as a name scope, even if it doesn't have members. For example,
// `(i32*).X` should fail because there's no name `X` in `i32*`, not because
+45 -23
View File
@@ -119,7 +119,9 @@ using State =
class MatchContext {
public:
struct PreWork : Printable<PreWork> {
// `None` when processing the callee side.
// `None` when processing the callee side, or when processing the caller
// side and no value was supplied, in expectation of using a default value
// from the corresponding callee pattern.
SemIR::InstId scrutinee_id;
auto Print(llvm::raw_ostream& out) const -> void {
@@ -936,13 +938,31 @@ auto MatchContext::DoPreWork(State state,
SemIR::DefaultValuePattern default_value_pattern,
SemIR::InstId scrutinee_id, WorkItem entry)
-> void {
if (!std::holds_alternative<CalleeState*>(state)) {
CARBON_FATAL("Unhandled state kind in DefaultValuePattern pre-work");
CARBON_KIND_SWITCH(state) {
case CARBON_KIND(CallerState* _): {
// If there's no scrutinee supplied, supply the default value instead.
if (!scrutinee_id.has_value()) {
const auto& default_value = context_.default_values().Get(
default_value_pattern.default_value_id);
CARBON_CHECK(default_value.value_id.has_value());
auto [inst_id, _] = WrapInstForSpecific(
context_, SemIR::LocId(default_value.value_id),
default_value.value_id, specific_id_stack_.back());
scrutinee_id = inst_id;
}
break;
}
case CARBON_KIND(CalleeState* _): {
// We will need to check the type of the parameter to make sure it
// matches the provided default, so add ourselves to the post-work list.
results_stack_.PushArray();
AddAsPostWork(entry);
break;
}
default: {
CARBON_FATAL("Unhandled state kind in DefaultValuePattern pre-work");
}
}
// We will need to check the type of the parameter to make sure it
// matches the provided default, so add ourselves to the post-work list.
results_stack_.PushArray();
AddAsPostWork(entry);
// Process the subpattern for the default.
AddWork({.pattern_id = default_value_pattern.subpattern_id,
@@ -962,21 +982,13 @@ auto MatchContext::DoPostWork(State state,
// If a constant was specified, we should be able to convert it into the
// type of the parameter.
auto raw_default_value_inst_id =
context_.full_pattern_stack()
.GetRawDefaultValues()[default_value_pattern.default_value_id.index];
auto converted_inst_id =
context_.insts().Is<SemIR::UnspecifiedValue>(raw_default_value_inst_id)
? raw_default_value_inst_id
: ConvertToValueOfType(context_,
SemIR::LocId(raw_default_value_inst_id),
raw_default_value_inst_id, param_type_id);
// The index of the converted value should be the same as the raw value.
auto converted_default_id =
context_.full_pattern_stack().AddConvertedDefaultValue(converted_inst_id);
CARBON_CHECK(converted_default_id.index ==
default_value_pattern.default_value_id.index);
auto& default_value =
context_.default_values().Get(default_value_pattern.default_value_id);
if (!default_value.is_unspecified) {
default_value.value_id =
ConvertToValueOfType(context_, SemIR::LocId(default_value.raw_id),
default_value.raw_id, param_type_id);
}
results_stack_.PopArray();
@@ -1234,9 +1246,19 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id,
CARBON_CHECK(self_pattern_id.has_value());
}
for (const auto& [arg_id, param_pattern_id] : llvm::zip_equal(
// `arg_refs` may have a smaller arity than `param_patterns_id` due to the
// possible presence of default values for some parameters. We use
// `zip_longest` here to allow for that size disparity. But we presume we
// always have a parameter pattern, so test that presumption here.
CARBON_CHECK(self_arg_refs.size() + arg_refs.size() <=
context.inst_blocks().GetOrEmpty(param_patterns_id).size());
for (const auto& [maybe_arg_id, maybe_param_pattern_id] : llvm::zip_longest(
llvm::concat<const SemIR::InstId>(self_arg_refs, arg_refs),
context.inst_blocks().GetOrEmpty(param_patterns_id))) {
CARBON_CHECK(maybe_param_pattern_id.has_value());
const auto& param_pattern_id = *maybe_param_pattern_id;
const auto& arg_id =
maybe_arg_id.has_value() ? *maybe_arg_id : SemIR::InstId::None;
match.Match(&state,
{.pattern_id = param_pattern_id,
.work = MatchContext::PreWork{.scrutinee_id = arg_id},
+15 -28
View File
@@ -22,8 +22,7 @@ namespace Carbon::Check {
auto MakePeriodSelfFacetValue(Context& context, SemIR::LocId loc_id,
SemIR::TypeId self_type_id) -> SemIR::InstId {
CARBON_CHECK(self_type_id == SemIR::ErrorInst::TypeId ||
context.types().Is<SemIR::FacetType>(self_type_id));
CARBON_CHECK(context.types().IsFacetTypeOrError(self_type_id));
auto entity_name_id = context.entity_names().AddCanonical(
{.name_id = SemIR::NameId::PeriodSelf,
.parent_scope_id = context.scope_stack().PeekNameScopeId(),
@@ -57,8 +56,7 @@ static auto TryGetAsPeriodSelf(Context& context, SemIR::InstId inst_id,
return std::nullopt;
}
auto query_inst_id =
canonicalize ? GetCanonicalFacetOrTypeValue(context, const_inst_id)
: inst_id;
canonicalize ? GetCanonicalFacet(context, const_inst_id) : inst_id;
if (auto bind =
context.insts().TryGetAs<SemIR::SymbolicBinding>(query_inst_id)) {
const auto& entity_name = context.entity_names().Get(bind->entity_name_id);
@@ -122,7 +120,7 @@ class SubstPeriodSelfCallbacks : public SubstInstCallbacks {
context().constant_values().GetInstId(period_self_replacement_id_);
auto replacement_type_id =
context().insts().Get(replacement_self_inst_id).type_id();
CARBON_CHECK(context().types().IsFacetType(replacement_type_id));
CARBON_CHECK(context().types().Is<SemIR::FacetType>(replacement_type_id));
// If the replacement has the same type as `.Self`, use it directly.
if (replacement_type_id == period_self_type_id) {
@@ -136,42 +134,32 @@ class SubstPeriodSelfCallbacks : public SubstInstCallbacks {
}
// Convert the replacement facet to the type of `.Self`.
cached_replacement_id_ =
ConvertReplacement(replacement_self_inst_id, replacement_type_id,
period_self, period_self_type_id);
cached_replacement_id_ = ConvertReplacement(
replacement_self_inst_id, period_self, period_self_type_id);
cached_replacement_type_id_ = period_self_type_id;
return cached_replacement_id_;
}
auto ConvertReplacement(SemIR::InstId replacement_self_inst_id,
SemIR::TypeId replacement_type_id,
SemIR::InstId period_self_inst_id,
SemIR::TypeId period_self_type_id) -> SemIR::InstId {
// TODO: Replace all empty facet types with TypeType.
if (period_self_type_id == GetEmptyFacetType(context())) {
// Convert to an empty facet type (representing TypeType); we don't need
// any witnesses.
return ConvertToValueOfType(context(), loc_id_, replacement_self_inst_id,
period_self_type_id);
// Ensure the replacement is a type, which we will need for the return or to
// construct FacetValue.
auto replacement_self_type_inst_id = context().types().GetTypeInstId(
GetFacetAccessType(context(), replacement_self_inst_id));
if (period_self_type_id == SemIR::TypeType::TypeId) {
return replacement_self_type_inst_id;
}
// We have a facet or a type, but we need more interfaces in the facet type.
// We will have to synthesize a symbolic witness for each interface.
// We have a replacement facet (converted to `type`), but we need different
// interfaces than we had in the facet's type. We will have to synthesize a
// symbolic witness for each interface.
//
// Why is this okay? The type of `.Self` comes from interfaces that are
// before it (to the left of it) in the facet type. The replacement for
// `.Self` will have to impl those interfaces in order to match the facet
// type, so we know that it is valid to construct these witnesses.
// Make the replacement into a type, which we will need for the FacetValue.
if (context().types().Is<SemIR::FacetType>(replacement_type_id)) {
replacement_self_inst_id = context().constant_values().GetInstId(
EvalOrAddInst<SemIR::FacetAccessType>(
context(), loc_id_,
{.type_id = SemIR::TypeType::TypeId,
.facet_value_inst_id = replacement_self_inst_id}));
}
auto witnesses = MakeWitnessesForPeriodSelfTypeWithoutLookup(
context(), loc_id_,
context().constant_values().Get(replacement_self_inst_id),
@@ -184,8 +172,7 @@ class SubstPeriodSelfCallbacks : public SubstInstCallbacks {
context(), loc_id_,
{
.type_id = period_self_type_id,
.type_inst_id =
context().types().GetAsTypeInstId(replacement_self_inst_id),
.type_inst_id = replacement_self_type_inst_id,
.witnesses_block_id = witnesses.inst_block_id(),
}));
}
+1 -1
View File
@@ -72,7 +72,7 @@ auto SubstPeriodSelfInFacetType(Context& context, SemIR::LocId loc_id,
// Returns whether the constant value of `inst_id` is a reference to `.Self`.
//
// If `canonicalize` is true, look at the constant value of `inst_id` and get
// the canonicalized facet or type to look through FacetAccessType.
// the canonicalized facet to look through FacetAccessType.
auto IsPeriodSelf(Context& context, SemIR::InstId inst_id,
bool canonicalize = true) -> bool;
+3
View File
@@ -158,6 +158,7 @@ extern alias C = Class;
// CHECK:STDOUT: --- alias.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -174,6 +175,7 @@ extern alias C = Class;
// CHECK:STDOUT: --- alias_of_alias.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %C [concrete]
@@ -211,6 +213,7 @@ extern alias C = Class;
// CHECK:STDOUT: --- alias_to_generic.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = generic_class_type @A [concrete]
// CHECK:STDOUT: %A.generic: %A.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
+6
View File
@@ -39,6 +39,7 @@ let a_test: bool = a;
// CHECK:STDOUT: --- i32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: }
@@ -50,6 +51,10 @@ let a_test: bool = a;
// CHECK:STDOUT:
// CHECK:STDOUT: --- bool.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %.loc5: type = type_literal bool [concrete = bool]
// CHECK:STDOUT: %b: type = alias_binding b, %.loc5 [concrete = bool]
@@ -58,6 +63,7 @@ let a_test: bool = a;
// CHECK:STDOUT: --- bool_value.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %false: bool = bool_literal false [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type bool [concrete]
// CHECK:STDOUT: %a_test.patt: %pattern_type = value_binding_pattern a_test [concrete]
+6
View File
@@ -75,6 +75,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- base.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -110,6 +111,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- export.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -147,6 +149,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- export_orig.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -184,6 +187,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- use_export.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -240,6 +244,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- fail_orig_name_not_in_export.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -280,6 +285,7 @@ var d: D* = &c;
// CHECK:STDOUT: --- indirect_compat.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
+6
View File
@@ -68,6 +68,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- class1.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -143,6 +144,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- class2.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -224,6 +226,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- class3.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -300,6 +303,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- var1.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
@@ -347,6 +351,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- var2.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %a.patt: %pattern_type = ref_binding_pattern a [concrete]
@@ -402,6 +407,7 @@ var c: () = a_alias_alias;
// CHECK:STDOUT: --- var3.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
+4
View File
@@ -59,6 +59,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: --- def.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -85,6 +86,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: --- def.impl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -138,6 +140,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: --- fail_local_def.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -172,6 +175,7 @@ var inst: Test.A = {};
// CHECK:STDOUT: --- fail_other_def.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: }
+2
View File
@@ -36,6 +36,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: --- a.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
@@ -79,6 +80,7 @@ var a_val: a = {.v = b_val.v};
// CHECK:STDOUT: --- b.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %struct_type.v: type = struct_type {.v: %empty_tuple.type} [concrete]
+1
View File
@@ -49,6 +49,7 @@ fn F() -> {} {
// CHECK:STDOUT: --- in_namespace.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
+2
View File
@@ -46,6 +46,7 @@ fn F() -> () {
// CHECK:STDOUT: --- global.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -64,6 +65,7 @@ fn F() -> () {
// CHECK:STDOUT: --- fail_local.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
+330 -20
View File
@@ -108,6 +108,7 @@ var a: array(1, 1);
// CHECK:STDOUT: --- assign_var.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete]
@@ -171,11 +172,13 @@ var a: array(1, 1);
// CHECK:STDOUT: --- array_in_place.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.ff9 = tuple_value (%C, %C, %C) [concrete]
// CHECK:STDOUT: %tuple.type.531: type = tuple_type (type, type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.531 = tuple_value (%C, %C, %C) [concrete]
// CHECK:STDOUT: %tuple.type.a8c: type = tuple_type (%C, %C, %C) [concrete]
// CHECK:STDOUT: %pattern_type.730: type = pattern_type %tuple.type.a8c [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
@@ -187,8 +190,93 @@ var a: array(1, 1);
// CHECK:STDOUT: %tuple.type.8c7: type = tuple_type (%tuple.type.a8c, %tuple.type.a8c) [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc10_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete]
// CHECK:STDOUT: %self.param_patt.99a: %pattern_type.98b = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.cbd: %pattern_type.98b = wrapper_binding_pattern self, %self.param_patt.99a [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc10_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.bed: %pattern_type.730 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.d67: %pattern_type.730 = wrapper_binding_pattern self, %self.param_patt.bed [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc10_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.e5f: %pattern_type.c3e = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.1ad: %pattern_type.c3e = wrapper_binding_pattern self, %self.param_patt.e5f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.4: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.4: type = fn_type @Destroy.WithSelf.Op.loc10_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.4: %Destroy.WithSelf.Op.type.ef016f.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.4: type = fn_type @Destroy.WithSelf.SelfDestruct.loc10_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.4: %Destroy.WithSelf.SelfDestruct.type.fbceb5.4 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc10_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.98b = ref_param_pattern [concrete = constants.%self.param_patt.99a]
// CHECK:STDOUT: %self.patt: %pattern_type.98b = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.cbd]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %C = ref_param call_param0
// CHECK:STDOUT: %self: ref %C = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc10_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.98b = ref_param_pattern [concrete = constants.%self.param_patt.99a]
// CHECK:STDOUT: %self.patt: %pattern_type.98b = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.cbd]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %C = ref_param call_param0
// CHECK:STDOUT: %self: ref %C = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_3.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.730 = ref_param_pattern [concrete = constants.%self.param_patt.bed]
// CHECK:STDOUT: %self.patt: %pattern_type.730 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.d67]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type.a8c = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type.a8c = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc10_3.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.730 = ref_param_pattern [concrete = constants.%self.param_patt.bed]
// CHECK:STDOUT: %self.patt: %pattern_type.730 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.d67]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type.a8c = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type.a8c = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.4: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_3.4 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.4] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c3e = ref_param_pattern [concrete = constants.%self.param_patt.e5f]
// CHECK:STDOUT: %self.patt: %pattern_type.c3e = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.1ad]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.4: %Destroy.WithSelf.Op.type.ef016f.4 = fn_decl @Destroy.WithSelf.Op.loc10_3.4 [concrete = constants.%Destroy.WithSelf.Op.403171.4] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c3e = ref_param_pattern [concrete = constants.%self.param_patt.e5f]
// CHECK:STDOUT: %self.patt: %pattern_type.c3e = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.1ad]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
@@ -214,7 +302,7 @@ var a: array(1, 1);
// CHECK:STDOUT: %C.ref.loc10_24: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %C.ref.loc10_27: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %C.ref.loc10_30: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %.loc10_31.1: %tuple.type.ff9 = tuple_literal (%C.ref.loc10_24, %C.ref.loc10_27, %C.ref.loc10_30) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc10_31.1: %tuple.type.531 = tuple_literal (%C.ref.loc10_24, %C.ref.loc10_27, %C.ref.loc10_30) [concrete = constants.%tuple]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
// CHECK:STDOUT: %.loc10_31.2: type = converted %.loc10_31.1, constants.%tuple.type.a8c [concrete = constants.%tuple.type.a8c]
// CHECK:STDOUT: %array_type: type = array_type %int_2, %.loc10_31.2 [concrete = constants.%array_type]
@@ -224,31 +312,68 @@ var a: array(1, 1);
// CHECK:STDOUT: %v.patt: %pattern_type.c3e = ref_binding_pattern v [concrete = constants.%v.patt]
// CHECK:STDOUT: %v.var_patt: %pattern_type.c3e = var_pattern %v.patt [concrete = constants.%v.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %v.var, constants.%Destroy.WithSelf.Op.403171.4
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%v.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %v.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.4
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%v.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.2(%self.param: ref %C) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_3.2(%self.param: ref %C) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.3(%self.param: ref %tuple.type.a8c) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.2(%self.param: ref %C) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_3.2(%self.param: ref %C) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_3.3(%self.param: ref %tuple.type.a8c) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.4(%self.param: ref %array_type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.3(%self.param: ref %tuple.type.a8c) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_3.3(%self.param: ref %tuple.type.a8c) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_3.4(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_3.4(%self.param: ref %array_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_3.4(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.4(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.4(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- array_vs_tuple.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete]
@@ -269,10 +394,29 @@ var a: array(1, 1);
// CHECK:STDOUT: %b.var_patt: %pattern_type.8c1 = var_pattern %b.patt [concrete]
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness.b33: <witness> = impl_witness imports.%DefaultOrUnformed.impl_witness_table.856, @T.as.DefaultOrUnformed.impl(%tuple.type) [concrete]
// CHECK:STDOUT: %DefaultOrUnformed.facet.f59: %DefaultOrUnformed.type = facet_value %tuple.type, (%DefaultOrUnformed.impl_witness.b33) [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %self.param_patt.65a: %pattern_type.cb1 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.df1: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt.65a [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc8_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc8_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.327: %pattern_type.8c1 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.570: %pattern_type.8c1 = wrapper_binding_pattern self, %self.param_patt.327 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc8_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc8_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc8_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.279: %pattern_type.035 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.06d: %pattern_type.035 = wrapper_binding_pattern self, %self.param_patt.279 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -280,6 +424,51 @@ var a: array(1, 1);
// CHECK:STDOUT: %DefaultOrUnformed.impl_witness_table.856 = impl_witness_table (%Core.import_ref.cc8), @T.as.DefaultOrUnformed.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc8_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc8_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc8_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.8c1 = ref_param_pattern [concrete = constants.%self.param_patt.327]
// CHECK:STDOUT: %self.patt: %pattern_type.8c1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.570]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc8_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.8c1 = ref_param_pattern [concrete = constants.%self.param_patt.327]
// CHECK:STDOUT: %self.patt: %pattern_type.8c1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.570]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc7 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.035 = ref_param_pattern [concrete = constants.%self.param_patt.279]
// CHECK:STDOUT: %self.patt: %pattern_type.035 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.06d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc7 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.035 = ref_param_pattern [concrete = constants.%self.param_patt.279]
// CHECK:STDOUT: %self.patt: %pattern_type.035 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.06d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %a.var: ref %array_type = var_storage %a.var_patt
@@ -326,31 +515,60 @@ var a: array(1, 1);
// CHECK:STDOUT: %b.patt: %pattern_type.8c1 = ref_binding_pattern b [concrete = constants.%b.patt]
// CHECK:STDOUT: %b.var_patt: %pattern_type.8c1 = var_pattern %b.patt [concrete = constants.%b.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc8: <bound method> = bound_method %b.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc8: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc8(%b.var)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc7: <bound method> = bound_method %a.var, constants.%Destroy.WithSelf.Op.403171.3
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc7: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc7(%a.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc8: <bound method> = bound_method %b.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc8: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc8(%b.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc7: <bound method> = bound_method %a.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc7: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc7(%a.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc8_3.1(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_3.1(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_3.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc8_3.1(%self.param: ref %empty_tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc8_3.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc7(%self.param: ref %array_type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_3.2(%self.param: ref %tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc8_3.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc7(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc7(%self.param: ref %array_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc7(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- assign_return_value.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type) [concrete]
// CHECK:STDOUT: %pattern_type.559: type = pattern_type %tuple.type [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
@@ -360,10 +578,74 @@ var a: array(1, 1);
// CHECK:STDOUT: %t.var_patt: %pattern_type.fe8 = var_pattern %t.patt [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %array: %array_type = tuple_value (%empty_tuple) [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %self.param_patt.65a: %pattern_type.cb1 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.df1: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt.65a [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc8_34.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc8_34.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.383: %pattern_type.559 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.363: %pattern_type.559 = wrapper_binding_pattern self, %self.param_patt.383 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc8_34.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc8_34.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc8_34.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.f73: %pattern_type.fe8 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.741: %pattern_type.fe8 = wrapper_binding_pattern self, %self.param_patt.f73 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc8_3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc8_3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc8_3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc8_34.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc8_34.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc8_34.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.559 = ref_param_pattern [concrete = constants.%self.param_patt.383]
// CHECK:STDOUT: %self.patt: %pattern_type.559 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.363]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc8_34.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.559 = ref_param_pattern [concrete = constants.%self.param_patt.383]
// CHECK:STDOUT: %self.patt: %pattern_type.559 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.363]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc8_3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.fe8 = ref_param_pattern [concrete = constants.%self.param_patt.f73]
// CHECK:STDOUT: %self.patt: %pattern_type.fe8 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.741]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc8_3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.fe8 = ref_param_pattern [concrete = constants.%self.param_patt.f73]
// CHECK:STDOUT: %self.patt: %pattern_type.fe8 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.741]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Run() {
@@ -393,28 +675,56 @@ var a: array(1, 1);
// CHECK:STDOUT: %t.patt: %pattern_type.fe8 = ref_binding_pattern t [concrete = constants.%t.patt]
// CHECK:STDOUT: %t.var_patt: %pattern_type.fe8 = var_pattern %t.patt [concrete = constants.%t.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc8_34: <bound method> = bound_method %.loc8_34.2, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc8_34: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc8_34(%.loc8_34.2)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc8_3: <bound method> = bound_method %t.var, constants.%Destroy.WithSelf.Op.403171.3
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc8_3: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc8_3(%t.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc8_34: <bound method> = bound_method %.loc8_34.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc8_34: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc8_34(%.loc8_34.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc8_3: <bound method> = bound_method %t.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc8_3: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc8_3(%t.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc8_34.1(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_34.1(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_34.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc8_34.1(%self.param: ref %empty_tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc8_34.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_3(%self.param: ref %array_type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_34.2(%self.param: ref %tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc8_34.2(%self.param: ref %tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc8_3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc8_3(%self.param: ref %array_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc8_3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- nine_elements.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type, %empty_tuple.type) [concrete]
+2
View File
@@ -68,6 +68,7 @@ var b: array(1, 39999999999999999993);
// CHECK:STDOUT: --- addition.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
@@ -112,6 +113,7 @@ var b: array(1, 39999999999999999993);
// CHECK:STDOUT: --- unsigned.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete]
+99 -4
View File
@@ -53,15 +53,18 @@ fn F() -> i32 {
// CHECK:STDOUT: --- user.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete]
// CHECK:STDOUT: %array_type: type = array_type %int_42, %i32 [concrete]
// CHECK:STDOUT: %pattern_type.c07: type = pattern_type %array_type [concrete]
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
@@ -72,8 +75,27 @@ fn F() -> i32 {
// CHECK:STDOUT: %Copy.WithSelf.Op.type.381: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
// CHECK:STDOUT: %.737: type = fn_type_with_self_type %Copy.WithSelf.Op.type.381, %Copy.facet [concrete]
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.4f6, @Int.as.Copy.impl.Op(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.956: type = pattern_type %i32.builtin [concrete]
// CHECK:STDOUT: %self.param_patt.331: %pattern_type.956 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.319: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt.331 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc6_12.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc6_12.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.705: %pattern_type.6b6 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.70d: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt.705 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc6_12.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc6_12.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.087: %pattern_type.c07 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.b22: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt.087 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc6_12.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc6_12.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc6_12.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -82,6 +104,51 @@ fn F() -> i32 {
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc6_12.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc6_12.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc6_12.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc6_12.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc6_12.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c07 = ref_param_pattern [concrete = constants.%self.param_patt.087]
// CHECK:STDOUT: %self.patt: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.b22]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc6_12.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.c07 = ref_param_pattern [concrete = constants.%self.param_patt.087]
// CHECK:STDOUT: %self.patt: %pattern_type.c07 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.b22]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G(%n.param: %i32) -> out %return.param: %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, imports.%Main.F [concrete = constants.%F]
@@ -96,26 +163,54 @@ fn F() -> i32 {
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
// CHECK:STDOUT: %bound_method.loc6_15.2: <bound method> = bound_method %.loc6_15.2, %specific_fn
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc6_15.2(%.loc6_15.2)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %.loc6_12.2, constants.%Destroy.WithSelf.Op.403171.3
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%.loc6_12.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %.loc6_12.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%.loc6_12.2)
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc6_12.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc6_12.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc6_12.2(%self.param: ref %i32) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc6_12.1(%self.param: ref %i32.builtin) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc6_12.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc6_12.3(%self.param: ref %array_type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc6_12.2(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc6_12.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc6_12.3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc6_12.3(%self.param: ref %array_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc6_12.3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_symbolic_decl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
+99 -4
View File
@@ -49,12 +49,15 @@ fn F(a: array({}, 3)) -> {} {
// CHECK:STDOUT: --- function_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete]
// CHECK:STDOUT: %array_type: type = array_type %int_3.1ba, %i32 [concrete]
// CHECK:STDOUT: %pattern_type.771: type = pattern_type %array_type [concrete]
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete]
@@ -95,9 +98,28 @@ fn F(a: array({}, 3)) -> {} {
// CHECK:STDOUT: %int_3.410: %i32 = int_value 3 [concrete]
// CHECK:STDOUT: %array: %array_type = tuple_value (%int_1.0c6, %int_2.295, %int_3.410) [concrete]
// CHECK:STDOUT: %.981: ref %array_type = temporary invalid, %array [concrete]
// CHECK:STDOUT: %pattern_type.956: type = pattern_type %i32.builtin [concrete]
// CHECK:STDOUT: %self.param_patt.331: %pattern_type.956 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.319: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt.331 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_20.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc10_20.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.705: %pattern_type.6b6 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.70d: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt.705 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_20.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc10_20.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.c42: %pattern_type.771 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.3bc: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt.c42 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc10_20.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc10_20.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %.981, %Destroy.WithSelf.Op.403171.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc10_20.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %.981, %Destroy.WithSelf.SelfDestruct.db3fdb.3 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -107,6 +129,51 @@ fn F(a: array({}, 3)) -> {} {
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1aa = impl_witness_table (%Core.import_ref.edf), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_20.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc10_20.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_20.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc10_20.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc10_20.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.771 = ref_param_pattern [concrete = constants.%self.param_patt.c42]
// CHECK:STDOUT: %self.patt: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.3bc]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc10_20.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.771 = ref_param_pattern [concrete = constants.%self.param_patt.c42]
// CHECK:STDOUT: %self.patt: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.3bc]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%arr.param: %array_type, %i.param: %i32) -> out %return.param: %i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %arr.ref: %array_type = name_ref arr, %arr
@@ -170,25 +237,53 @@ fn F(a: array({}, 3)) -> {} {
// CHECK:STDOUT: %.loc10_23.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_23 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %.loc10_23.2: %i32 = converted %int_1.loc10_23, %.loc10_23.1 [concrete = constants.%int_1.0c6]
// CHECK:STDOUT: %F.call: init %i32 = call %F.ref(%.loc10_20.15, %.loc10_23.2)
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.981)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call constants.%Destroy.WithSelf.SelfDestruct.bound(constants.%.981)
// CHECK:STDOUT: return %F.call
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_20.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_20.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_20.2(%self.param: ref %i32) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_20.1(%self.param: ref %i32.builtin) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_20.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_20.3(%self.param: ref %array_type) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_20.2(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_20.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc10_20.3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_20.3(%self.param: ref %array_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc10_20.3(%self.param: ref %array_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- index_non_literal.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete]
+185 -60
View File
@@ -59,25 +59,26 @@ fn H() { G(3); }
// CHECK:STDOUT: --- generic_empty.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.9a5: type = pattern_type type [concrete]
// CHECK:STDOUT: %T.patt: %pattern_type.9a5 = symbolic_binding_pattern T, 0 [symbolic]
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
// CHECK:STDOUT: %array_type.1b3: type = array_type %int_0, %T [symbolic]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.1b3 [symbolic]
// CHECK:STDOUT: %require_complete.cc5: <witness> = require_complete_type %array_type.1b3 [symbolic]
// CHECK:STDOUT: %pattern_type.bd6: type = pattern_type %array_type.1b3 [symbolic]
// CHECK:STDOUT: %arr.patt.770: %pattern_type.bd6 = ref_binding_pattern arr [symbolic]
// CHECK:STDOUT: %arr.var_patt.5fc: %pattern_type.bd6 = var_pattern %arr.patt.770 [symbolic]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %array.ca4: %array_type.1b3 = tuple_value () [symbolic]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.1b3, @Destroy [symbolic]
// CHECK:STDOUT: %Destroy.facet.a52: %Destroy.type = facet_value %array_type.1b3, (%Destroy.lookup_impl_witness) [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.a67: type = fn_type @Destroy.WithSelf.Op.1, @Destroy.WithSelf(%Destroy.facet.a52) [symbolic]
// CHECK:STDOUT: %.1e5: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.a67, %Destroy.facet.a52 [symbolic]
// CHECK:STDOUT: %impl.elem0: %.1e5 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic]
// CHECK:STDOUT: %specific_impl_fn: <specific function> = specific_impl_function %impl.elem0, @Destroy.WithSelf.Op.1(%Destroy.facet.a52) [symbolic]
// CHECK:STDOUT: %Destroy.lookup_impl_witness.ac5: <witness> = lookup_impl_witness %array_type.1b3, @Destroy [symbolic]
// CHECK:STDOUT: %Destroy.facet.a52: %Destroy.type = facet_value %array_type.1b3, (%Destroy.lookup_impl_witness.ac5) [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.e30: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.a52) [symbolic]
// CHECK:STDOUT: %.c54: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type.e30, %Destroy.facet.a52 [symbolic]
// CHECK:STDOUT: %impl.elem2: %.c54 = impl_witness_access %Destroy.lookup_impl_witness.ac5, element2 [symbolic]
// CHECK:STDOUT: %specific_impl_fn.0cb: <specific function> = specific_impl_function %impl.elem2, @Destroy.WithSelf.SelfDestruct.1(%Destroy.facet.a52) [symbolic]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %array_type.988: type = array_type %int_0, %C [concrete]
// CHECK:STDOUT: %complete_type.e80: <witness> = complete_type_witness %array_type.988 [concrete]
@@ -85,12 +86,35 @@ fn H() { G(3); }
// CHECK:STDOUT: %arr.patt.c91: %pattern_type.6be = ref_binding_pattern arr [concrete]
// CHECK:STDOUT: %arr.var_patt.9dd: %pattern_type.6be = var_pattern %arr.patt.c91 [concrete]
// CHECK:STDOUT: %array.497: %array_type.988 = tuple_value () [concrete]
// CHECK:STDOUT: %self.param_patt.5c1: %pattern_type.6be = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.1a6: %pattern_type.6be = wrapper_binding_pattern self, %self.param_patt.5c1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.6c4: <witness> = custom_witness (%Destroy.WithSelf.Op.403), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.a8f: %Destroy.type = facet_value %array_type.988, (%custom_witness.6c4) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.3eb: type = fn_type @Destroy.WithSelf.Op.1, @Destroy.WithSelf(%Destroy.facet.a8f) [concrete]
// CHECK:STDOUT: %.2c2: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.3eb, %Destroy.facet.a8f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.f8f: <witness> = custom_witness (%Destroy.WithSelf.Op.403, %Destroy.WithSelf.SubobjectDestroy.d01, %Destroy.WithSelf.SelfDestruct.db3), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.23c: %Destroy.type = facet_value %array_type.988, (%custom_witness.f8f) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.180: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.23c) [concrete]
// CHECK:STDOUT: %.a26: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type.180, %Destroy.facet.23c [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc7 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6be = ref_param_pattern [concrete = constants.%self.param_patt.5c1]
// CHECK:STDOUT: %self.patt: %pattern_type.6be = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.1a6]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type.988 = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type.988 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc7 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6be = ref_param_pattern [concrete = constants.%self.param_patt.5c1]
// CHECK:STDOUT: %self.patt: %pattern_type.6be = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.1a6]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type.988 = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type.988 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @G(%T.loc4_15.2: type) {
@@ -98,17 +122,17 @@ fn H() { G(3); }
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %array_type.loc7_29.2: type = array_type constants.%int_0, %T.loc4_15.1 [symbolic = %array_type.loc7_29.2 (constants.%array_type.1b3)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.loc7_29.2 [symbolic = %require_complete (constants.%require_complete)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %array_type.loc7_29.2 [symbolic = %require_complete (constants.%require_complete.cc5)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc7_29.2 [symbolic = %pattern_type (constants.%pattern_type.bd6)]
// CHECK:STDOUT: %arr.patt.loc7_17.2: @G.%pattern_type (%pattern_type.bd6) = ref_binding_pattern arr [symbolic = %arr.patt.loc7_17.2 (constants.%arr.patt.770)]
// CHECK:STDOUT: %arr.var_patt.loc7_3.2: @G.%pattern_type (%pattern_type.bd6) = var_pattern %arr.patt.loc7_17.2 [symbolic = %arr.var_patt.loc7_3.2 (constants.%arr.var_patt.5fc)]
// CHECK:STDOUT: %array: @G.%array_type.loc7_29.2 (%array_type.1b3) = tuple_value () [symbolic = %array (constants.%array.ca4)]
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc7_29.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)]
// CHECK:STDOUT: %Destroy.lookup_impl_witness: <witness> = lookup_impl_witness %array_type.loc7_29.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness.ac5)]
// CHECK:STDOUT: %Destroy.facet.loc7_3.3: %Destroy.type = facet_value %array_type.loc7_29.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type: type = fn_type @Destroy.WithSelf.Op.1, @Destroy.WithSelf(%Destroy.facet.loc7_3.3) [symbolic = %Destroy.WithSelf.Op.type (constants.%Destroy.WithSelf.Op.type.a67)]
// CHECK:STDOUT: %.loc7_3.4: type = fn_type_with_self_type %Destroy.WithSelf.Op.type, %Destroy.facet.loc7_3.3 [symbolic = %.loc7_3.4 (constants.%.1e5)]
// CHECK:STDOUT: %impl.elem0.loc7_3.2: @G.%.loc7_3.4 (%.1e5) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2: <specific function> = specific_impl_function %impl.elem0.loc7_3.2, @Destroy.WithSelf.Op.1(%Destroy.facet.loc7_3.3) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.loc7_3.3) [symbolic = %Destroy.WithSelf.SelfDestruct.type (constants.%Destroy.WithSelf.SelfDestruct.type.e30)]
// CHECK:STDOUT: %.loc7_3.4: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type, %Destroy.facet.loc7_3.3 [symbolic = %.loc7_3.4 (constants.%.c54)]
// CHECK:STDOUT: %impl.elem2.loc7_3.2: @G.%.loc7_3.4 (%.c54) = impl_witness_access %Destroy.lookup_impl_witness, element2 [symbolic = %impl.elem2.loc7_3.2 (constants.%impl.elem2)]
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2: <specific function> = specific_impl_function %impl.elem2.loc7_3.2, @Destroy.WithSelf.SelfDestruct.1(%Destroy.facet.loc7_3.3) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn.0cb)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn() {
// CHECK:STDOUT: !entry:
@@ -127,21 +151,30 @@ fn H() { G(3); }
// CHECK:STDOUT: %arr.patt.loc7_17.1: @G.%pattern_type (%pattern_type.bd6) = ref_binding_pattern arr [symbolic = %arr.patt.loc7_17.2 (constants.%arr.patt.770)]
// CHECK:STDOUT: %arr.var_patt.loc7_3.1: @G.%pattern_type (%pattern_type.bd6) = var_pattern %arr.patt.loc7_17.1 [symbolic = %arr.var_patt.loc7_3.2 (constants.%arr.var_patt.5fc)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %impl.elem0.loc7_3.1: @G.%.loc7_3.4 (%.1e5) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_3.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %arr.var, %impl.elem0.loc7_3.1
// CHECK:STDOUT: %Destroy.facet.loc7_3.1: %Destroy.type = facet_value constants.%array_type.1b3, (constants.%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %impl.elem2.loc7_3.1: @G.%.loc7_3.4 (%.c54) = impl_witness_access constants.%Destroy.lookup_impl_witness.ac5, element2 [symbolic = %impl.elem2.loc7_3.2 (constants.%impl.elem2)]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %arr.var, %impl.elem2.loc7_3.1
// CHECK:STDOUT: %Destroy.facet.loc7_3.1: %Destroy.type = facet_value constants.%array_type.1b3, (constants.%Destroy.lookup_impl_witness.ac5) [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %.loc7_3.2: %Destroy.type = converted constants.%array_type.1b3, %Destroy.facet.loc7_3.1 [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %Destroy.facet.loc7_3.2: %Destroy.type = facet_value constants.%array_type.1b3, (constants.%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %Destroy.facet.loc7_3.2: %Destroy.type = facet_value constants.%array_type.1b3, (constants.%Destroy.lookup_impl_witness.ac5) [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %.loc7_3.3: %Destroy.type = converted constants.%array_type.1b3, %Destroy.facet.loc7_3.2 [symbolic = %Destroy.facet.loc7_3.3 (constants.%Destroy.facet.a52)]
// CHECK:STDOUT: %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem0.loc7_3.1, @Destroy.WithSelf.Op.1(constants.%Destroy.facet.a52) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn)]
// CHECK:STDOUT: %specific_impl_fn.loc7_3.1: <specific function> = specific_impl_function %impl.elem2.loc7_3.1, @Destroy.WithSelf.SelfDestruct.1(constants.%Destroy.facet.a52) [symbolic = %specific_impl_fn.loc7_3.2 (constants.%specific_impl_fn.0cb)]
// CHECK:STDOUT: %bound_method.loc7_3.2: <bound method> = bound_method %arr.var, %specific_impl_fn.loc7_3.1
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %bound_method.loc7_3.2(%arr.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %bound_method.loc7_3.2(%arr.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc7(%self.param: ref %array_type.988) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc7(%self.param: ref %array_type.988) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc7(%self.param: ref %array_type.988) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @G(constants.%T) {
// CHECK:STDOUT: %T.patt.loc4_15.2 => constants.%T.patt
// CHECK:STDOUT: %T.loc4_15.1 => constants.%T
@@ -158,17 +191,18 @@ fn H() { G(3); }
// CHECK:STDOUT: %arr.patt.loc7_17.2 => constants.%arr.patt.c91
// CHECK:STDOUT: %arr.var_patt.loc7_3.2 => constants.%arr.var_patt.9dd
// CHECK:STDOUT: %array => constants.%array.497
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%custom_witness.6c4
// CHECK:STDOUT: %Destroy.facet.loc7_3.3 => constants.%Destroy.facet.a8f
// CHECK:STDOUT: %Destroy.WithSelf.Op.type => constants.%Destroy.WithSelf.Op.type.3eb
// CHECK:STDOUT: %.loc7_3.4 => constants.%.2c2
// CHECK:STDOUT: %impl.elem0.loc7_3.2 => constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2 => constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%custom_witness.f8f
// CHECK:STDOUT: %Destroy.facet.loc7_3.3 => constants.%Destroy.facet.23c
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type => constants.%Destroy.WithSelf.SelfDestruct.type.180
// CHECK:STDOUT: %.loc7_3.4 => constants.%.a26
// CHECK:STDOUT: %impl.elem2.loc7_3.2 => constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %specific_impl_fn.loc7_3.2 => constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_init_template_dependent_bound.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
@@ -189,14 +223,14 @@ fn H() { G(3); }
// CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%int_1, %int_2, %int_3.1ba) [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %Self.0e7: %Destroy.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d3e: type = fn_type @Destroy.WithSelf.Op.1, @Destroy.WithSelf(%Self.0e7) [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.Op.42b: %Destroy.WithSelf.Op.type.d3e = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.4e5: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Self.0e7) [symbolic]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.4a0: %Destroy.WithSelf.SelfDestruct.type.4e5 = struct_value () [symbolic]
// CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete]
// CHECK:STDOUT: %assoc0.ae8: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.918 [concrete]
// CHECK:STDOUT: %.0be: type = type_of_inst @G.%.loc11_3.5 [template]
// CHECK:STDOUT: %.db2: %.0be = splice_inst @G.%.loc11_3.5 [template]
// CHECK:STDOUT: %.76e: type = type_of_inst @G.%.loc11_3.8 [template]
// CHECK:STDOUT: %.772: %.76e = splice_inst @G.%.loc11_3.8 [template]
// CHECK:STDOUT: %assoc2: %Destroy.assoc_type = assoc_entity element2, imports.%Core.import_ref.71d [concrete]
// CHECK:STDOUT: %.19c: type = type_of_inst @G.%.loc11_3.5 [template]
// CHECK:STDOUT: %.11f: %.19c = splice_inst @G.%.loc11_3.5 [template]
// CHECK:STDOUT: %.e86: type = type_of_inst @G.%.loc11_3.8 [template]
// CHECK:STDOUT: %.9d4: %.e86 = splice_inst @G.%.loc11_3.8 [template]
// CHECK:STDOUT: %From: Core.IntLiteral = symbolic_binding From, 0 [symbolic]
// CHECK:STDOUT: %ImplicitAs.type.7cb: type = facet_type <@ImplicitAs, @ImplicitAs(Core.IntLiteral)> [concrete]
// CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.type.48d: type = fn_type @Int.as.ImplicitAs.impl.Convert, @Int.as.ImplicitAs.impl(%From) [symbolic]
@@ -226,30 +260,94 @@ fn H() { G(3); }
// CHECK:STDOUT: %pattern_type.771: type = pattern_type %array_type.dc7 [concrete]
// CHECK:STDOUT: %arr.patt.316: %pattern_type.771 = ref_binding_pattern arr [concrete]
// CHECK:STDOUT: %arr.var_patt.c63: %pattern_type.771 = var_pattern %arr.patt.316 [concrete]
// CHECK:STDOUT: %pattern_type.956: type = pattern_type %i32.builtin [concrete]
// CHECK:STDOUT: %self.param_patt.331: %pattern_type.956 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.319: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt.331 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc11_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc11_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.705: %pattern_type.6b6 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.70d: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt.705 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc11_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc11_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.c42: %pattern_type.771 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.3bc: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt.c42 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc11_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc11_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.6c4ec3.3: <witness> = custom_witness (%Destroy.WithSelf.Op.403171.3), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.87b: %Destroy.type = facet_value %array_type.dc7, (%custom_witness.6c4ec3.3) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.d31: type = fn_type @Destroy.WithSelf.Op.1, @Destroy.WithSelf(%Destroy.facet.87b) [concrete]
// CHECK:STDOUT: %.6e0: type = fn_type_with_self_type %Destroy.WithSelf.Op.type.d31, %Destroy.facet.87b [concrete]
// CHECK:STDOUT: %inst.splice_block.c0d: <instruction> = inst_value [concrete] {
// CHECK:STDOUT: %.729: <bound method> = splice_block %bound_method.7de {
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc11_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: %custom_witness.f8f19d.3: <witness> = custom_witness (%Destroy.WithSelf.Op.403171.3, %Destroy.WithSelf.SubobjectDestroy.d01daf.3, %Destroy.WithSelf.SelfDestruct.db3fdb.3), @Destroy [concrete]
// CHECK:STDOUT: %Destroy.facet.149: %Destroy.type = facet_value %array_type.dc7, (%custom_witness.f8f19d.3) [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.95e: type = fn_type @Destroy.WithSelf.SelfDestruct.1, @Destroy.WithSelf(%Destroy.facet.149) [concrete]
// CHECK:STDOUT: %.7f7: type = fn_type_with_self_type %Destroy.WithSelf.SelfDestruct.type.95e, %Destroy.facet.149 [concrete]
// CHECK:STDOUT: %inst.splice_block.11c: <instruction> = inst_value [concrete] {
// CHECK:STDOUT: %.214: <bound method> = splice_block %bound_method.e27 {
// CHECK:STDOUT: %.875: ref %array_type.dc7 = specific_inst @G.%arr.var, @G(%int_3.410)
// CHECK:STDOUT: %impl.elem0.6b3: %.6e0 = impl_witness_access %custom_witness.6c4ec3.3, element0 [concrete = %Destroy.WithSelf.Op.403171.3]
// CHECK:STDOUT: %bound_method.7de: <bound method> = bound_method %.875, %impl.elem0.6b3
// CHECK:STDOUT: %impl.elem2: %.7f7 = impl_witness_access %custom_witness.f8f19d.3, element2 [concrete = %Destroy.WithSelf.SelfDestruct.db3fdb.3]
// CHECK:STDOUT: %bound_method.e27: <bound method> = bound_method %.875, %impl.elem2
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %inst.call: <instruction> = inst_value [concrete] {
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %.729(%.875)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %.214(%.875)
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Core.import_ref.918: @Destroy.WithSelf.%Destroy.WithSelf.Op.type (%Destroy.WithSelf.Op.type.d3e) = import_ref Core//prelude/parts/destroy, loc{{\d+_\d+}}, loaded [symbolic = @Destroy.WithSelf.%Destroy.WithSelf.Op (constants.%Destroy.WithSelf.Op.42b)]
// CHECK:STDOUT: %Core.import_ref.71d: @Destroy.WithSelf.%Destroy.WithSelf.SelfDestruct.type (%Destroy.WithSelf.SelfDestruct.type.4e5) = import_ref Core//prelude/parts/destroy, loc{{\d+_\d+}}, loaded [symbolic = @Destroy.WithSelf.%Destroy.WithSelf.SelfDestruct (constants.%Destroy.WithSelf.SelfDestruct.4a0)]
// CHECK:STDOUT: %Core.import_ref.32e: @Int.as.ImplicitAs.impl.%Int.as.ImplicitAs.impl.Convert.type (%Int.as.ImplicitAs.impl.Convert.type.48d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.ImplicitAs.impl.%Int.as.ImplicitAs.impl.Convert (constants.%Int.as.ImplicitAs.impl.Convert.0f9)]
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.204 = impl_witness_table (%Core.import_ref.32e), @Int.as.ImplicitAs.impl [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc11_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc11_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.956 = ref_param_pattern [concrete = constants.%self.param_patt.331]
// CHECK:STDOUT: %self.patt: %pattern_type.956 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.319]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32.builtin = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32.builtin = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc11_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc11_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6b6 = ref_param_pattern [concrete = constants.%self.param_patt.705]
// CHECK:STDOUT: %self.patt: %pattern_type.6b6 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.70d]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc11_3.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.771 = ref_param_pattern [concrete = constants.%self.param_patt.c42]
// CHECK:STDOUT: %self.patt: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.3bc]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type.dc7 = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type.dc7 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc11_3.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.771 = ref_param_pattern [concrete = constants.%self.param_patt.c42]
// CHECK:STDOUT: %self.patt: %pattern_type.771 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.3bc]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %array_type.dc7 = ref_param call_param0
// CHECK:STDOUT: %self: ref %array_type.dc7 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @G(%N.loc5_16.2: %i32) {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT:
@@ -261,12 +359,12 @@ fn H() { G(3); }
// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc11_31.2 [template = %pattern_type (constants.%pattern_type.ed3)]
// CHECK:STDOUT: %arr.patt.loc11_17.2: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc11_17.2 (constants.%arr.patt.515)]
// CHECK:STDOUT: %arr.var_patt.loc11_3.2: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc11_17.2 [template = %arr.var_patt.loc11_3.2 (constants.%arr.var_patt.821)]
// CHECK:STDOUT: %.loc11_3.5: <instruction> = compound_member_access_action %arr.var, constants.%assoc0.ae8 [template]
// CHECK:STDOUT: %.loc11_3.6: type = type_of_inst %.loc11_3.5 [template = %.loc11_3.6 (constants.%.0be)]
// CHECK:STDOUT: %.loc11_3.7: @G.%.loc11_3.6 (%.0be) = splice_inst %.loc11_3.5 [template = %.loc11_3.7 (constants.%.db2)]
// CHECK:STDOUT: %.loc11_3.5: <instruction> = compound_member_access_action %arr.var, constants.%assoc2 [template]
// CHECK:STDOUT: %.loc11_3.6: type = type_of_inst %.loc11_3.5 [template = %.loc11_3.6 (constants.%.19c)]
// CHECK:STDOUT: %.loc11_3.7: @G.%.loc11_3.6 (%.19c) = splice_inst %.loc11_3.5 [template = %.loc11_3.7 (constants.%.11f)]
// CHECK:STDOUT: %.loc11_3.8: <instruction> = call_action (%.loc11_3.2), true [template]
// CHECK:STDOUT: %.loc11_3.9: type = type_of_inst %.loc11_3.8 [template = %.loc11_3.9 (constants.%.76e)]
// CHECK:STDOUT: %.loc11_3.10: @G.%.loc11_3.9 (%.76e) = splice_inst %.loc11_3.8 [template = %.loc11_3.10 (constants.%.772)]
// CHECK:STDOUT: %.loc11_3.9: type = type_of_inst %.loc11_3.8 [template = %.loc11_3.9 (constants.%.e86)]
// CHECK:STDOUT: %.loc11_3.10: @G.%.loc11_3.9 (%.e86) = splice_inst %.loc11_3.8 [template = %.loc11_3.10 (constants.%.9d4)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn() {
// CHECK:STDOUT: !entry:
@@ -287,23 +385,50 @@ fn H() { G(3); }
// CHECK:STDOUT: %arr.patt.loc11_17.1: @G.%pattern_type (%pattern_type.ed3) = ref_binding_pattern arr [template = %arr.patt.loc11_17.2 (constants.%arr.patt.515)]
// CHECK:STDOUT: %arr.var_patt.loc11_3.1: @G.%pattern_type (%pattern_type.ed3) = var_pattern %arr.patt.loc11_17.1 [template = %arr.var_patt.loc11_3.2 (constants.%arr.var_patt.821)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc11_3.1: type = type_of_inst %.loc11_3.5 [template = %.loc11_3.6 (constants.%.0be)]
// CHECK:STDOUT: %.loc11_3.2: @G.%.loc11_3.6 (%.0be) = splice_inst %.loc11_3.5 [template = %.loc11_3.7 (constants.%.db2)]
// CHECK:STDOUT: %.loc11_3.3: type = type_of_inst %.loc11_3.8 [template = %.loc11_3.9 (constants.%.76e)]
// CHECK:STDOUT: %.loc11_3.4: @G.%.loc11_3.9 (%.76e) = splice_inst %.loc11_3.8 [template = %.loc11_3.10 (constants.%.772)]
// CHECK:STDOUT: %.loc11_3.1: type = type_of_inst %.loc11_3.5 [template = %.loc11_3.6 (constants.%.19c)]
// CHECK:STDOUT: %.loc11_3.2: @G.%.loc11_3.6 (%.19c) = splice_inst %.loc11_3.5 [template = %.loc11_3.7 (constants.%.11f)]
// CHECK:STDOUT: %.loc11_3.3: type = type_of_inst %.loc11_3.8 [template = %.loc11_3.9 (constants.%.e86)]
// CHECK:STDOUT: %.loc11_3.4: @G.%.loc11_3.9 (%.e86) = splice_inst %.loc11_3.8 [template = %.loc11_3.10 (constants.%.9d4)]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc11_3.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc11_3.1(%self.param: ref %i32.builtin) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc11_3.2(%self.param: ref %i32) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc11_3.1(%self.param: ref %i32.builtin) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc11_3.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc11_3.3(%self.param: ref %array_type.dc7) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc11_3.2(%self.param: ref %i32) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc11_3.2(%self.param: ref %i32) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc11_3.3(%self.param: ref %array_type.dc7) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc11_3.3(%self.param: ref %array_type.dc7) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc11_3.3(%self.param: ref %array_type.dc7) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -324,7 +449,7 @@ fn H() { G(3); }
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.771
// CHECK:STDOUT: %arr.patt.loc11_17.2 => constants.%arr.patt.316
// CHECK:STDOUT: %arr.var_patt.loc11_3.2 => constants.%arr.var_patt.c63
// CHECK:STDOUT: %.loc11_3.5 => constants.%inst.splice_block.c0d
// CHECK:STDOUT: %.loc11_3.5 => constants.%inst.splice_block.11c
// CHECK:STDOUT: %.loc11_3.6 => <bound method>
// CHECK:STDOUT: %.loc11_3.7 => invalid
// CHECK:STDOUT: %.loc11_3.8 => constants.%inst.call
+8 -3
View File
@@ -173,6 +173,7 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: --- adapt_class.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %A.Make.type: type = fn_type @A.Make [concrete]
// CHECK:STDOUT: %A.Make: %A.Make.type = struct_value () [concrete]
@@ -237,6 +238,7 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: --- adapt_i32.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
@@ -304,6 +306,7 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: --- multi_level_adapt.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: %D: type = class_type @D [concrete]
@@ -333,6 +336,7 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: --- init_class_value.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
@@ -414,12 +418,13 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: --- init_tuple_value.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Noncopyable: type = class_type @Noncopyable [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
// CHECK:STDOUT: %tuple.type.c8c: type = tuple_type (%empty_struct_type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.c8c = tuple_value (%empty_struct, %Noncopyable) [concrete]
// CHECK:STDOUT: %tuple.type.12a: type = tuple_type (%empty_struct_type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.12a = tuple_value (%empty_struct, %Noncopyable) [concrete]
// CHECK:STDOUT: %tuple.type.c68: type = tuple_type (%empty_struct_type, %Noncopyable) [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %A [concrete]
// CHECK:STDOUT: %a_value.patt: %pattern_type = value_binding_pattern a_value [concrete]
@@ -430,7 +435,7 @@ var b: B = {.x = ()} as B;
// CHECK:STDOUT: %a.ref: %A = name_ref a, %a
// CHECK:STDOUT: %.loc14_35: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
// CHECK:STDOUT: %Noncopyable.ref: type = name_ref Noncopyable, file.%Noncopyable.decl [concrete = constants.%Noncopyable]
// CHECK:STDOUT: %.loc14_49.1: %tuple.type.c8c = tuple_literal (%.loc14_35, %Noncopyable.ref) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc14_49.1: %tuple.type.12a = tuple_literal (%.loc14_35, %Noncopyable.ref) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc14_49.2: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
// CHECK:STDOUT: %.loc14_49.3: type = converted %.loc14_49.1, constants.%tuple.type.c68 [concrete = constants.%tuple.type.c68]
// CHECK:STDOUT: %.loc14_30.1: %tuple.type.c68 = as_compatible %a.ref
+176 -17
View File
@@ -131,6 +131,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: --- simple_as.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %empty_tuple.type, .y: %empty_tuple.type} [concrete]
@@ -173,6 +174,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: --- as_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete]
// CHECK:STDOUT: %t.patt: %pattern_type = value_binding_pattern t [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
@@ -204,22 +206,88 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: --- as_tuple.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.6cb: type = pattern_type %X [concrete]
// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete]
// CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.24b = tuple_value (%X, %X) [concrete]
// CHECK:STDOUT: %tuple.type.693: type = tuple_type (type, type) [concrete]
// CHECK:STDOUT: %tuple: %tuple.type.693 = tuple_value (%X, %X) [concrete]
// CHECK:STDOUT: %tuple.type.359: type = tuple_type (%X, %X) [concrete]
// CHECK:STDOUT: %pattern_type.3ee: type = pattern_type %tuple.type.359 [concrete]
// CHECK:STDOUT: %a.patt: %pattern_type.3ee = value_binding_pattern a [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13_40.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc13_40.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13_40.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc13_40.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc13_40.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: %b.patt: %pattern_type.3ee = ref_binding_pattern b [concrete]
// CHECK:STDOUT: %b.var_patt: %pattern_type.3ee = var_pattern %b.patt [concrete]
// CHECK:STDOUT: %self.param_patt.bc5: %pattern_type.3ee = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.15e: %pattern_type.3ee = wrapper_binding_pattern self, %self.param_patt.bc5 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc20 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc20 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc20 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13_40.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc13_40.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13_40.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc13_40.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc20 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.3ee = ref_param_pattern [concrete = constants.%self.param_patt.bc5]
// CHECK:STDOUT: %self.patt: %pattern_type.3ee = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.15e]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type.359 = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type.359 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc20 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.3ee = ref_param_pattern [concrete = constants.%self.param_patt.bc5]
// CHECK:STDOUT: %self.patt: %pattern_type.3ee = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.15e]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %tuple.type.359 = ref_param call_param0
// CHECK:STDOUT: %self: ref %tuple.type.359 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Let() {
@@ -233,7 +301,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %.loc13_41.1: %tuple.type.359 = tuple_literal (%Make.call.loc13_32, %Make.call.loc13_40)
// CHECK:STDOUT: %X.ref.loc13_47: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %X.ref.loc13_50: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %.loc13_51.1: %tuple.type.24b = tuple_literal (%X.ref.loc13_47, %X.ref.loc13_50) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc13_51.1: %tuple.type.693 = tuple_literal (%X.ref.loc13_47, %X.ref.loc13_50) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc13_51.2: type = converted %.loc13_51.1, constants.%tuple.type.359 [concrete = constants.%tuple.type.359]
// CHECK:STDOUT: %.loc13_32.2: ref %X = temporary %.loc13_32.1, %Make.call.loc13_32
// CHECK:STDOUT: %.loc13_32.3: %X = acquire_value %.loc13_32.2
@@ -244,24 +312,42 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %.loc13_22.1: type = splice_block %.loc13_22.3 [concrete = constants.%tuple.type.359] {
// CHECK:STDOUT: %X.ref.loc13_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %X.ref.loc13_21: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %.loc13_22.2: %tuple.type.24b = tuple_literal (%X.ref.loc13_18, %X.ref.loc13_21) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc13_22.2: %tuple.type.693 = tuple_literal (%X.ref.loc13_18, %X.ref.loc13_21) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc13_22.3: type = converted %.loc13_22.2, constants.%tuple.type.359 [concrete = constants.%tuple.type.359]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: %tuple.type.359 = wrapper_binding a, %.loc13_41.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %pattern_type.3ee = value_binding_pattern a [concrete = constants.%a.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc13_40: <bound method> = bound_method %.loc13_40.2, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc13_40: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc13_40(%.loc13_40.2)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc13_32: <bound method> = bound_method %.loc13_32.2, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc13_32: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc13_32(%.loc13_32.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13_40: <bound method> = bound_method %.loc13_40.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13_40: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13_40(%.loc13_40.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13_32: <bound method> = bound_method %.loc13_32.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13_32: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13_32(%.loc13_32.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13_40.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13_40.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13_40.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13_40.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13_40.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13_40.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13_40.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -277,7 +363,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %.loc20_41.1: %tuple.type.359 = tuple_literal (%Make.call.loc20_32, %Make.call.loc20_40)
// CHECK:STDOUT: %X.ref.loc20_47: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %X.ref.loc20_50: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %.loc20_51.1: %tuple.type.24b = tuple_literal (%X.ref.loc20_47, %X.ref.loc20_50) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc20_51.1: %tuple.type.693 = tuple_literal (%X.ref.loc20_47, %X.ref.loc20_50) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc20_51.2: type = converted %.loc20_51.1, constants.%tuple.type.359 [concrete = constants.%tuple.type.359]
// CHECK:STDOUT: %.loc20_41.2: init %tuple.type.359 to %b.var = tuple_init (%Make.call.loc20_32, %Make.call.loc20_40)
// CHECK:STDOUT: %.loc20_3: init %tuple.type.359 = converted %.loc20_41.1, %.loc20_41.2
@@ -285,7 +371,7 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %.loc20_22.1: type = splice_block %.loc20_22.3 [concrete = constants.%tuple.type.359] {
// CHECK:STDOUT: %X.ref.loc20_18: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %X.ref.loc20_21: type = name_ref X, file.%X.decl [concrete = constants.%X]
// CHECK:STDOUT: %.loc20_22.2: %tuple.type.24b = tuple_literal (%X.ref.loc20_18, %X.ref.loc20_21) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc20_22.2: %tuple.type.693 = tuple_literal (%X.ref.loc20_18, %X.ref.loc20_21) [concrete = constants.%tuple]
// CHECK:STDOUT: %.loc20_22.3: type = converted %.loc20_22.2, constants.%tuple.type.359 [concrete = constants.%tuple.type.359]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %tuple.type.359 = wrapper_binding b, %b.var
@@ -293,19 +379,29 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %b.patt: %pattern_type.3ee = ref_binding_pattern b [concrete = constants.%b.patt]
// CHECK:STDOUT: %b.var_patt: %pattern_type.3ee = var_pattern %b.patt [concrete = constants.%b.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %b.var, constants.%Destroy.WithSelf.Op.403171.3
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%b.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %b.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%b.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc20(%self.param: ref %tuple.type.359) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc20(%self.param: ref %tuple.type.359) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc20(%self.param: ref %tuple.type.359) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc20(%self.param: ref %tuple.type.359) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- identity.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.6cb: type = pattern_type %X [concrete]
@@ -318,8 +414,52 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete]
// CHECK:STDOUT: %x.patt: %pattern_type.6cb = ref_binding_pattern x [concrete]
// CHECK:STDOUT: %x.var_patt: %pattern_type.6cb = var_pattern %x.patt [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc24_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc24_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc24_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc24_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc24_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc24_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc24_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc24_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc24_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Value(%n.param: %X) {
@@ -365,21 +505,40 @@ let n: {.x: ()} = {.x = ()} as {.x = ()};
// CHECK:STDOUT: %x.patt: %pattern_type.6cb = ref_binding_pattern x [concrete = constants.%x.patt]
// CHECK:STDOUT: %x.var_patt: %pattern_type.6cb = var_pattern %x.patt [concrete = constants.%x.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %x.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%x.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %x.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%x.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc24_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc24_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc24_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc24_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc24_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc24_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc24_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- overloaded.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
+164 -7
View File
@@ -95,8 +95,10 @@ fn Use() {
// CHECK:STDOUT: --- add_const.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.6cb: type = pattern_type %X [concrete]
// CHECK:STDOUT: %Init.type: type = fn_type @Init [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %Init: %Init.type = struct_value () [concrete]
@@ -112,8 +114,72 @@ fn Use() {
// CHECK:STDOUT: %reference.var: ref %const = var_storage file.%reference.var_patt [concrete]
// CHECK:STDOUT: %addr.daa: %ptr.faf = addr_of %reference.var [concrete]
// CHECK:STDOUT: %b.patt: %pattern_type.7f7 = value_binding_pattern b [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc14_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc14_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc14_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc14_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.b9b: %pattern_type.dfd = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.a99: %pattern_type.dfd = wrapper_binding_pattern self, %self.param_patt.b9b [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc14_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc14_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3: type = fn_type @Destroy.WithSelf.SelfDestruct.loc14_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.3: %Destroy.WithSelf.SelfDestruct.type.fbceb5.3 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc14_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc14_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc14_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc14_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc14_3.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.dfd = ref_param_pattern [concrete = constants.%self.param_patt.b9b]
// CHECK:STDOUT: %self.patt: %pattern_type.dfd = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a99]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %const = ref_param call_param0
// CHECK:STDOUT: %self: ref %const = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc14_3.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.dfd = ref_param_pattern [concrete = constants.%self.param_patt.b9b]
// CHECK:STDOUT: %self.patt: %pattern_type.dfd = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a99]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %const = ref_param call_param0
// CHECK:STDOUT: %self: ref %const = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Use() {
@@ -179,20 +245,47 @@ fn Use() {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.7f7 = value_binding_pattern b [concrete = constants.%b.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.Op.403171.3
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%i.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%i.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc14_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc14_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc14_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.3(%self.param: ref %const) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc14_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc14_3.3(%self.param: ref %const) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.3(%self.param: ref %const) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc14_3.3(%self.param: ref %const) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -204,6 +297,7 @@ fn Use() {
// CHECK:STDOUT: --- remove_const.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %const: type = const_type %X [concrete]
@@ -214,8 +308,52 @@ fn Use() {
// CHECK:STDOUT: %i.patt: %pattern_type.6cb = ref_binding_pattern i [concrete]
// CHECK:STDOUT: %i.var_patt: %pattern_type.6cb = var_pattern %i.patt [concrete]
// CHECK:STDOUT: %v.patt: %pattern_type.6cb = value_binding_pattern v [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc12_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc12_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Use() {
@@ -243,15 +381,33 @@ fn Use() {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %v.patt: %pattern_type.6cb = value_binding_pattern v [concrete = constants.%v.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%i.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%i.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -263,6 +419,7 @@ fn Use() {
// CHECK:STDOUT: --- unsafe_remove_const.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %const: type = const_type %X [concrete]
// CHECK:STDOUT: %ptr.faf: type = ptr_type %const [concrete]
+130 -5
View File
@@ -136,6 +136,7 @@ fn Use() {
// CHECK:STDOUT: --- add_unformed.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %DefaultOrUnformed.type: type = facet_type <@DefaultOrUnformed> [concrete]
// CHECK:STDOUT: %ptr.db8: type = ptr_type %X [concrete]
@@ -212,8 +213,10 @@ fn Use() {
// CHECK:STDOUT: --- fail_todo_add_unformed_nonref.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.6cb: type = pattern_type %X [concrete]
// CHECK:STDOUT: %Init.type: type = fn_type @Init [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %Init: %Init.type = struct_value () [concrete]
@@ -228,8 +231,34 @@ fn Use() {
// CHECK:STDOUT: %As.generic: %As.type.116 = struct_value () [concrete]
// CHECK:STDOUT: %v.patt: %pattern_type.009 = value_binding_pattern v [concrete]
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc19_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc19_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc19_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc19_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.b19: type = pattern_type %.f01 [concrete]
// CHECK:STDOUT: %self.param_patt.64e: %pattern_type.b19 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.00a: %pattern_type.b19 = wrapper_binding_pattern self, %self.param_patt.64e [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc19_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.3: type = fn_type @Destroy.WithSelf.Op.loc19_3.3 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.3: %Destroy.WithSelf.Op.type.ef016f.3 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.bd6: %pattern_type.009 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.eed: %pattern_type.009 = wrapper_binding_pattern self, %self.param_patt.bd6 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc19_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.4: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.4: type = fn_type @Destroy.WithSelf.Op.loc19_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.4: %Destroy.WithSelf.Op.type.ef016f.4 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.4: type = fn_type @Destroy.WithSelf.SelfDestruct.loc19_3.4 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.4: %Destroy.WithSelf.SelfDestruct.type.fbceb5.4 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -245,6 +274,65 @@ fn Use() {
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc19_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc19_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc19_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc19_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.3: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.3 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc19_3.3 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.b19 = ref_param_pattern [concrete = constants.%self.param_patt.64e]
// CHECK:STDOUT: %self.patt: %pattern_type.b19 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.00a]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.f01 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.f01 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.3: %Destroy.WithSelf.Op.type.ef016f.3 = fn_decl @Destroy.WithSelf.Op.loc19_3.3 [concrete = constants.%Destroy.WithSelf.Op.403171.3] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.b19 = ref_param_pattern [concrete = constants.%self.param_patt.64e]
// CHECK:STDOUT: %self.patt: %pattern_type.b19 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.00a]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.f01 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.f01 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.4: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.4 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc19_3.4 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.4] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.009 = ref_param_pattern [concrete = constants.%self.param_patt.bd6]
// CHECK:STDOUT: %self.patt: %pattern_type.009 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.eed]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %MaybeUnformed.198 = ref_param call_param0
// CHECK:STDOUT: %self: ref %MaybeUnformed.198 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.4: %Destroy.WithSelf.Op.type.ef016f.4 = fn_decl @Destroy.WithSelf.Op.loc19_3.4 [concrete = constants.%Destroy.WithSelf.Op.403171.4] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.009 = ref_param_pattern [concrete = constants.%self.param_patt.bd6]
// CHECK:STDOUT: %self.patt: %pattern_type.009 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.eed]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %MaybeUnformed.198 = ref_param call_param0
// CHECK:STDOUT: %self: ref %MaybeUnformed.198 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Use() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %i.var: ref %MaybeUnformed.198 = var_storage %i.var_patt
@@ -284,25 +372,61 @@ fn Use() {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %v.patt: %pattern_type.009 = value_binding_pattern v [concrete = constants.%v.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.Op.403171.4
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%i.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.4
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%i.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc19_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc19_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc19_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.3(%self.param: ref %.f01) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc19_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc19_3.3(%self.param: ref %.f01) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.4(%self.param: ref %MaybeUnformed.198) {
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.3(%self.param: ref %.f01) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc19_3.3(%self.param: ref %.f01) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.3(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.3(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc19_3.4(%self.param: ref %MaybeUnformed.198) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc19_3.4(%self.param: ref %MaybeUnformed.198) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc19_3.4(%self.param: ref %MaybeUnformed.198) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.4(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.4(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -314,6 +438,7 @@ fn Use() {
// CHECK:STDOUT: --- unsafe_remove_unformed.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %MaybeUnformed.198: type = class_type @MaybeUnformed, @MaybeUnformed(%X) [concrete]
// CHECK:STDOUT: %ptr.b8c: type = ptr_type %MaybeUnformed.198 [concrete]
+137 -10
View File
@@ -109,6 +109,7 @@ fn Use() {
// CHECK:STDOUT: --- add_partial.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %Init.type: type = fn_type @Init [concrete]
@@ -126,8 +127,52 @@ fn Use() {
// CHECK:STDOUT: %reference.var: ref %.d74 = var_storage file.%reference.var_patt [concrete]
// CHECK:STDOUT: %addr.3a0: %ptr.44a = addr_of %reference.var [concrete]
// CHECK:STDOUT: %b.patt: %pattern_type.12c = value_binding_pattern b [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc14_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc14_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.9b7: %pattern_type.53b = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.8cb: %pattern_type.53b = wrapper_binding_pattern self, %self.param_patt.9b7 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc14_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc14_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc14_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc14_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc14_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc14_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.53b = ref_param_pattern [concrete = constants.%self.param_patt.9b7]
// CHECK:STDOUT: %self.patt: %pattern_type.53b = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.8cb]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.d74 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.d74 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc14_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.53b = ref_param_pattern [concrete = constants.%self.param_patt.9b7]
// CHECK:STDOUT: %self.patt: %pattern_type.53b = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.8cb]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %.d74 = ref_param call_param0
// CHECK:STDOUT: %self: ref %.d74 = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Use() {
@@ -193,15 +238,33 @@ fn Use() {
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %pattern_type.12c = value_binding_pattern b [concrete = constants.%b.patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%i.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%i.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc14_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.2(%self.param: ref %.d74) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc14_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc14_3.2(%self.param: ref %.d74) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc14_3.2(%self.param: ref %.d74) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc14_3.2(%self.param: ref %.d74) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -213,6 +276,7 @@ fn Use() {
// CHECK:STDOUT: --- remove_partial_in_init.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %.d74: type = partial_type %X [concrete]
@@ -226,8 +290,52 @@ fn Use() {
// CHECK:STDOUT: %j.var_patt: %pattern_type.6cb = var_pattern %j.patt [concrete]
// CHECK:STDOUT: %k.patt: %pattern_type.6cb = ref_binding_pattern k [concrete]
// CHECK:STDOUT: %k.var_patt: %pattern_type.6cb = var_pattern %k.patt [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc12_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc12_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Use() {
@@ -273,25 +381,44 @@ fn Use() {
// CHECK:STDOUT: %k.patt: %pattern_type.6cb = ref_binding_pattern k [concrete = constants.%k.patt]
// CHECK:STDOUT: %k.var_patt: %pattern_type.6cb = var_pattern %k.patt [concrete = constants.%k.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc12: <bound method> = bound_method %k.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc12: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc12(%k.var)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc11: <bound method> = bound_method %j.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc11: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc11(%j.var)
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc10: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc10: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc10(%i.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc12: <bound method> = bound_method %k.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc12: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc12(%k.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc11: <bound method> = bound_method %j.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc11: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc11(%j.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc10: <bound method> = bound_method %i.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc10: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc10(%i.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- unsafe_remove_partial.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %.d74: type = partial_type %X [concrete]
// CHECK:STDOUT: %ptr.44a: type = ptr_type %.d74 [concrete]
+66 -3
View File
@@ -30,6 +30,7 @@ fn Convert(unused t: ()) {
// CHECK:STDOUT: --- var_init.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %X: type = class_type @X [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
@@ -45,8 +46,52 @@ fn Convert(unused t: ()) {
// CHECK:STDOUT: %x.var_patt: %pattern_type.6cb = var_pattern %x.patt [concrete]
// CHECK:STDOUT: %.b8c: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.dd7, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %empty_tuple, %empty_tuple.type.as.ImplicitAs.impl.Convert [concrete]
// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
// CHECK:STDOUT: %self.param_patt.52f: %pattern_type.a96 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.4b1: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt.52f [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc12_3.1 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.925: %pattern_type.6cb = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.617: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt.925 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc12_3.2 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc12_3.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.a96 = ref_param_pattern [concrete = constants.%self.param_patt.52f]
// CHECK:STDOUT: %self.patt: %pattern_type.a96 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.4b1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_struct_type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_struct_type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc12_3.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc12_3.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.6cb = ref_param_pattern [concrete = constants.%self.param_patt.925]
// CHECK:STDOUT: %self.patt: %pattern_type.6cb = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.617]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %X = ref_param call_param0
// CHECK:STDOUT: %self: ref %X = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Convert(%t.param: %empty_tuple.type) {
@@ -67,15 +112,33 @@ fn Convert(unused t: ()) {
// CHECK:STDOUT: %x.patt: %pattern_type.6cb = ref_binding_pattern x [concrete = constants.%x.patt]
// CHECK:STDOUT: %x.var_patt: %pattern_type.6cb = var_pattern %x.patt [concrete = constants.%x.var_patt]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %x.var, constants.%Destroy.WithSelf.Op.403171.2
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%x.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %x.var, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%x.var)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.1(%self.param: ref %empty_struct_type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.1(%self.param: ref %empty_struct_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc12_3.2(%self.param: ref %X) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc12_3.2(%self.param: ref %X) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
+45 -8
View File
@@ -100,13 +100,14 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: --- function.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc5 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc5 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: %.262: Core.Form = init_form %empty_tuple.type [concrete]
// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern [concrete]
// CHECK:STDOUT: %return.patt: %pattern_type.cb1 = return_slot_pattern %return.param_patt, %empty_tuple.type [concrete]
@@ -164,14 +165,15 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: %c.ref.loc20: ref %empty_tuple.type = name_ref c, %c
// CHECK:STDOUT: %.loc20_10: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc20_11: init %empty_tuple.type = converted %c.ref.loc20, %.loc20_10 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %c.var, constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound(%c.var)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %c.var, constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%c.var)
// CHECK:STDOUT: return %.loc20_11
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- class.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %A.G.type: type = fn_type @A.G [concrete]
// CHECK:STDOUT: %A.G: %A.G.type = struct_value () [concrete]
@@ -214,14 +216,39 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: --- call_params.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
// CHECK:STDOUT: %C: %C.type = struct_value () [concrete]
// CHECK:STDOUT: %self.param_patt.65a: %pattern_type.cb1 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.df1: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt.65a [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc17 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc17 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc17 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc17 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc17 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
@@ -242,19 +269,29 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: %empty_tuple.loc17: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc17_7.3: %empty_tuple.type = converted %C.call, %empty_tuple.loc17 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc17: <bound method> = bound_method %.loc17_7.2, constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc17: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc17(%.loc17_7.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc17: <bound method> = bound_method %.loc17_7.2, constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc17: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc17(%.loc17_7.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc13: <bound method> = bound_method %.loc13_7.2, constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc13: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc13(%.loc13_7.2)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13: <bound method> = bound_method %.loc13_7.2, constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13(%.loc13_7.2)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc17(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc17(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc17(%self.param: ref %empty_tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- file_without_ranges.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -34,6 +34,7 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: --- with-range.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -50,6 +51,7 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: --- without-range.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -36,6 +36,7 @@ library "[[@TEST_NAME]]";
// CHECK:STDOUT: --- with-range.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -23,17 +23,41 @@ fn A() {
// CHECK:STDOUT: --- duplicate_name_same_line.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %n.patt.785a0d.1: %pattern_type.cb1 = ref_binding_pattern n [concrete]
// CHECK:STDOUT: %n.var_patt.961036.1: %pattern_type.cb1 = var_pattern %n.patt.785a0d.1 [concrete]
// CHECK:STDOUT: %self.param_patt.65a: %pattern_type.cb1 = ref_param_pattern [concrete]
// CHECK:STDOUT: %self.patt.df1: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt.65a [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfc: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc18 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01: %Destroy.WithSelf.SubobjectDestroy.type.dfc = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef0: type = fn_type @Destroy.WithSelf.Op.loc18 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.Op.403: %Destroy.WithSelf.Op.type.ef0 = struct_value () [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbc: type = fn_type @Destroy.WithSelf.SelfDestruct.loc18 [concrete]
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3: %Destroy.WithSelf.SelfDestruct.type.fbc = struct_value () [concrete]
// CHECK:STDOUT: %n.patt.785a0d.2: %pattern_type.cb1 = ref_binding_pattern n [concrete]
// CHECK:STDOUT: %n.var_patt.961036.2: %pattern_type.cb1 = var_pattern %n.patt.785a0d.2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generated {
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl: %Destroy.WithSelf.SubobjectDestroy.type.dfc = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc18 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl: %Destroy.WithSelf.Op.type.ef0 = fn_decl @Destroy.WithSelf.Op.loc18 [concrete = constants.%Destroy.WithSelf.Op.403] {
// CHECK:STDOUT: %self.param_patt: %pattern_type.cb1 = ref_param_pattern [concrete = constants.%self.param_patt.65a]
// CHECK:STDOUT: %self.patt: %pattern_type.cb1 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.df1]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %self.param: ref %empty_tuple.type = ref_param call_param0
// CHECK:STDOUT: %self: ref %empty_tuple.type = wrapper_binding self, %self.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @A() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: <elided>
@@ -53,8 +77,8 @@ fn A() {
// CHECK:STDOUT: %n.patt.loc18_17: %pattern_type.cb1 = ref_binding_pattern n [concrete = constants.%n.patt.785a0d.1]
// CHECK:STDOUT: %n.var_patt.loc18_5: %pattern_type.cb1 = var_pattern %n.patt.loc18_17 [concrete = constants.%n.var_patt.961036.1]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc18_5: <bound method> = bound_method %n.var.loc18_5, constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc18_5: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc18_5(%n.var.loc18_5)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc18_5: <bound method> = bound_method %n.var.loc18_5, constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc18_5: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc18_5(%n.var.loc18_5)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT:
// CHECK:STDOUT: !if.else:
@@ -72,13 +96,22 @@ fn A() {
// CHECK:STDOUT: %n.patt.loc18_49: %pattern_type.cb1 = ref_binding_pattern n [concrete = constants.%n.patt.785a0d.2]
// CHECK:STDOUT: %n.var_patt.loc18_37: %pattern_type.cb1 = var_pattern %n.patt.loc18_49 [concrete = constants.%n.var_patt.961036.2]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound.loc18_37: <bound method> = bound_method %n.var.loc18_37, constants.%Destroy.WithSelf.Op.403
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc18_37: init %empty_tuple.type = call %Destroy.WithSelf.Op.bound.loc18_37(%n.var.loc18_37)
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc18_37: <bound method> = bound_method %n.var.loc18_37, constants.%Destroy.WithSelf.SelfDestruct.db3
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc18_37: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc18_37(%n.var.loc18_37)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT:
// CHECK:STDOUT: !if.done:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc18(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc18(%self.param: ref %empty_tuple.type) = "no_op";
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc18(%self.param: ref %empty_tuple.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl(%self.param)
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl(%self.param)
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -83,6 +83,7 @@ fn F(c: C) { c.(I.Op)(); }
// CHECK:STDOUT: --- exclude/included.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: }
@@ -119,6 +120,7 @@ fn F(c: C) { c.(I.Op)(); }
// CHECK:STDOUT: --- exclude/included_with_range.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic]
@@ -213,6 +215,7 @@ fn F(c: C) { c.(I.Op)(); }
// CHECK:STDOUT: --- import_included.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
@@ -350,6 +353,7 @@ fn F(c: C) { c.(I.Op)(); }
// CHECK:STDOUT: --- import_excluded.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete]
// CHECK:STDOUT: %c.param_patt: %pattern_type.98b = value_param_pattern [concrete]
+1
View File
@@ -31,6 +31,7 @@ fn Boo[runtime a: ()]() {}
// CHECK:STDOUT: --- fail_multi_error.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [concrete]
// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [concrete]
// CHECK:STDOUT: %Boo.type: type = fn_type @Boo [concrete]
+1
View File
@@ -17,6 +17,7 @@ var b: i32 = ((2));
// CHECK:STDOUT: --- parens.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
+1
View File
@@ -26,6 +26,7 @@ fn C(r#if: ()) -> () {
// CHECK:STDOUT: --- raw_identifier.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
+8 -6
View File
@@ -21,8 +21,9 @@
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {}}
// CHECK:STDOUT: entity_names: {}
// CHECK:STDOUT: functions: {}
// CHECK:STDOUT: classes: {}
@@ -60,9 +61,10 @@
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: 'inst(TypeType)': {kind: TypeType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(AutoType)': {kind: AutoType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(BoolType)': {kind: BoolType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(BoundMethodType)': {kind: BoundMethodType, type: type(TypeType)}
@@ -78,7 +80,7 @@
// CHECK:STDOUT: 'inst(UnspecifiedValueType)': {kind: UnspecifiedValueType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(VtableType)': {kind: VtableType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(WitnessType)': {kind: WitnessType, type: type(TypeType)}
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
@@ -98,7 +100,7 @@
// CHECK:STDOUT: 'inst(UnspecifiedValueType)': concrete_constant(inst(UnspecifiedValueType))
// CHECK:STDOUT: 'inst(VtableType)': concrete_constant(inst(VtableType))
// CHECK:STDOUT: 'inst(WitnessType)': concrete_constant(inst(WitnessType))
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: symbolic_constants: {}
// CHECK:STDOUT: inst_blocks:
// CHECK:STDOUT: inst_block_empty: {}
@@ -107,7 +109,7 @@
// CHECK:STDOUT: imports: {}
// CHECK:STDOUT: global_init: {}
// CHECK:STDOUT: inst_block50000005:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: value_stores:
// CHECK:STDOUT: shared_values:
// CHECK:STDOUT: ints: {}
+147 -146
View File
@@ -30,21 +30,22 @@ fn F(generic Form: Core.Form) ->? Form;
// CHECK:STDOUT: import_ir_inst0: {ir_id: import_ir70000003, inst_id: inst50000023}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Core): inst70000012, name0: inst70000033}}
// CHECK:STDOUT: name_scope70000001: {inst: inst70000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000017}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Core): inst70000012, name0: inst70000032}}
// CHECK:STDOUT: name_scope70000001: {inst: inst70000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000016}}
// CHECK:STDOUT: entity_names:
// CHECK:STDOUT: entity_name70000000: {name: name(PeriodSelf), parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, is_frozen_period_self: 1}, form: inst<none>, type: inst<none>}
// CHECK:STDOUT: entity_name70000001: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst<none>, type: inst<none>}
// CHECK:STDOUT: entity_name70000002: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0, form: inst<none>, type: inst70000018}
// CHECK:STDOUT: entity_name70000002: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0, form: inst<none>, type: inst70000017}
// CHECK:STDOUT: functions:
// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000021, return_form_inst_id: inst70000020, return_pattern_id: inst7000002A}
// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000020, return_form_inst_id: inst7000001F, return_pattern_id: inst70000029}
// CHECK:STDOUT: classes: {}
// CHECK:STDOUT: interfaces: {}
// CHECK:STDOUT: associated_constants: {}
// CHECK:STDOUT: impls: {}
// CHECK:STDOUT: generics:
// CHECK:STDOUT: generic70000000: {decl: inst70000033, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block<none>}
// CHECK:STDOUT: generic70000000: {decl: inst70000032, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block<none>}
// CHECK:STDOUT: specifics:
// CHECK:STDOUT: specific70000000: {generic: generic70000000, args: inst_block7000000C, decl_block_id: inst_block7000000E, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
// CHECK:STDOUT: specific_interfaces: {}
@@ -76,190 +77,190 @@ fn F(generic Form: Core.Form) ->? Form;
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: 'type(inst70000039)':
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst7000003A)}
// CHECK:STDOUT: 'type(inst70000038)':
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000039)}
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: 'type(inst7000003A)':
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst7000003A)}
// CHECK:STDOUT: 'type(inst70000039)':
// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000039)}
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: declared_facet_type70000000: {}
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000011: {kind: ImportDecl, arg0: name(Core)}
// CHECK:STDOUT: inst70000012: {kind: Namespace, arg0: name_scope70000001, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000013: {kind: FacetType, arg0: declared_facet_type70000000, type: type(TypeType)}
// CHECK:STDOUT: inst70000014: {kind: SymbolicBinding, arg0: entity_name70000000, arg1: inst<none>, type: type(inst70000013)}
// CHECK:STDOUT: inst70000015: {kind: SymbolicBinding, arg0: entity_name70000000, arg1: inst<none>, type: type(inst70000013)}
// CHECK:STDOUT: inst70000016: {kind: NameRef, arg0: name(Core), arg1: inst70000012, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000017: {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name70000001, type: type(TypeType)}
// CHECK:STDOUT: inst70000018: {kind: NameRef, arg0: name1, arg1: inst70000017, type: type(TypeType)}
// CHECK:STDOUT: inst70000019: {kind: PatternType, arg0: inst(FormType), type: type(TypeType)}
// CHECK:STDOUT: inst7000001A: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000019)}
// CHECK:STDOUT: inst7000001B: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000019)}
// CHECK:STDOUT: inst7000001C: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000019)}
// CHECK:STDOUT: inst70000013: {kind: SymbolicBinding, arg0: entity_name70000000, arg1: inst<none>, type: type(TypeType)}
// CHECK:STDOUT: inst70000014: {kind: SymbolicBinding, arg0: entity_name70000000, arg1: inst<none>, type: type(TypeType)}
// CHECK:STDOUT: inst70000015: {kind: NameRef, arg0: name(Core), arg1: inst70000012, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000016: {kind: ImportRefLoaded, arg0: import_ir_inst0, arg1: entity_name70000001, type: type(TypeType)}
// CHECK:STDOUT: inst70000017: {kind: NameRef, arg0: name1, arg1: inst70000016, type: type(TypeType)}
// CHECK:STDOUT: inst70000018: {kind: PatternType, arg0: inst(FormType), type: type(TypeType)}
// CHECK:STDOUT: inst70000019: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000018)}
// CHECK:STDOUT: inst7000001A: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000018)}
// CHECK:STDOUT: inst7000001B: {kind: SymbolicBindingPattern, arg0: entity_name70000002, type: type(inst70000018)}
// CHECK:STDOUT: inst7000001C: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
// CHECK:STDOUT: inst7000001D: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
// CHECK:STDOUT: inst7000001E: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
// CHECK:STDOUT: inst7000001F: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, type: type(inst(FormType))}
// CHECK:STDOUT: inst70000020: {kind: NameRef, arg0: name1, arg1: inst7000001D, type: type(inst(FormType))}
// CHECK:STDOUT: inst70000021: {kind: TypeComponentOf, arg0: inst70000020, type: type(TypeType)}
// CHECK:STDOUT: inst7000001F: {kind: NameRef, arg0: name1, arg1: inst7000001C, type: type(inst(FormType))}
// CHECK:STDOUT: inst70000020: {kind: TypeComponentOf, arg0: inst7000001F, type: type(TypeType)}
// CHECK:STDOUT: inst70000021: {kind: TypeComponentOf, arg0: inst7000001D, type: type(TypeType)}
// CHECK:STDOUT: inst70000022: {kind: TypeComponentOf, arg0: inst7000001E, type: type(TypeType)}
// CHECK:STDOUT: inst70000023: {kind: TypeComponentOf, arg0: inst7000001F, type: type(TypeType)}
// CHECK:STDOUT: inst70000024: {kind: PatternType, arg0: inst70000022, type: type(TypeType)}
// CHECK:STDOUT: inst70000025: {kind: OutFormParamPatternAction, arg0: inst70000020, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000026: {kind: SpliceInst, arg0: inst70000025, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst70000027: {kind: SpliceInst, arg0: inst70000025, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000028: {kind: PatternType, arg0: inst70000023, type: type(TypeType)}
// CHECK:STDOUT: inst70000029: {kind: SpliceInst, arg0: inst70000025, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst7000002A: {kind: ReturnSlotPattern, arg0: inst70000026, arg1: inst70000021, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst7000002B: {kind: ReturnSlotPattern, arg0: inst70000027, arg1: inst70000022, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst7000002C: {kind: ReturnSlotPattern, arg0: inst70000029, arg1: inst70000023, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst7000002D: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000018, type: type(TypeType)}
// CHECK:STDOUT: inst7000002E: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
// CHECK:STDOUT: inst7000002F: {kind: SpliceInst, arg0: inst7000002E, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst70000030: {kind: SpliceInst, arg0: inst7000002E, type: type(symbolic_constant70000005)}
// CHECK:STDOUT: inst70000031: {kind: SpliceInst, arg0: inst7000002E, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst70000032: {kind: ReturnSlot, arg0: inst70000022, arg1: inst7000002F, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst70000033: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst70000039)}
// CHECK:STDOUT: inst70000034: {kind: OutFormParamPatternAction, arg0: inst7000001E, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000035: {kind: SpliceInst, arg0: inst70000034, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000036: {kind: ReturnSlotPattern, arg0: inst70000035, arg1: inst70000022, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000037: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000038: {kind: SpliceInst, arg0: inst70000037, type: type(symbolic_constant70000005)}
// CHECK:STDOUT: inst70000039: {kind: FunctionType, arg0: function70000000, arg1: specific<none>, type: type(TypeType)}
// CHECK:STDOUT: inst7000003A: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
// CHECK:STDOUT: inst7000003B: {kind: StructValue, arg0: inst_block_empty, type: type(inst70000039)}
// CHECK:STDOUT: inst70000023: {kind: PatternType, arg0: inst70000021, type: type(TypeType)}
// CHECK:STDOUT: inst70000024: {kind: OutFormParamPatternAction, arg0: inst7000001F, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000025: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst70000026: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000027: {kind: PatternType, arg0: inst70000022, type: type(TypeType)}
// CHECK:STDOUT: inst70000028: {kind: SpliceInst, arg0: inst70000024, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst70000029: {kind: ReturnSlotPattern, arg0: inst70000025, arg1: inst70000020, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst7000002A: {kind: ReturnSlotPattern, arg0: inst70000026, arg1: inst70000021, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst7000002B: {kind: ReturnSlotPattern, arg0: inst70000028, arg1: inst70000022, type: type(symbolic_constant7000000A)}
// CHECK:STDOUT: inst7000002C: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000017, type: type(TypeType)}
// CHECK:STDOUT: inst7000002D: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
// CHECK:STDOUT: inst7000002E: {kind: SpliceInst, arg0: inst7000002D, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst7000002F: {kind: SpliceInst, arg0: inst7000002D, type: type(symbolic_constant70000005)}
// CHECK:STDOUT: inst70000030: {kind: SpliceInst, arg0: inst7000002D, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst70000031: {kind: ReturnSlot, arg0: inst70000021, arg1: inst7000002E, type: type(symbolic_constant70000006)}
// CHECK:STDOUT: inst70000032: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst70000038)}
// CHECK:STDOUT: inst70000033: {kind: OutFormParamPatternAction, arg0: inst7000001D, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000034: {kind: SpliceInst, arg0: inst70000033, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000035: {kind: ReturnSlotPattern, arg0: inst70000034, arg1: inst70000021, type: type(symbolic_constant70000007)}
// CHECK:STDOUT: inst70000036: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))}
// CHECK:STDOUT: inst70000037: {kind: SpliceInst, arg0: inst70000036, type: type(symbolic_constant70000005)}
// CHECK:STDOUT: inst70000038: {kind: FunctionType, arg0: function70000000, arg1: specific<none>, type: type(TypeType)}
// CHECK:STDOUT: inst70000039: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
// CHECK:STDOUT: inst7000003A: {kind: StructValue, arg0: inst_block_empty, type: type(inst70000038)}
// CHECK:STDOUT: bundles:
// CHECK:STDOUT: bundle70000000: {arg0: inst70000027, arg1: call_param0}
// CHECK:STDOUT: bundle70000000: {arg0: inst70000026, arg1: call_param0}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst70000012: concrete_constant(inst70000012)
// CHECK:STDOUT: inst70000013: concrete_constant(inst70000013)
// CHECK:STDOUT: inst70000013: symbolic_constant70000000
// CHECK:STDOUT: inst70000014: symbolic_constant70000000
// CHECK:STDOUT: inst70000015: symbolic_constant70000000
// CHECK:STDOUT: inst70000016: concrete_constant(inst70000012)
// CHECK:STDOUT: inst70000015: concrete_constant(inst70000012)
// CHECK:STDOUT: inst70000016: concrete_constant(inst(FormType))
// CHECK:STDOUT: inst70000017: concrete_constant(inst(FormType))
// CHECK:STDOUT: inst70000018: concrete_constant(inst(FormType))
// CHECK:STDOUT: inst70000019: concrete_constant(inst70000019)
// CHECK:STDOUT: inst7000001A: symbolic_constant70000002
// CHECK:STDOUT: inst7000001B: symbolic_constant70000001
// CHECK:STDOUT: inst7000001C: symbolic_constant70000002
// CHECK:STDOUT: inst7000001D: symbolic_constant70000004
// CHECK:STDOUT: inst7000001E: symbolic_constant70000003
// CHECK:STDOUT: inst70000018: concrete_constant(inst70000018)
// CHECK:STDOUT: inst70000019: symbolic_constant70000002
// CHECK:STDOUT: inst7000001A: symbolic_constant70000001
// CHECK:STDOUT: inst7000001B: symbolic_constant70000002
// CHECK:STDOUT: inst7000001C: symbolic_constant70000004
// CHECK:STDOUT: inst7000001D: symbolic_constant70000003
// CHECK:STDOUT: inst7000001E: symbolic_constant70000004
// CHECK:STDOUT: inst7000001F: symbolic_constant70000004
// CHECK:STDOUT: inst70000020: symbolic_constant70000004
// CHECK:STDOUT: inst70000021: symbolic_constant70000006
// CHECK:STDOUT: inst70000022: symbolic_constant70000005
// CHECK:STDOUT: inst70000023: symbolic_constant70000006
// CHECK:STDOUT: inst70000024: symbolic_constant70000007
// CHECK:STDOUT: inst70000025: symbolic_constant70000008
// CHECK:STDOUT: inst70000026: symbolic_constant7000000B
// CHECK:STDOUT: inst70000027: symbolic_constant70000009
// CHECK:STDOUT: inst70000028: symbolic_constant7000000A
// CHECK:STDOUT: inst70000029: symbolic_constant7000000B
// CHECK:STDOUT: inst7000002A: symbolic_constant7000000D
// CHECK:STDOUT: inst7000002B: symbolic_constant7000000C
// CHECK:STDOUT: inst7000002C: symbolic_constant7000000D
// CHECK:STDOUT: inst7000002D: concrete_constant(inst(FormType))
// CHECK:STDOUT: inst7000002E: symbolic_constant7000000E
// CHECK:STDOUT: inst7000002F: symbolic_constant70000010
// CHECK:STDOUT: inst70000030: symbolic_constant7000000F
// CHECK:STDOUT: inst70000031: symbolic_constant70000010
// CHECK:STDOUT: inst70000033: concrete_constant(inst7000003B)
// CHECK:STDOUT: inst70000034: symbolic_constant70000011
// CHECK:STDOUT: inst70000035: symbolic_constant70000012
// CHECK:STDOUT: inst70000036: symbolic_constant70000013
// CHECK:STDOUT: inst70000037: symbolic_constant70000014
// CHECK:STDOUT: inst70000038: symbolic_constant70000015
// CHECK:STDOUT: inst70000020: symbolic_constant70000006
// CHECK:STDOUT: inst70000021: symbolic_constant70000005
// CHECK:STDOUT: inst70000022: symbolic_constant70000006
// CHECK:STDOUT: inst70000023: symbolic_constant70000007
// CHECK:STDOUT: inst70000024: symbolic_constant70000008
// CHECK:STDOUT: inst70000025: symbolic_constant7000000B
// CHECK:STDOUT: inst70000026: symbolic_constant70000009
// CHECK:STDOUT: inst70000027: symbolic_constant7000000A
// CHECK:STDOUT: inst70000028: symbolic_constant7000000B
// CHECK:STDOUT: inst70000029: symbolic_constant7000000D
// CHECK:STDOUT: inst7000002A: symbolic_constant7000000C
// CHECK:STDOUT: inst7000002B: symbolic_constant7000000D
// CHECK:STDOUT: inst7000002C: concrete_constant(inst(FormType))
// CHECK:STDOUT: inst7000002D: symbolic_constant7000000E
// CHECK:STDOUT: inst7000002E: symbolic_constant70000010
// CHECK:STDOUT: inst7000002F: symbolic_constant7000000F
// CHECK:STDOUT: inst70000030: symbolic_constant70000010
// CHECK:STDOUT: inst70000032: concrete_constant(inst7000003A)
// CHECK:STDOUT: inst70000033: symbolic_constant70000011
// CHECK:STDOUT: inst70000034: symbolic_constant70000012
// CHECK:STDOUT: inst70000035: symbolic_constant70000013
// CHECK:STDOUT: inst70000036: symbolic_constant70000014
// CHECK:STDOUT: inst70000037: symbolic_constant70000015
// CHECK:STDOUT: inst70000038: concrete_constant(inst70000038)
// CHECK:STDOUT: inst70000039: concrete_constant(inst70000039)
// CHECK:STDOUT: inst7000003A: concrete_constant(inst7000003A)
// CHECK:STDOUT: inst7000003B: concrete_constant(inst7000003B)
// CHECK:STDOUT: symbolic_constants:
// CHECK:STDOUT: symbolic_constant70000000: {inst: inst70000015, kind: self, attached: null}
// CHECK:STDOUT: symbolic_constant70000001: {inst: inst7000001B, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000002: {inst: inst7000001B, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl0}}
// CHECK:STDOUT: symbolic_constant70000003: {inst: inst7000001E, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000004: {inst: inst7000001E, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl1}}
// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000022, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000022, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl2}}
// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000024, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000008: {inst: inst70000025, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl3}}
// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000027, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000024, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl4}}
// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000027, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}}
// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst7000002B, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst7000002B, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}}
// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst7000002E, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}}
// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst70000030, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000010: {inst: inst70000030, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl8}}
// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000034, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000035, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000013: {inst: inst70000036, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000014: {inst: inst70000037, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000015: {inst: inst70000038, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000000: {inst: inst70000014, kind: self, attached: null}
// CHECK:STDOUT: symbolic_constant70000001: {inst: inst7000001A, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000002: {inst: inst7000001A, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl0}}
// CHECK:STDOUT: symbolic_constant70000003: {inst: inst7000001D, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000004: {inst: inst7000001D, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl1}}
// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000021, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000021, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl2}}
// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000023, kind: checked, attached: null}
// CHECK:STDOUT: symbolic_constant70000008: {inst: inst70000024, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl3}}
// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000026, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000023, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl4}}
// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000026, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}}
// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst7000002A, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst7000002A, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}}
// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst7000002D, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}}
// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst7000002F, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000010: {inst: inst7000002F, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl8}}
// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000033, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000034, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000013: {inst: inst70000035, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000014: {inst: inst70000036, kind: template, attached: null}
// CHECK:STDOUT: symbolic_constant70000015: {inst: inst70000037, kind: template, attached: null}
// CHECK:STDOUT: inst_blocks:
// CHECK:STDOUT: inst_block_empty: {}
// CHECK:STDOUT: exports:
// CHECK:STDOUT: 0: inst70000033
// CHECK:STDOUT: 0: inst70000032
// CHECK:STDOUT: generated: {}
// CHECK:STDOUT: imports:
// CHECK:STDOUT: 0: inst70000012
// CHECK:STDOUT: 1: inst70000017
// CHECK:STDOUT: 1: inst70000016
// CHECK:STDOUT: global_init: {}
// CHECK:STDOUT: inst_block70000005:
// CHECK:STDOUT: 0: inst70000014
// CHECK:STDOUT: 1: inst70000016
// CHECK:STDOUT: 2: inst70000018
// CHECK:STDOUT: 0: inst70000013
// CHECK:STDOUT: 1: inst70000015
// CHECK:STDOUT: 2: inst70000017
// CHECK:STDOUT: inst_block70000006:
// CHECK:STDOUT: 0: inst7000001A
// CHECK:STDOUT: 0: inst70000019
// CHECK:STDOUT: inst_block70000007:
// CHECK:STDOUT: 0: inst70000026
// CHECK:STDOUT: 0: inst70000025
// CHECK:STDOUT: inst_block70000008:
// CHECK:STDOUT: 0: inst7000002F
// CHECK:STDOUT: 0: inst7000002E
// CHECK:STDOUT: inst_block70000009:
// CHECK:STDOUT: 0: inst7000001A
// CHECK:STDOUT: 1: inst70000026
// CHECK:STDOUT: 2: inst7000002A
// CHECK:STDOUT: 0: inst70000019
// CHECK:STDOUT: 1: inst70000025
// CHECK:STDOUT: 2: inst70000029
// CHECK:STDOUT: inst_block7000000A:
// CHECK:STDOUT: 0: inst70000020
// CHECK:STDOUT: 1: inst70000021
// CHECK:STDOUT: 2: inst7000002D
// CHECK:STDOUT: 3: inst7000001D
// CHECK:STDOUT: 4: inst7000002F
// CHECK:STDOUT: 5: inst70000032
// CHECK:STDOUT: 0: inst7000001F
// CHECK:STDOUT: 1: inst70000020
// CHECK:STDOUT: 2: inst7000002C
// CHECK:STDOUT: 3: inst7000001C
// CHECK:STDOUT: 4: inst7000002E
// CHECK:STDOUT: 5: inst70000031
// CHECK:STDOUT: inst_block7000000B:
// CHECK:STDOUT: 0: inst7000001D
// CHECK:STDOUT: inst_block7000000C:
// CHECK:STDOUT: 0: inst7000001E
// CHECK:STDOUT: inst_block7000000D:
// CHECK:STDOUT: 0: inst7000001C
// CHECK:STDOUT: 1: inst7000001F
// CHECK:STDOUT: 2: inst70000023
// CHECK:STDOUT: 3: inst70000025
// CHECK:STDOUT: 4: inst70000028
// CHECK:STDOUT: 5: inst70000029
// CHECK:STDOUT: 6: inst7000002C
// CHECK:STDOUT: 7: inst7000002E
// CHECK:STDOUT: 8: inst70000031
// CHECK:STDOUT: inst_block7000000E:
// CHECK:STDOUT: inst_block7000000C:
// CHECK:STDOUT: 0: inst7000001D
// CHECK:STDOUT: inst_block7000000D:
// CHECK:STDOUT: 0: inst7000001B
// CHECK:STDOUT: 1: inst7000001E
// CHECK:STDOUT: 2: inst70000022
// CHECK:STDOUT: 3: inst70000034
// CHECK:STDOUT: 4: inst70000024
// CHECK:STDOUT: 5: inst70000035
// CHECK:STDOUT: 6: inst70000036
// CHECK:STDOUT: 7: inst70000037
// CHECK:STDOUT: 8: inst70000038
// CHECK:STDOUT: 3: inst70000024
// CHECK:STDOUT: 4: inst70000027
// CHECK:STDOUT: 5: inst70000028
// CHECK:STDOUT: 6: inst7000002B
// CHECK:STDOUT: 7: inst7000002D
// CHECK:STDOUT: 8: inst70000030
// CHECK:STDOUT: inst_block7000000E:
// CHECK:STDOUT: 0: inst7000001A
// CHECK:STDOUT: 1: inst7000001D
// CHECK:STDOUT: 2: inst70000021
// CHECK:STDOUT: 3: inst70000033
// CHECK:STDOUT: 4: inst70000023
// CHECK:STDOUT: 5: inst70000034
// CHECK:STDOUT: 6: inst70000035
// CHECK:STDOUT: 7: inst70000036
// CHECK:STDOUT: 8: inst70000037
// CHECK:STDOUT: inst_block7000000F:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst70000011
// CHECK:STDOUT: 2: inst70000033
// CHECK:STDOUT: 2: inst70000032
// CHECK:STDOUT: value_stores:
// CHECK:STDOUT: shared_values:
// CHECK:STDOUT: ints: {}
@@ -53,7 +53,7 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: import_ir_inst3: {ir_id: import_ir(Cpp), clang_source_loc_id: clang_source_loc50000003}
// CHECK:STDOUT: import_ir_inst4: {ir_id: import_ir(Cpp), clang_source_loc_id: clang_source_loc50000004}
// CHECK:STDOUT: clang_decls:
// CHECK:STDOUT: clang_decl_id50000000: {key: {decl: "namespace Carbon {\n}"}, inst_id: inst10}
// CHECK:STDOUT: clang_decl_id50000000: {key: {decl: "namespace Carbon {\n}"}, inst_id: inst(Package)}
// CHECK:STDOUT: clang_decl_id50000001: {key: {decl: "<translation unit>"}, inst_id: inst50000012}
// CHECK:STDOUT: clang_decl_id50000002: {key: {decl: "struct X {}"}, inst_id: inst50000014}
// CHECK:STDOUT: clang_decl_id50000003: {key: {decl: "X * _Nonnull p"}, inst_id: inst50000025}
@@ -65,8 +65,9 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: clang_decl_signatures:
// CHECK:STDOUT: clang_decl_signature_id50000000: {kind: normal, num_params: 0}
// CHECK:STDOUT: clang_decl_signature_id50000001: {kind: normal, num_params: 1, modes: [value]}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Cpp): inst50000012, name0: inst5000001F}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name(Cpp): inst50000012, name0: inst5000001F}}
// CHECK:STDOUT: name_scope50000001: {inst: inst50000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name2: inst50000014, name3: inst5000002D, name4: inst50000055}}
// CHECK:STDOUT: name_scope50000002: {inst: inst50000014, parent_scope: name_scope50000001, has_error: false, extended_scopes: [], names: {}}
// CHECK:STDOUT: entity_names:
@@ -180,9 +181,10 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: 'inst(TypeType)': {kind: TypeType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(AutoType)': {kind: AutoType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(BoolType)': {kind: BoolType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(BoundMethodType)': {kind: BoundMethodType, type: type(TypeType)}
@@ -198,7 +200,7 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: 'inst(UnspecifiedValueType)': {kind: UnspecifiedValueType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(VtableType)': {kind: VtableType, type: type(TypeType)}
// CHECK:STDOUT: 'inst(WitnessType)': {kind: WitnessType, type: type(TypeType)}
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst50000011: {kind: ImportCppDecl}
// CHECK:STDOUT: inst50000012: {kind: Namespace, arg0: name_scope50000001, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst50000013: {kind: NameRef, arg0: name(Cpp), arg1: inst50000012, type: type(inst(NamespaceType))}
@@ -295,7 +297,7 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: 'inst(UnspecifiedValueType)': concrete_constant(inst(UnspecifiedValueType))
// CHECK:STDOUT: 'inst(VtableType)': concrete_constant(inst(VtableType))
// CHECK:STDOUT: 'inst(WitnessType)': concrete_constant(inst(WitnessType))
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst50000012: concrete_constant(inst50000012)
// CHECK:STDOUT: inst50000013: concrete_constant(inst50000012)
// CHECK:STDOUT: inst50000014: concrete_constant(inst50000015)
@@ -449,7 +451,7 @@ fn G(x: Cpp.X) {
// CHECK:STDOUT: inst_block5000001D:
// CHECK:STDOUT: 0: inst5000005B
// CHECK:STDOUT: inst_block5000001E:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst50000011
// CHECK:STDOUT: 2: inst5000001F
// CHECK:STDOUT: value_stores:
+18 -10
View File
@@ -38,8 +38,9 @@ fn B() {
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011}}
// CHECK:STDOUT: entity_names: {}
// CHECK:STDOUT: functions:
// CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block_empty, call_params_id: inst_block_empty, body: [inst_block50000006]}
@@ -88,9 +89,11 @@ fn B() {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst50000011: {kind: FunctionDecl, arg0: function50000000, arg1: inst_block_empty, type: type(inst50000012)}
// CHECK:STDOUT: inst50000012: {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
// CHECK:STDOUT: inst50000013: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
@@ -99,7 +102,8 @@ fn B() {
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst50000011: concrete_constant(inst50000014)
// CHECK:STDOUT: inst50000012: concrete_constant(inst50000012)
// CHECK:STDOUT: inst50000013: concrete_constant(inst50000013)
@@ -116,7 +120,7 @@ fn B() {
// CHECK:STDOUT: inst_block50000006:
// CHECK:STDOUT: 0: inst50000015
// CHECK:STDOUT: inst_block50000007:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst50000011
// CHECK:STDOUT: value_stores:
// CHECK:STDOUT: shared_values:
@@ -142,8 +146,9 @@ fn B() {
// CHECK:STDOUT: import_ir_inst1: {ir_id: import_ir70000002, inst_id: inst50000011}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst70000012, name0: inst70000013}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst70000012, name0: inst70000013}}
// CHECK:STDOUT: name_scope70000001: {inst: inst70000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000018}}
// CHECK:STDOUT: entity_names:
// CHECK:STDOUT: entity_name70000000: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst<none>, type: inst<none>}
@@ -195,9 +200,11 @@ fn B() {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000011: {kind: ImportDecl, arg0: name1}
// CHECK:STDOUT: inst70000012: {kind: Namespace, arg0: name_scope70000001, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000013: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block_empty, type: type(inst70000014)}
@@ -215,7 +222,8 @@ fn B() {
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst70000012: concrete_constant(inst70000012)
// CHECK:STDOUT: inst70000013: concrete_constant(inst70000016)
// CHECK:STDOUT: inst70000014: concrete_constant(inst70000014)
@@ -245,7 +253,7 @@ fn B() {
// CHECK:STDOUT: 2: inst7000001D
// CHECK:STDOUT: 3: inst7000001E
// CHECK:STDOUT: inst_block70000007:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst70000011
// CHECK:STDOUT: 2: inst70000013
// CHECK:STDOUT: value_stores:
@@ -38,8 +38,9 @@ fn B() {
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst50000011}}
// CHECK:STDOUT: entity_names: {}
// CHECK:STDOUT: functions:
// CHECK:STDOUT: function50000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block_empty, call_params_id: inst_block_empty, body: [inst_block50000006]}
@@ -88,9 +89,11 @@ fn B() {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst50000011: {kind: FunctionDecl, arg0: function50000000, arg1: inst_block_empty, type: type(inst50000012)}
// CHECK:STDOUT: inst50000012: {kind: FunctionType, arg0: function50000000, arg1: specific<none>, type: type(TypeType)}
// CHECK:STDOUT: inst50000013: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
@@ -99,7 +102,8 @@ fn B() {
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst50000011: concrete_constant(inst50000014)
// CHECK:STDOUT: inst50000012: concrete_constant(inst50000012)
// CHECK:STDOUT: inst50000013: concrete_constant(inst50000013)
@@ -116,7 +120,7 @@ fn B() {
// CHECK:STDOUT: inst_block50000006:
// CHECK:STDOUT: 0: inst50000015
// CHECK:STDOUT: inst_block50000007:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst50000011
// CHECK:STDOUT: value_stores:
// CHECK:STDOUT: shared_values:
@@ -130,6 +134,7 @@ fn B() {
// CHECK:STDOUT: --- a.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
// CHECK:STDOUT: }
@@ -161,8 +166,9 @@ fn B() {
// CHECK:STDOUT: import_ir_inst1: {ir_id: import_ir70000002, inst_id: inst50000011}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst70000012, name0: inst70000013}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst70000012, name0: inst70000013}}
// CHECK:STDOUT: name_scope70000001: {inst: inst70000012, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000018}}
// CHECK:STDOUT: entity_names:
// CHECK:STDOUT: entity_name70000000: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst<none>, type: inst<none>}
@@ -214,9 +220,11 @@ fn B() {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000011: {kind: ImportDecl, arg0: name1}
// CHECK:STDOUT: inst70000012: {kind: Namespace, arg0: name_scope70000001, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst70000013: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block_empty, type: type(inst70000014)}
@@ -234,7 +242,8 @@ fn B() {
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst70000012: concrete_constant(inst70000012)
// CHECK:STDOUT: inst70000013: concrete_constant(inst70000016)
// CHECK:STDOUT: inst70000014: concrete_constant(inst70000014)
@@ -264,7 +273,7 @@ fn B() {
// CHECK:STDOUT: 2: inst7000001D
// CHECK:STDOUT: 3: inst7000001E
// CHECK:STDOUT: inst_block70000007:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst70000011
// CHECK:STDOUT: 2: inst70000013
// CHECK:STDOUT: value_stores:
@@ -280,6 +289,7 @@ fn B() {
// CHECK:STDOUT: --- b.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %B.type: type = fn_type @B [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %B: %B.type = struct_value () [concrete]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -29,8 +29,9 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: clang_decls: {}
// CHECK:STDOUT: clang_decl_signatures: {}
// CHECK:STDOUT: default_values: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst10, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst5000002F}}
// CHECK:STDOUT: name_scope0: {inst: inst(Package), parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst5000002F}}
// CHECK:STDOUT: entity_names:
// CHECK:STDOUT: entity_name50000000: {name: name1, parent_scope: name_scope<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>, type: inst50000014}
// CHECK:STDOUT: functions:
@@ -90,9 +91,11 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: object_layout:
// CHECK:STDOUT: size: 0
// CHECK:STDOUT: alignment: 1
// CHECK:STDOUT: declared_facet_types: {}
// CHECK:STDOUT: declared_facet_types:
// CHECK:STDOUT: 'declared_facet_type(Empty)': {}
// CHECK:STDOUT: insts:
// CHECK:STDOUT: inst10: {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: 'inst(TypeType)': {kind: FacetType, arg0: declared_facet_type(Empty), type: type(TypeType)}
// CHECK:STDOUT: 'inst(Package)': {kind: Namespace, arg0: name_scope0, type: type(inst(NamespaceType))}
// CHECK:STDOUT: inst50000011: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)}
// CHECK:STDOUT: inst50000012: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst50000011)}
// CHECK:STDOUT: inst50000013: {kind: TupleValue, arg0: inst_block_empty, type: type(inst50000011)}
@@ -143,7 +146,8 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: bundles: {}
// CHECK:STDOUT: constant_values:
// CHECK:STDOUT: values:
// CHECK:STDOUT: inst10: concrete_constant(inst10)
// CHECK:STDOUT: 'inst(TypeType)': concrete_constant(inst(TypeType))
// CHECK:STDOUT: 'inst(Package)': concrete_constant(inst(Package))
// CHECK:STDOUT: inst50000011: concrete_constant(inst50000011)
// CHECK:STDOUT: inst50000012: concrete_constant(inst50000013)
// CHECK:STDOUT: inst50000013: concrete_constant(inst50000013)
@@ -253,7 +257,7 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: 0: inst50000038
// CHECK:STDOUT: 1: inst5000003C
// CHECK:STDOUT: inst_block50000012:
// CHECK:STDOUT: 0: inst10
// CHECK:STDOUT: 0: inst(Package)
// CHECK:STDOUT: 1: inst5000002F
// CHECK:STDOUT: value_stores:
// CHECK:STDOUT: shared_values:
@@ -268,6 +272,7 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: --- one_file_with_textual_ir.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
+2
View File
@@ -47,6 +47,7 @@ var d: C(false == false) = True();
// CHECK:STDOUT: --- builtin_call.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Eq.type: type = fn_type @Eq [concrete]
// CHECK:STDOUT: %Eq: %Eq.type = struct_value () [concrete]
// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete]
@@ -91,6 +92,7 @@ var d: C(false == false) = True();
// CHECK:STDOUT: --- prelude.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete]
// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete]
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
@@ -29,6 +29,7 @@ let b: Bool() = false;
// CHECK:STDOUT: --- use_types.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete]
// CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
+2
View File
@@ -47,6 +47,7 @@ var d: C(false != false) = False();
// CHECK:STDOUT: --- builtin_call.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %Neq.type: type = fn_type @Neq [concrete]
// CHECK:STDOUT: %Neq: %Neq.type = struct_value () [concrete]
// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete]
@@ -92,6 +93,7 @@ var d: C(false != false) = False();
// CHECK:STDOUT: --- prelude.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete]
// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete]
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
@@ -75,6 +75,7 @@ let c: CharLiteral = AddCharInt('a', Negate(98));
// CHECK:STDOUT: --- success.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.8c6: type = pattern_type Core.CharLiteral [concrete]
// CHECK:STDOUT: %AddCharInt.type: type = fn_type @AddCharInt [concrete]
// CHECK:STDOUT: %AddCharInt: %AddCharInt.type = struct_value () [concrete]
@@ -96,6 +96,7 @@ let c: UInt(8) = ToChar('\u{1E15}');
// CHECK:STDOUT: --- narrow.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %UInt.type: type = fn_type @UInt [concrete]
// CHECK:STDOUT: %UInt: %UInt.type = struct_value () [concrete]
// CHECK:STDOUT: %int_8: Core.IntLiteral = int_value 8 [concrete]
@@ -61,6 +61,7 @@ let g: u8 = ConvertToU8('\u{100}');
// CHECK:STDOUT: --- success.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
@@ -25,6 +25,7 @@ let b: bool = Eq('a', 'b');
// CHECK:STDOUT: --- eq.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
// CHECK:STDOUT: %Eq.type: type = fn_type @Eq [concrete]
// CHECK:STDOUT: %Eq: %Eq.type = struct_value () [concrete]
@@ -25,6 +25,7 @@ let b: bool = Greater('a', 'b');
// CHECK:STDOUT: --- greater.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
// CHECK:STDOUT: %Greater.type: type = fn_type @Greater [concrete]
// CHECK:STDOUT: %Greater: %Greater.type = struct_value () [concrete]
@@ -26,6 +26,7 @@ let c: bool = GreaterEq('a', 'b');
// CHECK:STDOUT: --- greater_eq.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
// CHECK:STDOUT: %GreaterEq.type: type = fn_type @GreaterEq [concrete]
// CHECK:STDOUT: %GreaterEq: %GreaterEq.type = struct_value () [concrete]
@@ -25,6 +25,7 @@ let b: bool = Less('b', 'a');
// CHECK:STDOUT: --- less.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
// CHECK:STDOUT: %Less.type: type = fn_type @Less [concrete]
// CHECK:STDOUT: %Less: %Less.type = struct_value () [concrete]
@@ -26,6 +26,7 @@ let c: bool = LessEq('b', 'a');
// CHECK:STDOUT: --- less_eq.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
// CHECK:STDOUT: %LessEq.type: type = fn_type @LessEq [concrete]
// CHECK:STDOUT: %LessEq: %LessEq.type = struct_value () [concrete]
@@ -32,6 +32,7 @@ let not_8_bit: CharLiteral = '\u{1E15}';
// CHECK:STDOUT: --- use_types.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type Core.CharLiteral [concrete]
// CHECK:STDOUT: %ascii_x.patt: %pattern_type = value_binding_pattern ascii_x [concrete]
// CHECK:STDOUT: %.4ac: Core.CharLiteral = char_value U+0078 [concrete]

Some files were not shown because too many files have changed in this diff Show More