This enables us to stop using `Env` in the typechecker. As a byproduct, this commit also restructures the interpreter to handle run-time global initialization as part of ordinary execution, using the Action stack.
As a byproduct, replace NamedEntity with a type-erasing wrapper NamedEntityView, eliminate virtual inheritance from the AST, and eliminate interfaces from gen_rtti.
This doesn't actually use the results of name resolution, but it does verify that they are present.
Also ensures that name resolution and type checking are applied to deduced function parameters and the implicit call to `Main()`.
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
- Rename `PointerValue` to `LValue` to reflect how it's actually used. We can introduce a `PointerValue` type when we add support for actual pointer values.
- Remove support for pattern assignment. It's unclear if Carbon will support this, and even if we do, it raises questions that should first be addressed in a language proposal, like "is the left-hand side of `(x, y) = (1, 2)` an lvalue, or a pattern, or both, or something else entirely?"
This enables us to stop treating the return type as a Pattern (which is really isn't), treat return types more consistently with other static types in the typechecker, and drop ReturnTypeContext.
Additional changes:
- Merge TypeCheckFunDef with TypeOfFunDef.
- Handle implicit conversions in `return` statements.
- Require function type literals to have an explicit `->`.
- Move consistency check for omitted returns from TypeChecker to ResolveControlFlow.
#939 switch to `Main`, but #919 predated it and didn't get updated
before merging. Its tests passed on the PR branch as a consequence, but
failed when landed.
This just updates the test cases. Trivial fix forward.
This starts detecting naming collisions as a consequence of being able to determine when the name is declared twice in a given scope.
Co-authored-by: Geoff Romer <gromer@google.com>
The `__Fn` naming is intended to mirror things like `__Continuation`.
The reason for this path is because it's not clear this is the form we'll want, and I think experimental naming will help reflect that.
This was born out of wanting FunctionDeclaration to explicitly have a Block for a body, and became a bit more of specifying types around. Note this forces exec_program to generate a Block for print()'s body, which is probably more correct as now we can expect a standard FunctionDeclaration AST structure, even for the built-ins.
There is a syntactic change here: a continuation's body is now a Block, not just a Statement. I've added an example disallowed test case. I think this is more reasonable syntax.
Other than that, note that optional_else now generates a valid Block. This has me thinking about whether we can eliminate Sequence, but that seemed well out of scope for this.
Rationale: Based on the status of #478 and #505, Carbon won't have this feature for a while, and it will be simpler not to support it on spec in the meantime.
I should emphasize that I am **completely cheating** here. This PR does not add support for actually _performing_ implicit conversions at run time, because the AST doesn't yet contain the necessary type information. At run time, code like `var p: Point = {.x = 1, .y = 2};` directly initializes the name `p` with the _struct_ value `{.x = 1, .y = 2}`; no object of type `Point` is actually created. I'm only getting away with this because we don't yet have any tests that can tell the difference.
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
Prior to this change, `__await` would make a deep copy of the continuation stack, but shallow-copy the individual stack frames within it. As a result, continuations appeared to have shallow semantics so long as the continuation stack had only a single frame.
This change also removes an obsolete test from the brief period when we intended continuations to have deep-copy semantics, which has been passing basically by accident.
This implements #826, I think covering everything important there.
Regarding ReturnTypeContext, I broke that out because it started feeling like a significant number of args to be passing around, and I think this makes the association inside type checking clearer.
Co-authored-by: Geoff Romer <gromer@google.com>
There's a small update to update_checks.py to handle the recursive directories. Also, I'm only using one level of nesting in this PR but really no reason we can't do more. I'm just not sure what clustering is best right now.
As a pattern, I'm trying to name all failing tests `fail_*.carbon`.
Doesn't add much logic, only takes advantage of parser structure for the ordering enforcement.
Note import_nonexistent tests should probably fail, but writing import tests needs a chain of functionality, and I figured I'd just start adding some to validate the syntax (not adding existent imports because that'd require multi-file structure).
This is based on discussion on #732: that we should probably parse the invalid whitespace, then reject it as part of string validation, rather than having different parses. I worry the question of "how is this parsed" may lead to subtly unexpected results if we aren't consistent, so I'm switching the logic from the lexer to the unescape library (and also adjusting the list of rejected whitespace).
Related to discussion on #738, but also trying to standardize handling of everything and make placement of token spellings (`AND "and"`) consistently in lexer.lpp.
I could have gone the other direction, removing the list of things in lexer.lpp, but this feels like it does more to use the compiler to detect skew between lexer.lpp and parser.ypp.
It was in my mind to add String in order to support libraries in `package`. `print` is added in order to have a String go to stdout. I've tried to do `print` in a way that won't be too hard to add other printable types, but it's probably also somewhat optional here -- that is, if desired, I could remove it. But it was a lot easier to doublecheck `\n` behavior with it, and I suspect it'll be helpful in other tests if it supports more value types.
On the side, this also fixes dereferencing in Pattern/Expression Print() calls, which I was noticing printing pointers instead of values. This may be another argument for moving away from passing pointers, since this seems to be a difficult-to-catch error.
Co-authored-by: Geoff Romer <gromer@google.com>
This creates a ReturnExpression. A separate change should enforce that an implicit return of `()` is only allowed in functions that have an implicit return type of `()`, and I think the structure taken here should ease that.
`Pattern` is intended to pilot some changes I would like to apply to all our sum types:
- The alternatives are expressed as derived classes rather than members of a `std::variant`.
- The alternatives are classes in the [style guide sense](https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes), meaning they can have invariants, but can't have public data members.
- Creating an object is expressed using a constructor rather than a factory function.
- Accessing an alternative is expressed as a cast (using LLVM's RTTI system) rather than `std::get` or a `Get` method.
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This is intended to:
- Standardize use of line_num (and highlight where no line_num is available).
- Standardize indications of runtime/compilation errors.
- Make it incrementally easier to write new errors.
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>