Commit Graph
23 Commits
Author SHA1 Message Date
Jon Ross-Perkins b5d28f2c4b location -> loc abbreviation (#3826) 2024-03-28 18:15:18 +00:00
Jon Ross-Perkins b079acd86f Replace NodeId with a hybrid LocationId in SemIR diagnostics. (#3810)
The purpose of this change is to allow something such as a FunctionDecl
instruction to note an imported instruction as the "loc_id". Note that
doesn't occur here: this change is already very sweeping in edits. There
is no testdata affected, intended to show equivalent behavior.

We might want to consolidate NodeId references towards LocationId, but
if that's preferred, I'd still like to split it out. A lot of this just
piping through LocationId where it's a build error otherwise, enough
that imports should be able to start using it for diagnostics.
ValueStores are added but still unused -- just flushing out structure
for review.

Restructuring SemIRLocation is necessary to use LocationId this way. For
TokenOnly, it's not getting used in Parse, so I migrated it to Check and
it's now specific to SemIRLocation.

I also considered making LocationId reference an InstId (which would
need to be an ImportRef) instead of an ImportIRInstId. However, that
would've required import.cpp to add instructions for decls which are
reached during resolution -- we typically don't have an inst ready for
use. An extra inst is essentially 16 bytes in InstId's ValueStore + 4
bytes in LocationId's ValueStore, whereas this is 8 bytes per.
2024-03-27 22:55:22 +00:00
Jon Ross-Perkins 8567e02aa7 Refactor handling of cross-package imports. (#3783)
This revamps the support for cross-package imports, making them look
more like a namespace. The planned model is mentioned on
[#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1217586076022210670).
This does not implement name lookup into the new namespace structure.

A few key changes in this PR (it's a little sprawling) are:

- Moves logic for adding package imports from context.* to import.*
- Remove SemIR::Import, which was the prior model. This is instead now a
SemIR::Namespace with the NameScope getting a new import_ir_scopes
field.
- Allow SemIR::Namespace to use Parse::ImportDirectiveId in addition to
the prior Parse::NamespaceId
- The import_ir_scopes field includes a NameScopeId so that as we
traverse to child namespaces, we can directly perform name lookup in the
other IR.
- is_closed_import now tracks whether a namespace comes from a different
package. This has a diagnostic implemented in decl_name_stack.
2024-03-14 22:03:30 +00:00
Jon Ross-Perkins 86a7c9ff45 Rename parse_node -> node_id (#3760)
This was previously discussed at
https://discord.com/channels/655572317891461132/655578254970716160/1209975051588210729.
I'm initiating this mainly because we typically use "id" suffixes to
indicate an `IdBase` being passed around and the non-id suffix of
`parse_node` suggests at it carrying more data than it actually does.
There used to be more reason for avoiding `node_id` because
`SemIR::InstId` used to be named `NodeId`, but that's no longer
necessary. As a consequence, I'd like to rename `parse_node` to more
precisely reflect its type.

In full, this is doing:

```
parse_node_kind -> node_kind
parse_node -> node_id
ParseNodeCategory -> NodeCategory
ParseNodeKind -> NodeKind
ParseNode -> NodeId
```

This is primarily in check and sem_ir, but with some `parse_node_kind`
references in parse too.

Pluralization is consistent with name forms on both sides, so that
wasn't part of my replacements.
2024-03-09 00:21:29 +00:00
Richard Smith 90369815ad Support for name lookup into interfaces. (#3729)
Follow the existing support for classes.

None of this is especially useful until other features land: we don't
yet have any use for defining methods of an interface out of line,
because we don't support `default` or `final` interface methods, and we
don't have impl lookup, so referring to an interface member is also not
especially useful. But this is a nice piece to factor out that's a
prerequisite for effectively testing other interface features.
2024-02-27 21:28:46 +00:00
Jon Ross-Perkins 4ab42c0712 Fix for MakeUnqualifiedName conflicting with a namespace (#3707)
Unqualified names don't handle scopes the way that typical names do, so
a name conflict with a namespace needs to be handled specially. I'm
still favoring keeping code close as much as possible, particularly
since long-term this syntax will probably shift to be more consistent.
For now I'm just flagging when we shouldn't push scopes, so that
MakeUnqualifiedName doesn't need to clean up.

Note, a different approach would basically be:

```
PushScopeAndStartName
ApplyNameQualifierTo
result = decl_name_stack_.back();
decl_name_stack_.back().state = NameContext::State::Finished;
PopScope
return result;
```

But that approach feels worse to me, due to the additional stack
manipulations and the need to duplicate some of the FinishName logic
just to be able to pop the scope that didn't really need to be added.
2024-02-20 18:43:57 +00:00
Jon Ross-Perkins 1bf4dc53d9 Add diagnostic support so that we can just pass in TypeId. (#3695)
Note we may also want to do this with NameId, maybe some other things,
but the TypeId use is pretty broad and repetitive -- I thought I'd start
with it first.
2024-02-09 16:25:23 +00:00
Richard Smith 5ab26072fd Use the DeclNameStack for impl declarations. (#3691)
They don't have names, but using the DeclNameStack anyway keeps our
behavior more consistent, and keeps track of the enclosing name scope
and the prior state of the scope stack for us.

Depends on #3683.
2024-02-06 22:28:31 +00:00
Richard Smith fdfb1fb5ef Factor the scope stack and lexical lookups out of Check::Context. (#3688) 2024-02-06 00:59:52 +00:00
Richard Smith 44fca1669a Keep parameters in scope throughout the entity that they parameterize. (#3671)
Previously, we created scopes for implicit parameter lists and tuple
patterns, but that meant that bindings went out of scope too soon. We
now keep them in scope until the end of the enclosing declaration. This
is accomplished by pushing a scope for parameters when we handle a name
that might have them, and then popping the scope again if it turns out
that there were no parameters.

For a case such as:

```carbon
fn A(T:! type).B(U:! type).F(x: T, y: U) {
  var z: T;
}
```

... we now have the following scopes in the stack:

-   A parameter scope containing `T`.
-   A class scope for `A(T:! type)`.
-   A parameter scope containing `U`.
-   A class scope for `A(T:! type).B(U:! type)`.
-   A parameter scope containing `x: T` and `y: U`.
-   A function body scope containing `z: T`.

The innermost scope when check processes a declaration of a function,
class, or similar is now often a parameter scope rather than the
enclosing scope in which the class or function is declared, so the
target scope is now passed explicitly into the modifier checking code
that wants to inspect that enclosing scope.
2024-01-31 21:40:45 +00:00
Jon Ross-Perkins f4a741903f Add import support for remaining decl types. (#3651)
I'd excluded these initially just because I was thinking towards copies,
but under the current model I'm trying to catch all the decl types just
for consistency. Note references will still be a TODO error
(LazyImportRef is already tested for this, it just didn't feel necessary
to add individual tests while I try to sort out behavior).

Fixes an oversight where declarations in an entity's scope were being
added to the list of exports.

Note I'm trimming some Import API arguments as now-unused.
2024-01-25 18:19:22 +00:00
Jon Ross-Perkins d0fb4b5815 Change DiagnoseDuplicateName to expect an inst ID for the duplicate. (#3616)
This makes duplicate and previous definition handling match. While we
may want to make both point more fine-grained at the name, the necessary
logic seems likely to be equivalent.

Note, I'm looking at this mainly due to duplicate names in imports,
where it's especially helpful to take an instruction instead of a parse
node. We'll eventually want to handle parse nodes from other imports
better, and I think this is the way it would most likely work.
2024-01-18 23:23:31 +00:00
Jon Ross-Perkins 5d0465d43c Adjust a few Invalid comparisons to use is_valid (#3583)
Deliberately not touching the case that came up from #3575
2024-01-10 00:21:27 +00:00
Jon Ross-Perkins b6ffe0197b Implement a list of exported names for imports. (#3552)
This adds a block for exported InstIds, rather than scanning the package
scope. This working down a path discussed last month, which we'll need
to add enclosing namespaces to the Inst in order to complete import of
something like `namespace NS; var NS.a;`

Exports could've been a separate `vector<InstId>` on `SemIR::File`, but
using an entry in `inst_blocks` felt more consistent.
2024-01-02 22:17:27 +00:00
josh11b 29104e212a Do TODO to rename QualifiedDecl -> QualifiedName (#3543)
Renaming since the parse node does not represent a declaration.
2023-12-26 23:12:28 +00:00
Jon Ross-Perkins 3d661c96f3 Handle out-of-line declarations. (#3536)
By adding an InstId to the NameScope, we can determine whether the
declaration is being added to a scoped entity (versus a namespace).

The choice of InstId on NameScope is chosen versus other solutions
because, for imports, we want to just have a list of InstIds to import
and, from those, get the containing namespaces for addition. Similar may
also be desirable for printing fully qualified names given a singular
InstId. That means an InstId must have a path to find enclosing name
scopes.

What we're looking at here is:

- NameScopeId knows its InstId. (done here)
- Inst knows the enclosing NameScopeId. (future work)
- To walk up enclosing scopes for an Inst:
  1. Fetch the Inst.
2. Find its enclosing NameScopeId (which will be per-declaration due to
Function etc complexity).
  3. Fetch the NameScope if not Package scope. (if Package scope, done)
  4. Use the InstId on the NameScope to go back to step 1.
2023-12-21 18:36:33 +00:00
Richard Smith 0a1abe9f64 Clean up some uses of the node stack. (#3512)
Also minor cleanups for the stack itself.
2023-12-14 20:57:03 +00:00
Richard SmithandJon Ross-Perkins de0c02ddae If a name is not found in a class, perform lookup into base classes. (#3502)
This builds out a little infrastructure for one name scope to `extend`
another. We'll need more refinement here to cover other cases, but this
should provide some foundation for that future work.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-14 19:51:55 +00:00
Jon Ross-Perkins 032c0e017b Start adding lazy import references to name lookup. (#3475)
Adds a `LazyImportRef` instruction. Versus `CrossRef`, this is intended
to represent an instruction which cannot be used directly, and must be
replaced when it comes up due to name lookup. The intent is to use this
to avoid recursive loading of imported IR instructions.

Note, under this model, when `ResolveIfLazyImportRef` is called, it
essentially needs to load both inst and type information to a sufficient
point where any further attempts would hit name lookup again. That will
probably be complex, and the current implementation is just touching the
surface of the issue. I was heading down this route because it would
mean we have a limited number of points that need to consider whether
they're going to talk about a `LazyImportRef`.

I'm considering whether `CrossRef` should be dropped in favor of more
specific `Builtin` special-casing, due to the divergence of desired
behaviors. This could mean dropping the `builtins` IR since it's not
looking useful right now.

Modify `NameScope` to track whether the scope is associated with a load
error. This is to handle cases where one or more imports failed, so we
do not want to issue warnings for related scopes.

The 0-size on `ValueStore` comes up due to the changes to `NameScope`,
which make it too large for the default handling. After discussion with
zygoloid, the thought was we might want to try reserving a roughly
correct value based on parse node counts, but the stack default wasn't
buying much.

Fixes a bug where the implicit import used the package name instead of
the invalid identifier.
2023-12-12 00:13:25 +00:00
Richard Smith 22dff46ed2 Remove support for disambiguating a stringified type as being a type. (#3456)
Most of the calls to `StringifyType` already passed `true` for
`in_type_context`. Checking the rest, I found that every one of them was
already sufficiently clear that they were printing a type, or could be
made so with a very small change to the diagnostic text.
2023-12-05 17:34:04 +00:00
Richard Smith 7dffa0c7ec Support for base: T;, .base, x.base. (#3450)
No support for `extend base` yet, in an effort to minimize collisions
with #3412.
2023-12-04 22:45:59 +00:00
Richard Smith 332a368cee Rename Parse::Node -> Parse::NodeId. (#3432)
As discussed [on
discord](https://discord.com/channels/655572317891461132/655578254970716160/1178878128714678282)
and today's toolchain discussion.
2023-11-29 18:53:12 +00:00
josh11b 109e7889dd Rename files to use abbreviations (#3389)
Reflects these recent PRs:
* #3375 
* #3382
2023-11-11 00:25:40 +00:00