* Add `RequireCompleteFacetType` and `ResolveFacetTypeImplWitness` to
`check::Context`. Goal was to move code from `impl.cpp` (mostly) without
functional changes.
* Complete type information is cached with the facet type, and is stored
in a `complete_facet_types()` table.
* Main functional change is to diagnose attempts to use a rewrite
constraint on an associated function. Some existing diagnostics have
been updated.
* Remove `check::Context::RequireDefinedType`:
* For class types, use `RequireCompleteType`
* For facet types, use `RequireCompleteFacetType`
* Introduce a `SemIR::SpecificInterface` to hold an interface and
specific id pair.
* Keep the specific interface ids in the impl object.
* Avoid some extra copies in `Dump` functions.
* Future work missing from this PR:
* Resolving for member access or actions that require impl lookup.
* Resolving rewrites constraints that refer to non-concrete values.
* Any support for adding implied constraints that result from a `where`
clause (though TODOs have been added).
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Dana Jansens <danakj@orodu.net>
This allows iterating on all values in a store along with the Id for
each value, instead of `llvm::enumerate(store.array_ref())` which would
give you the indices.
While the indices are really the same as the Ids, this provides a
typesafe way to enumerate() over a store.
There's no use for this right now, but I thought I needed this, and it
helped me debug, and it was a pain to write correctly without dangling
references.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This adds support for choice types at a similar level to that of a C
enum, where each alternative has a name but no additional
data/parameters attached to it. We generate a TODO diagnostic if
parameters are specified.
Because there's no extra data, the storage is a simple unsigned integer
discriminant of the smallest possible size.
A choice without any alternatives is not constructible. A choice with a
single alternative is, and has an empty tuple in place of a discriminant
since it has only one state. The empty tuple is used to make the class
non-constructible. This can be improved.
Each alternative is turned into a let binding on the choice that is a
value of the choice with that alternative set as the active one in the
discriminant. This isn't possible to write in user code with a class
right now, since the let binding has the same type as the choice
(which is a class) it is within. It's possible to generate it in semir
however by adding the binding after the class is marked complete.
In order to have the name available for diagnostics, we now always set
`NameId` in `NameContext` and put `poisoning_loc_id` as part of the
union with `resolved_inst_id` instead (since we never need both).
Treat template bindings as introducing template phase, and propagate it
in the same way we propagate the checked generic phase.
Rename "symbolic" to "checked symbolic" to make room for "template
symbolic". Also rename "phase" to "dependence".
A value of type FacetAccessType can convert to a facet value of a target
FacetType if the value's underlying facet value's FacetType is
compatible.
A value of type FacetType can convert to another value of type FacetType
if the value's FacetType is compatible with the target FacetType.
During impl lookup, the comparison of the lookup type and the impl's
type needs to consider more than strict equality. If the impl's self
type is a FacetAccessType, we instead need to verify that the FacetType
of the lookup type and of the impl's self type are compatible (which is
like a problem of another impl lookup). For now we check that they are
equal by unwrapping the FacetAccessType to the constant facet value
within, and compare that with the lookup type.
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
I'm refactoring logic to try to make these files more manageable,
particularly as I'm looking at ways to use more threads. I'm renaming
FileTestBase::TestContext to TestFile and FileTestBase::TestFile to
TestFile::Split to try to be more consistent in how we talk about test
files and file splits in general. This change is not expected to change
any behavior, it's just refactoring.
This PR has two commits:
- Copying files for viewing deltas in GH
- Moving logic
The delta of the two commits is the main PR. The second commit can be
viewed on its own to see the delta versus file_test_base.* files where
the logic currently rests (there's still a reordering in run_test.cpp as
part of making one function static).
This should make it easy to add more tests which need the specific
behavior here. It also isolates where we reach into GoogleTest's
internals to a single common place.
This digs the Clang builtin headers out of the Clang package and
reconfigures them to install into our installation prefix, under the
LLVM installation subtree.
---------
Co-authored-by: Ilya Biryukov <ibiryukov@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
The language server is now able to subscribe to and apply incremental
changes to the document. Source code is assumed to be utf-8. It does not
currently handle utf-16 code points.
---------
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
- Add a better class comment.
- Remove the obsolete `type_ids_for_type_constants_` and `TypeNode`.
- For `bind_name_map`, fix declaration order and move comment to be
consistent with other members.
- Reorder accessors to better match order of data members.
- This is how I noticed `type_ids_for_type_constants_`
- Put a bigger notice so that `sem_ir` helper functions don't end up in
the middle of other members again.
Small cleanup for code sharing. Note, `*ReadFile` will trigger a
CHECK-failure on error; the relevant implementations would previously
have failed silently (empty string).
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Without this, diagnostics will linger after closing a file.
This refactors towards a pattern of putting outgoing calls as methods on
`Context`. I'm mixed on this, mainly thinking it's an improvement on
using `outgoing` directly (because it shares the name and structure),
might want to move it to a side-class later that is _only_ LSP wrappers.
I could also make inheritance private on OutgoingMessages and these
kinds of methods public there, but I'm hesitant to adopt that approach
versus a type separation.
Cycles are defined as reaching two independent lookups in a chain that
have all the same types involved. The acyclic rule states that this is
not possible and results in an error:
https://docs.carbon-lang.dev/docs/design/generics/details.html#acyclic-rule
To do this we need to track the types involved in impl lookup. The
interface constant includes the whole facet type being looked up, which
includes any specific types for generics or where constraints. Thus we
just need to compare the constant ids to look for this condition.
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Currently it returns false which just ends typechecking. Instead handle
the error state later and avoid firing overlapping diagnostics in
'extend impl as'.
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This in particular uses free functions because it's likely to end up
more consistent with types (versus a wrapper object for InstStore).
Note, this is unlikely to have a performance impact, but if it does, we
can look into related approaches (and we've already discussed using
LTO).
Renames `PendingBlock::AddInst` to `PendingBlock::Add` because
`MakeElementAccessInst` expects the matching name to exist.
When I open a .def file, there are often 4 errors:
- The #error
- The #define is not defined
- Missing `;`
- Identifier naming
This PR is meant to disable all of these, since they can be distracting
from fixable diagnostics.
rules_cc@0.1.0 was yanked from
[BCR](https://registry.bazel.build/modules/rules_cc) due to prematurely
removing cc_proto_library, this inconsistently causes the following
build error:
> ERROR: Error computing the main repository mapping: Yanked version
detected in your resolved dependency graph: rules_cc@0.1.0, for the
reason: rules_cc 0.1.0 is yanked due to incompatible change (prematurely
removing cc_proto_library from defs.bzl), please upgrade to 0.1.1.
Yanked versions may contain serious vulnerabilities and should not be
used. To fix this, use a bazel_dep on a newer version of this module. To
continue using this version, allow it using the --allow_yanked_versions
flag or the BZLMOD_ALLOW_YANKED_VERSIONS env variable.
This PR updates to 0.1.1 as recomended in warning and
[bazelbuild/rules_cc#268](https://github.com/bazelbuild/rules_cc/issues/268#issuecomment-2651269117).
This creates a new check/type.h for most logic, and also moves some
functions to TypeStore in sem_ir/type.h. My approach for TypeStore is to
focus on moving the read-only functions there.
This ensures the data is available for more uses (specifically for
diagnosing virtual/abstract/impl functions on non-instance methods).
It still doesn't quite address the TODO to move the Self param search
all the way back to the param walk in all cases. To do that in the case
that still has a separate search loop, I think we'd have to change
`Check::NameComponent` to carry this information (as it carries the
implicit_param_patterns-id) - though there's comments in NameComponent
suggesting it shouldn't carry function-specific things like
`call_params_id` and `return_slot_pattern_id` - so I wasn't sure if it
was suitable to add more there, but I can - possibly in a follow-up
change.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Change parse tree from `template (T:! type)` to `(template T):! type`,
so that we have information about whether a binding is a template
binding available when forming the representation of the binding
pattern. This incidentally fixes a bug that we would accept `template
addr A:! B` instead of the intended `addr template A:! B`.
Track whether a symbolic binding is a template binding on the
`EntityName` object. I'm borrowing a bit from the `CompileTimeBindIndex`
for this in order to avoid making `EntityName`s larger. Longer-term, we
should think about using a different representation for symbolic
bindings, to avoid including these fields in all `EntityName`s, but
that's out of scope for this change.
So far, template bindings are treated as having the same phase as
checked bindings, but that will change in a future PR.
To do this, we restructure the parse tree to make `forall` a leaf node
that comes before the parameter list.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
The explorer interpreter is still there, but it's non-default so it's a
little hard to link to (we could do a shortlink like
https://carbon.compiler-explorer.com/z/8P1WE97nn if you want to keep
that). As is, I assume it's okay to just state that this is now the
toolchain.
This adds a `SemIR::File` pointer to `scope_stack` so that
`GetCurrentScopeAs` doesn't require the argument, which would be why the
helper existed on `context`.
Note this mirrors parse_tree().packaging_decl().is_impl, but I'm
preferring to keep the version that doesn't access the parse tree so
that we could change tree storage without hurting as much.
Note this is building on #4927 which factors out RegionStack, because
this heavily uses the region stack. However, it's a more complex level
of logic that appears specific to pattern handling.
I've moved InsertHere to pattern_match.cpp because it appears to be in
specific use there.
If 'extend impl' is invalid, mark the impl as invalid by putting an
ErrorInst in the witness_id field.
The construction of the witness_id can otherwise return an ErrorInst but
impl lookup was not checking for that. Now have impl lookup check for an
error there before attempting to deduce generic parameters, which avoids
infinite recursion through deduction in cases like a cyclical impl of
itself.
Adds a testcase for infinite impl-of-itself lookup found by fuzzer.
The GetTypeIdForTypeConstant() and GetTypeIdForTypeInst() methods
convert from a type value to the type id of that value. The comments say
it can only be done for values of type `type` but it can be done for any
type value, which are either `TypeType` (aka `type`) or `FacetType`.
For example, for a `FacetValue` instruction as follows:
```
inst116: {kind: FacetValue, arg0: inst46, arg1: inst59, type: type(inst52)}
- type type(inst52): Generic(GenericParam); {kind: FacetType, arg0: facet_type2, type: type(TypeType)}
- value template_constant(inst117): {kind: FacetValue, arg0: inst46, arg1: inst59, type: type(inst52)}
```
The GetTypeIdForTypeInst() method will give the type id of the type
value (the type _in_ the FacetValue instruction) such as:
```
type(inst117): ImplsGeneric as Generic(GenericParam); {kind: FacetValue, arg0: inst46, arg1: inst59, type: type(inst52)}
```
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
When attempting to convert to a value of type FacetType, and the source
value is a FacetAccessType, then if the type of the underlying
FacetValue is the same as the target, we can use the FacetValue there as
the conversion output.
If the type of the FacetValue differs, then we still want to do impl
lookup with the FacetValue to see if it matches with the target
FacetType, but that is still a TODO.
This allows a generic function with a value whose type is constrained by
a FacetType (thus the value's type is a FacetAccessType), to call other
functions with the value as an argument when it is constrained by the
same FacetType:
```
fn F[T:! FacetType](x: T);
fn G[T:! FacetType](x: T) { F(x); }
```
It is also an optimization to avoid impl lookup where we've already done
it to produce the FacetAccessType.
Adds a bunch of new tests with values of types which are constrained by
a facet type (or "facet value value" for short), with some more tests
that currently fail and should be made to pass.