Adapts `StringLiteral` to lex characters. Adds a `CharLiteral` token,
which contains a `CharLiteralValue` which is a straight unicode code
point (suggested by zygoloid).
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
In order to verify rewrite constraints at the end of
`LookupImplWitness()` we need to replace references to associated
constants in the query facet type with values that come from the query's
self. To do this, we find any `ImplWitnessAccess` that is a reference to
`.Self` and replace its witness with the witness found through the impl
lookup process, if the interfaces match. This allows the
`ImplWitnessAccess` to resolve to a concrete value if that witness was
concrete. Then we just need to compare that for each rewrite constraint
the lhs and rhs are the same constant value. If they differ, the self
provided a different value for one side (either through its own facet
value constraints or through an associated impl), or the self did not
provide a value at all.
For now, only .Self references in the top-level facet type are
rewritten. Nested facet types are not, even if they contain a .Self
reference up to the top level facet value. This will be addressed by
adding numbering to the EntityName of of .Self in a BindSymbolicName.
See the third model in
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0
for the plan. For now, there is a TODO addressing this.
- A parameter binding can be marked `ref` instead of `var` or the
default. It will bind to reference argument expressions in the caller
and produces a reference expression in the callee.
- Unlike pointers, a `ref` binding can't be rebound to a different
object.
- This replaces `addr`, and is not restricted to the `self` parameter.
- A `ref` binding, like a value binding, can't be used in fields of
classes or structs.
- When calling functions, arguments to non-`self` `ref` parameters are
also marked with `ref`.
- The return of a function can optionally be marked `ref`, `val`, or
`var`. These control the category of the call expression invoking the
function, and how the return expression is returned.
- These may be mixed for functions returning tuple or struct forms.
- The address of a `ref` binding is `nocapture` and `noalias`.
- We mark parameters of a function that may be referenced by the return
value with `bound`.
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Iterate over arrays by producing their elements in the obvious way. We
use `i32` as the cursor type because that's the type that check converts
array indexes to. This may need revisiting if we support arrays with
more than 2Bi elements.
Also includes a fix for an import crash bug that's triggered by this
change, borrowed from #5873.
Instead of taking the complete text of the Clang diagnostic and using it
as the message portion of a Carbon diagnostic, generate the individual
pieces separately and pass them into the Carbon diagnostic
infrastructure.
* Clang's context lines are generated by running a custom "diagnostic
renderer" and tracking which lines it wants to print as context for a
given source location. When mapping from a C++ source location back to a
Carbon location, the Carbon `Loc` structure is now fully populated,
including filling in the context line and the column number.
* Clang's snippet is generated by running a custom diagnostic renderer
that is a cut-down version of the full text diagnostic renderer that
only prints a snippet. This is then attached to the Carbon diagnostic
manually as an override for the snippet we'd usually create.
We no longer repeat the file location twice on each diagnostic, and no
longer produce a bogus "in import" line for all locations coming from
clang that point arbitrarily to the first C++ import in the Carbon file.
The `[diagnostic kind]` marker is now displayed at the end of the
diagnostic message, not on a line of its own after the snippet.
When attempting to import a definition of a class with virtual bases,
diagnose the point of use instead of the point of definition of the
class.
---------
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
When importing a class definition, ask Clang to complete it first. This
causes class template specializations to get instantiated as needed when
the type-checking of Carbon requires a C++ class to be complete. It also
allows Clang to implement things like modules-aware definition
visibility checking.
Don't reject importing a class with a virtual base if it's never
required to be complete. Instead, defer diagnosing until the definition
is required.
This also removes the recursion from `MapType`, as mapping a class type
no longer maps its definition.
In order to get diagnostics from instantiation failures, fix a bug that
caused any Clang diagnostics produced after the initial building of the
`ASTUnit` to get discarded. This exposed some duplicate diagnostic
issues in `ImportNameFromCpp` which are fixed here too.
Previously we would drop these diagnostics; now periodically flush them
to Carbon's diagnostics emitter. We flush them at the end of checking,
and also immediately before changing the set of diagnostic annotation
scopes, so that Clang diagnostics get properly annotated.
This exposes some double diagnostics being produced in situations where
Clang's name lookup logic would produce a diagnostic and we also
produced one. For access control issues, use the Carbon diagnostic, in
order to properly handle protected access. For ambiguity issues, use the
Clang diagnostic that produces helpful notes.
Also fix rendering of note diagnostics produced by Clang, by attaching
them to the prior error / warning diagnostic.
---------
Co-authored-by: Boaz Brickner <brickner@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Per discussion at
https://github.com/carbon-language/carbon-lang/pull/5875#issuecomment-3137288037,
a different approach to the same solution.
A key difference is that whereas #5875 would build a `TypeStructure`
containing `ConcreteType{error}`, this instead just returns nothing.
This means impls with errors can't be compared in the same way, though
I'm not sure how much impact that'll really have (I've added a test here
to show a case where it seemed interesting to see what effect it'd have,
and it seems to have none).
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Also document why these are expected on `CARBON_KIND`. In
`kind_switch_test.cpp`, drop the `str` variable.
My recollection of the original discussion of `CARBON_KIND` is that it
should always have braces due to the risk of confusion for statement
interpretation, similar to a typical `if`/`else` but more subtle due to
the macro.
For example:
```
case CARBON_KIND(int n):
str << "int = " << n;
return str.TakeStr();
```
is equivalent to:
```
case CARBON_KIND(int n): {
str << "int = " << n;
}
return str.TakeStr();
```
This happens to work in context because `str` isn't scoped, but a
trivial refactoring to move `RawStringOstream str;` the first statement
of the `case` would probably have non-obvious results. For example:
```
case CARBON_KIND(int n):
RawStringOstream str; // Valid name shadowing, destructed without use.
str << "int = " << n; // Name lookup error on `n`.
return str.TakeStr();
```
Dropping this in with basic.carbon as an aspirational way to encourage
more tests there.
This currently crashes because `CollectCandidateImplsForQuery` tries
building a type structure which cannot contain `ErrorInst`.
A rewrite constraint like `.X = .Y.Z and .Y = .Self and .Z = ()` has a
nested `ImplWitnessAccess` `.Y.Z` (technically `(.Self.Y).Z`). The inner
access `.Self.Y` needs to be resolved (in this case to `.Self`) before
the outer `???.Z` can be resolved as `.Self.Z` which is `()`.
Dedupe rewrite constraints by consuming them by their LHS from the map
of rewrite values, and dropping any LHS that we see more than once. This
essentially uses the map to track which LHS we have seen in place of
sorting the rewrite constraints by the LHS.
Make Subst perform "recursion" on the RHS instructions as they are
replaced, effectively doing a depth-first traversal through the rewrite
constraints doing replacements. This allows us to fully compute
individual associated constants in the minimal amount of work, and cache
the results so they can be reused cheaply in cases where the rewrite
constraints generate an exponential number of references to associated
constants.
Fixes https://github.com/carbon-language/carbon-lang/issues/5672
In open discussion[1] we decided that "identical" rewrites would mean
that for a given LHS value, all RHS have the same value (after
evaluation), rather than requiring the RHS to all have the same
syntactic value. This means the following is valid, since the value of
`.Y` is known to be `()` while resolving the rewrite constraints of `T`.
So both rewrites of `.X` are resolved to `.X = ()`:
```
fn Identical(T:! I where .X = () and .X = .Y and .Y = ()) {}
```
The implementation of this clarification, along with test cases encoding
it, is done in https://github.com/carbon-language/carbon-lang/pull/5686.
Clarify this in the language design documents, and improve some other
clarity while we're there:
- The prose talks about a facet `T`, but the examples were using `A` as
its name. Change the facet to be `T`. This means changing the `.T`
associated constant (and `.U` and `.V`) to be `.X` (and `.Y` and `.Z`).
While doing this, use `I` for the interface name instead of `C`, which
we use more commonly for a class type name.
- Correct the comments in the cycle example that claim we find `.Y then
.Y* then .Y**`. In this example `.Y = .Z* and .Z = .Y*` which adds _two_
levels of pointers when evaluating `.Y`: `.Y => .Z* => (.Y*)* => .Y**`
[1]
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.qti4vn50zwy
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Otherwise these end up as unattached constants (see the baseline test
changes) and can't be resolved by `GetConstantValueInSpecific` in
lowering or in further derived vtables.
If the class is non-generic, then it's fine for the vtable entry for
some function inherited from a generic base is represented as an
unattached constant, since the specific in that specific_function is
already fully resolved.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
When using this with filesystem errors, a few issues came up that I'm
fixing here. They're small enough and near enough in code that it didn't
seem worth splitting part.
- It's nice to forward declare custom error types and an API using them
and then define both later. That doesn't work with `requires` but works
fine with `static_assert`, so go back to that pattern here. A test is
added that checks this pattern compiles.
- The `operator*` didn't support moving out of `ErrorOr`, which is
especially important when writing code that is happy with just
`CARBON_CHECK`-failing on any errors. For example, we have a lot of
filesystem code in tests that is made *much* more concise by just using
`*` on a function return and letting the built-in checking ensure no
errors were present. But when the value is move-only, this requires
special overloading. Add that and add a test with a move-only value.
- There wasn't an idiomatic way to do something like `operator*` for
`ErrorOr<Success, ...>`. This PR factors out the checking for `ok()`
into a `Check()` method that can be used to make code more readable that
is intentionally just verifying no error. Also makes the result of
`operator*` `[[nodiscard]]` to improve error messages and help void
accidental bugs.
- The `IsError` and `IsSuccess` test helpers required printable values
which isn't always realistic. Teach the printing logic to be conditional
on some indication of a printable value and gracefully fall back to a
generic string otherwise for testing output.
- The use of the `listener` in `IsError` and `IsSuccess` assumed a
non-null stream. Instead, streaming should go directly to the `listener`
as it is configured to only actually do the output when a stream is
installed. When a stream isn't installed, the previous code would crash
if the `MatchAndExplain` method ended up called without an 'interesting'
stream attached to the listener.
- When doing a `CARBON_CHECK` that there isn't an error, print the error
out as the check failure message. Without this, all the nice error
message work doesn't end up helping the debugging of test code that hits
these errors, etc.
The command is:
```
dump <context> [<ID>|<TYPE><ID>|<TYPE> <ID>|-- <ID>]
TYPE can be "inst", "entity_name", etc.
```
This saves a lot of typing of `SemIR::MakeInstId()` in a debugger, and
allows copy-pasting ids from dump output, as they take the form
`inst33`, etc.
Add a new type, `custom_layout_type`, representing a struct type whose
size, alignment, and field offsets can be manually controlled. Use this
as the object representation type for imported C++ class types (which
also includes struct and union types), allowing us to model C++ class
type layouts. In passing, also add support for incomplete C++ class
types, mapping them into incomplete Carbon class types.
Map C++ fields into Carbon field declarations, allowing direct access to
C++ fields from Carbon. So far, no support is added for base classes nor
anonymous struct or union declarations; those will be added in
subsequent PRs. Also, we don't map C++ access control into Carbon yet,
so all C++ fields are accessible regardless of their access control.
For now we still use a `struct_type` as the object representation for
empty C++ classes, in order to continue to support our existing tests
that convert `{}` to empty C++ class types. This is temporary and should
be removed once we support interop with C++ class initialization.
In trying to have types implicitly define `impl Self as Destroy`, I'm
wanting to use standard impl declaration support. For example, this
should produce more consistent errors if someone writes code that would
conflict with the generated impl. I'm also concerned, with the
complexity involved, that I'd get something wrong if I tried to write a
divergent implementation.
I'm only factoring out the start of the declaration. Right now the
finishing portion seems much simpler and lower risk to duplicate; I may
also factor it out separately. But either way, I think `StartImplDecl`
here is high churn risk due to its size (`CheckConstraintIsInterface` I
also expect to be used).
This is in anticipation of having `class` depending on the `Destroy`
interface, in order to automatically generate implementations of it.
I'm doing some sorting of imports in the prelude too, which I hope will
be uncontroversial; clang-format would do similar in C++...
This doesn't split apart the current error type into one that tracks
location and one that doesn't, although that might be easier to do once
we have this.
Instead, this is primarily intended to support custom error types that
lazily materialize the error message in case that can be avoided by
completely handling the error. For example, many file system operations
are *expected* to produce errors even in the hot path and we don't want
to render `ENOENT` (for example) to a pretty string and instead will
directly query the error to understand and handle it in code.
The type parameter ordering isn't the most obvious, but helpfully allows
us to default the error type in a useful way.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This is to make it easier to debug formatter issues. It means printing
can now result in things like:
```
<unexpected>.inst57.loc4_24: type = bind_symbolic_name ...
```
Where the "unexpected" reflects incorrect construction.
Expand support for `int` and `short` to cover all the other `intN_t` and
`uintN_t` types too. We achieve this by asking Clang what the `intN_t` /
`uintN_t` type that it would use for the given bitwidth is, and checking
if that's the type we're trying to map.