Commit Graph
170 Commits
Author SHA1 Message Date
Adrien Leravat 8cb3f00f1b Explorer: fix assignment error typo (#2746)
Fix typo in error message from expression categories renaming
2023-04-06 16:48:51 -07:00
Adrien Leravat d0645c6a85 Explorer: rename value categories to expression categories (#2744)
Rename value categories to expression categories based on [Discord discussion](https://discord.com/channels/655572317891461132/753021843459538996/1092924035517665332) regarding naming and behavior.

>* let expression -> value expression
>* var expression -> reference expression
>* located expression -> initializing expression
>So:
>- "value expressions" produce values (with no associated location). "reference expressions" produce a location of an existing value. "initializing expressions" take a location and initialize it.
>- A let binding is initialized by a value expression, because lets represent values (with category conversions performed as needed, but if a conversion is performed from a different category of expression, the value of the object is pinned for the lifetime of the let).
>- A var binding is initialized by an initializing expression, without performing a copy (with category conversions performed as needed, calling a copy constructor if the initializer is a different expression category).
>- The & operator requires a reference expression, and it's an error to give it other kinds.
>- The left-hand side of . requires a value expression when calling a function with a non-addr receiver, and requires a reference expression when calling a function with an addr receiver (it's an error to give it a value expression, and for an initializing expression, a temporary is materialized).

Changes
* Rename "value category" to "expression category"
* Rename Var and Let value categories to Value, Reference, and Initializing expression
* Rename `lvalue` to `location` (most of the time)
2023-04-05 16:16:10 -07:00
Amr Hesham 29cdeb0d6b Explorer: Fuzzer issue around divide-by-zero (#2735)
fail with a runtime error, preventing the divide-by-zero from actually running.

Issue #2731
2023-03-31 20:53:26 -07:00
josh11bandGeoff Romer 46503c0a9d Explorer and toolchain changes to implement #2483 (#2707)
This PR is making two main changes to the Explorer and Toolchain:
- Replace the `is` keyword in `where SomeType is SomeInterface` with `impls`, so it is `where SomeType impls SomeInterface`
- Rewrite uses of the "impls" to something else to avoid, frequently "`impl` declarations" or "implementations", to avoid confusion with the `impls` keyword.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2023-03-28 12:28:52 -07:00
Richard Smith e0c90767be Support for templated impl declarations (#2700)
The strategy that we use for now to support template instantiation is to check the impl declaration as if it were a generic, but to defer all checking of the impl definition until we see a use in which all template parameters have arguments. At that point, we clone the impl definition and type-check the whole thing, with constant values set on the template parameters corresponding to the given arguments.

No caching of template instantiations is performed yet; each time we form a reference to a template instantiation, we instantiate it afresh. We also don't implement the name lookup rule from #949 yet; lookups during template instantiation look only in the actual type and not in the constraint.

Depends on #2699
2023-03-22 14:19:02 -07:00
Adrien Leravat df289efac4 Explorer: Add virtual destructor support (#2695)
### Features

* Add virtual `destructor`s support (Closes #2521)
* Check virtual override for virtual destructors
* Error if attempting to `Delete` a class that does not have virtual destructors from a base class pointer 

### Implementation

* Update parser to support virtual override introducers for destructors
* Check virtual override for class destructor and add to class vtable if necessary
* Add corresponding tests

### Notes

Contrary to initial implementation, this implementation leverages the `Address` structure and implements a new `Address::DowncastedAddress()` method to get address from child most class from a base class address. This avoids the need to use `GetAllocationId` and its issues when it comes to having multiple values for an `AllocationId`.

### Next work

Following this PR, we need to:

* Check when using `Delete` that the class was allocated with `New` (WIP)
* Drop the old `GetAllocationId(Value*)` in favor of a better system (WIP)
2023-03-22 09:58:30 -07:00
Richard SmithandJon Ross-Perkins 28946d4b87 Order impl matching by type structure (#2691)
As described in [the generics design](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/generics/details.md#type-structure-of-an-impl-declaration), `impl` declarations are prioritized by type structure. Given two `impl` declarations that match a `type as interface` query, the one that describes the longest prefix of the query without using placeholders is preferred.

We implement this by putting all impls in a total order, first by type structure equivalence classes and then by lexical order. When matching an impl, we walk this total order, and stop once we find a match and reach the end of its equivalence class.

Equivalence classes are determined by finding the locations of the "holes" (the positions where deduced parameters appear) within the type structure, viewed as a tree. Two impls are in the same equivalence class if their holes are in the same place, and equivalence classes are ordered based on a reverse lexicographical ordering of their holes.

Explorer doesn't keep the `Bindings` list for a parameterized type in any particular order, but the type structure rule requires that we consider them in lexical order. In order to support this, we now track an index on the declared parameters of each generic. This is a simple numbering of enclosing generic parameters, both on that generic and on all lexically enclosing generics.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-03-17 16:50:06 -07:00
Richard SmithandJon Ross-Perkins 5b6873d147 Fix handling of choice types with a mixture of alternatives with parameters and alternatives without parameters in pattern analysis. (#2626)
This case previously caused a crash.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-03-07 17:09:40 -08:00
Richard Smith c8141b59d9 Remove ExpectType and some calls to IsImplicitlyConvertible. (#2647)
These functions are dangerous, as they check whether conversions are possible without actually performing the conversions. In each case where they were used, explorer would crash in some cases if a user-defined conversion is required.

This change moves us more towards implicit conversions being handled by a regular function call on an interface and away from them being magical builtins. Unfortunately, this exposes a pre-existing bug that a call of the form `x.(ImplicitAs(T).Convert)()` compiles even if `x` only has an explicit conversion to `T`. That's worked around here for now, but will need a proper fix later.
2023-03-02 14:04:44 -08:00
Richard Smith 7fe06a5d2f Unify handling of calls to functions and to methods. (#2620)
This fixes some bugs in each, where the fixes had only been made on one
side of the switch or the other. Also don't forget to instantiate
deduced generic arguments in a call when we read them out of the AST.
2023-02-22 13:51:25 -08:00
Jon Ross-PerkinsandRichard Smith 9df70fb115 Disable most tracing in the prelude. (#2616)
This is intended to address currently flaky timeouts that are likely caused by the size of the prelude. I'm addressing a performance bottleneck in AnalyzeProgram with trace output. Trying to omit prelude traces reduces most trace output significantly,  and I think it'll scale better as the prelude size increases.

The basic mechanics here are:

- In order to consistently track whether tracing is on, I've added a TraceStream class, explorer/interpreter/trace_stream.h.
- The AST now has a num_prelude_declarations field, so that it's provided where the boundary is.
- In order to mark where we try to skip prelude output, I've added calls to set_in_prelude in type_checker.
- In exec_program, I just use num_prelude_declarations directly to skip over.
- Everywhere checks TraceStream::is_enabled before printing, similar to the std::optional check that was previously used.

This does add some timing output in order to better diagnose where slowness is coming from, when tracing. It also adds "verbose" targets to make it easier to get the trace output.

So for example, here's a timing for zero.carbon:

```
Timings:
- Parse: 13ms
- AddPrelude: 25ms
- AnalyzeProgram: 116ms
- ExecProgram: 12ms
```

If I make a small change to just not set skipping_prelude (essentially getting back to current output):

```
- Parse: 13ms
- AddPrelude: 25ms
- AnalyzeProgram: 2359ms
- ExecProgram: 57ms
```

Thus in this trivial example, I'm eliminating about 95% of the execution time.

Note this approach could still be refined in a few ways:

- We could add a flag to allow overriding in_prelude. It should be a small amount of work after this change. But it's a little consistent with how parser_debug works, that it won't print prelude output by default (unless there's an error).
- Execution could skip messages involving initialization of globals declared in the prelude. This is a little noisy right now, but I don't think it's significant for performance because ExecProgram is tiny.
- Once files are more separated, we should be able to change the num_prelude_declarations/set_in_prelude approach.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-02-22 13:41:12 -08:00
Richard Smith 4b2254a61f Fix some comments after #2612. (#2614) 2023-02-21 09:58:31 -08:00
Jon Ross-PerkinsandRichard Smith 73869e9438 Modify lit_autoupdate so that it can handle errors in prelude.carbon (#2612)
The intent here is that changes to prelude.carbon shouldn't break every test that expects some error from prelude.carbon; that would be too fragile. As a consequence, this effectively ignores the line number in prelude.carbon.

This is a little complex because we don't know which line in the original source file is actually causing the error, just that there is an error. Also, the previous look-behind approach required a fixed-with prefix, whereas we want a little more than that in order to capture the filename for comparison.

This would be hard to do with extra_check_replacement because the path to bazel.runfiles is complex to calculate. As a consequence, this is basically all new code.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-02-17 09:31:48 -08:00
Richard Smith 81532c8918 Fix mishandling of struct and tuple types in impl matching termination check. (#2609)
Both cases need a label for each level of struct and tuple type appearing in the impl query, because we can have an unbounded number of such levels with the types otherwise being the same.

Prior to this, both added testcases exhibit unbounded recursion.
2023-02-15 15:10:01 -08:00
Richard Smith 0e41c569b1 Implement the termination algorithm for impl selection described in #2458 (#2602)
Detect when evaluating an impl recursively tries to evaluate the same impl for the same or a more complex set of parameters.

In order to perform the check after we have tested that the type structure matches and before we check that constraints are recursively satisfied, argument deduction is extended to check structural matching properties earlier.

This requires us to separate match failures into two kinds: hard failures that produce errors that should never be swallowed, and soft failures such as a missing impl that lead us to merely discard an impl as a candidate. A flag has been added to `ImplScope` and `ArgumentDeduction` to specify whether soft failures should produce an error message or not.
2023-02-14 17:44:16 -08:00
Richard Smith 59ff7743c0 Expect parentheses after an alternative only if they were present in its declaration (#2605)
The design of choice types expects the declaration of an alternative to match the usage: if an alternative is declared as `None`, then it should be used as `None` not `None()`, and if it is declared as `None()` then it should be used as `None()` not `None`. Update explorer to match.

Also clean up the handling of choice types and alternative values a little in general, by moving away from identifying choice types and alternatives as strings and towards identifying them symbolically.

Closes #2422
2023-02-14 13:28:52 -08:00
Amr Hesham 98041d70c2 Explorer: error on bit-shift overflow (#2600)
Return Integer overflow Runtime error for bit shift if The second operand is less than zero or bigger than or equal bit width of the first operand in this case (32 bit for int)

Issue #2595
2023-02-13 08:01:24 -08:00
Adrien Leravat 266fa401e6 Explorer: assert Optional not empty on Get() (#2587)
Prevent from unwrapping an empty Optional
2023-02-09 22:39:43 -08:00
Richard Smith 4fa71e32f5 Add support for most kinds of declarations to be declared and used as namespace members (#2575)
Support for global variables is still missing; they're a bit more tricky because they use a pattern to introduce their name.

Prior to this change, explorer heavily relied on name comparisons to determine whether two declarations declare the same entity. Some of those instances are fixed in this PR, but more remain to be fixed, and some TODOs are added for some harder-to-fix instances.
2023-02-08 13:21:15 -08:00
Adrien Leravat 65078ea943 Explorer: make use of != in Carbon lit (#2586)
Swap `not (a == b)` for `a != b` in test now that we have it.
2023-02-07 10:10:45 -08:00
Richard Smith 1a8a41a5a6 Improve diagnostic for unknown name in name qualifier. (#2579)
As requested in #2572.
2023-02-03 16:05:08 -08:00
Richard Smith 6d4920148b Initial support for name lookup into namespaces. (#2572)
Name lookup into namespaces needs to be resolved early, as part of name resolution, so that we can properly diagnose references to entities before they are fully declared.  Make name resolution set a target `value_node` on simple member accesses that name namespace members, and in type-checking rewrite those member accesses into `IdentifierExpression`s that directly reference the namespace member.
2023-02-03 12:58:38 -08:00
Richard SmithandJon Ross-Perkins c172487395 Support for declaring functions within a namespace (#2569)
First step towards permitting declarations within namespaces. Supports only functions within namespaces for now, with no way to call those functions except from within other such functions. Unqualified lookups within a function in a namespace look in that namespace first.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-02-02 14:11:03 -08:00
Richard Smith 60af531f5b Support parsing namespace declarations (#2563)
Initial support for parsing namespace declarations and referring to namespace names. No support for declaring members of namespaces yet.
2023-01-30 17:25:44 -08:00
Adrien Leravat b4e3a3e6cc Explorer: fix class destructor not called with heap.Delete (#2546)
This change ensures that DestroyAction is executed for the value being deallocated when calling heap.Delete.

Relates to #2521
2023-01-24 11:34:47 -05:00
Adrien Leravat ec683d1ab2 Explorer: fix variables not cleaned up if declared before unformed (#2544)
Fix variables not being properly cleaned up if declared before an unformed variable.

### Details

Currently the following example / test
```
package ExplorerTest api;

class A {
  var i: i32;
  destructor[self: Self] {
    Print("Destructor A {0}", self.i);
  }
}

fn Main() -> i32 {
  var a0: A;
  var a1: A = {.i = 1};
  var a2: A;
  var a3: A = {.i = 3};
  return 0;
}
```

prints
```
Destructor A 3
```

instead of 

```
Destructor A 3
Destructor A 1
```

This PR fixes the issue in the `CleanUp` logic.
2023-01-23 08:59:14 -08:00
Richard Smith 2fd7e2b65d Add support for compound assignment and increment (#2526)
Add support for user-defined assignment, as well as compound assignment and increment, following the design direction in pending proposal #2511.

Some of this isn't fully testable yet: because explorer doesn't properly support `impl` specialization, the blanket `impl`s in the prelude prevent types from customizing assignment.
2023-01-20 18:48:13 -08:00
Richard Smith c8f18446f4 Support explicit conversion of tuples. (#2537)
Allow explicit conversion from a tuple of `T1`, `T2`, ... to a tuple of `U1`, `U2`, ... if each element has an explicit conversion.

Also add a comment to existing `ImplicitAs` impl for tuples explaining its purpose.
2023-01-19 14:56:01 -08:00
Richard SmithandJon Ross-Perkins 0d279b388a Make built-in conversions visible to ImplicitAs. (#2525)
Add a blanket `ImplicitAs` implementation to perform the conversions that explorer can perform as built-in conversions. This allows those conversions to be detected by constraints and to be used as part of other user-defined conversions. For now, a single monolithic conversion is exposed. I intend to split this up into multiple smaller conversion kinds for each kind of conversion in a follow-up change.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-01-18 17:36:55 -08:00
Richard Smith 74aae0911f Basic support for match_first declarations. (#2523)
Add basic support for `match_first` declarations to explorer, as described in https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/generics/details.md#prioritization-rule. The concrete syntax here is not yet approved, so `match_first` is renamed to `__match_first` for now, but the semantics are necessary to implement other approved features in explorer so we're intentionally getting a little ahead of the design here.
2023-01-17 13:08:38 -08:00
Carson Radtke 08a289753c [explorer] clarify warning when declaring arguments for 'Main' (#2518)
Improves the error produced when 'Main' is declared with parameters. Resolves a TODO in the typechecker. Explorer only. 

PR also adds a test for this error message.
2023-01-10 19:24:35 -08:00
Carson Radtke 0af5c55f55 Fix typo in extended final class error message (#2516)
added the word "be" and updated test result.
2023-01-05 11:01:32 -08:00
Priyananda Shenoy c87d271c53 Issue #2121: Support new block string literal syntax in explorer (#2399) 2023-01-04 15:53:47 -08:00
Richard Smith 4daaa4866f Rename Type -> type, per #2360. (#2507)
Also make minor updates to the skeletal design in
docs/design/name_lookup.md following #2113, as there are no longer any prelude names that are made available to unqualified name lookup by default.

Add `type` to the keyword list in
docs/design/lexical_conventions/words.md, following #2360.
2023-01-04 14:22:30 -08:00
Adrien Leravat 798a40c886 Basic support for impl virtual override keyword (#2493)
Features:
* Add basic support for `impl` virtual methods (override virtual method)
* Error on invalid declaration for `impl` and `virtual`, covering simple use cases
* Add `abstract` fn parser-only support

Changes:
* Modify parser to handle new function specifiers, resolve conflicts
    * Group `virtual_override` and `FN`, and group `impl_kind` and `IMPL` to avoid ambiguities with around `impl` token parsing
* Add new `VirtualOverride` enum for function declarations, and matching `virt_override() -> VirtualOverride` getter
* Update function declaration logic

Depends on #2462
2023-01-04 11:09:23 -08:00
Adrien Leravat 8301258ef8 Explorer: support virtual class methods (#2462)
Features:
* Add `virtual` virtual override keyword for functions
* Support `virtual` class methods using dynamic dispatch

Changes:
* Add `vtable` in `NominalClassType`, 
* Add `NominalClassValue**` in class values pointing to  descendant-most class
* Resolve virtual methods during member lookup

Limitations:
* Does not include yet `impl`, `abstract` virtual override keywords, or the complete logic for virtual function declaration

Depends on #2460 
Relates to #1881 
Relates to #2493
2023-01-02 12:37:49 -08:00
Jon Ross-Perkins 60b45e3d30 The typed_linked_list test trace output is too slow, so stop testing it. (#2494)
Another case of flakiness from trace output performance:
https://github.com/carbon-language/carbon-lang/actions/runs/3760820974/jobs/6391950894
2022-12-23 06:44:42 -08:00
Adrien Leravat 026c4b9dc3 Explorer: move subtyping logic to TypeChecker (#2484)
Addresses comments from this discussion: https://github.com/carbon-language/carbon-lang/pull/2460#discussion_r1046444433

Features:
* Move subtyping logic from Interpreter to TypeChecker, exposing subtyping as a series of access to `.base`.
    * Excludes function parameter conversion, which is still done in ::Convert due to parameters conversion being handled differently.

Changes:
* Add new `class BaseAccessExpression : public MemberAccessExpression`, allowing rewrites
* Handle `BaseAccessExpression` expression type in Interpreter
* Move subtyping logic to `TypeChecker::ImplicitlyConvert`
2022-12-21 19:01:02 -08:00
9299e51511 Explorer: Support class subtyping (#2460)
Features:
* Adds support for [subtyping](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#subtyping) for local variables, and function parameters

Changes:
* Update function parameter `Deduce` to handle subtyping
* Update `InstantiateType` to support `PointerType`
* Update `Convert` to support convertion from child class to a base class

Relates to #1881 

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Geoff Romer <gromer@google.com>
2022-12-19 11:32:32 -08:00
Adrien Leravat e37a69a6d5 Destroy class hierarchy when destroying class with a base (#2378)
Depends on #2361, #2421

Add support for destructors of base classes.
Features:
- Call destructors from derived to base class
- Support addressing `TupleValue` using a new `Member` variant

Changes:
- Update `StepDestroy()` to recursively call destructors from derived to base class
- Add new `Member` variant and `IndexedValue` struct to be usable with `TupleValue`
2022-12-12 09:59:03 -08:00
Richard Smith 0ef7fa3a1d Support p->member, rewriting it to (*p).member in the parser. (#2455)
* Support `p->member`, rewriting it to `(*p).member` in the parser.

This behavior is as described in
https://github.com/carbon-language/carbon-lang/tree/trunk/docs/design#pointer-types:

> `p->m` is syntactic sugar for `(*p).m`.
2022-12-08 13:42:36 -08:00
josh11b 9c8fd6864e Implement rename me -> self (#2444)
Implements change proposed in #1382

Replaces #1624
2022-12-06 20:17:00 -08:00
Adrien Leravat 1d0bb85d0c Explorer: basic abstract class support (#2441)
Relates to #1881 

Features:
* Add basic support for `abstract` class
    * Allow extending an abstract class
    * Prevent direct instantiation of an abstract class
Changes:
* Check that class extensibility for `VariableDefinition` is not `Abstract`
* Add corresponding set of lit tests
2022-12-06 09:35:55 -08:00
Adrien LeravatandRichard Smith 46f4887cf7 Explorer: support .base to initialize parent class from struct (#2361)
Relates to https://github.com/carbon-language/carbon-lang/issues/1881

- Add support for `.base` field in structs for [parent class initialization](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#constructors)
    - Disabling base class initialization without `.base`
- Support class constructors (`Create() -> Self`) for base classes
- Direct access to base class(es) attributes with `object.var` remains unaffected

Changes:
- Add `TypeChecker::FieldTypesWithBase` to help assessing if a struct with `base` fields can be converted to a class
- Add a new `base_type()` attribute+getter to `NominalClassDeclaration` to as a first step to allow resolving parametrized classes
- Add a new `base` attribute+getter to `NominalClassValue` that contains the base class `NominalClassValue`. It is currently used mainly to get and set members of a class object.
- Add `Interpreter::ConvertClassWithBase` to build `NominalClassValue` from a init struct, that contains `.base` fields with either `NominalClassValue` or `StructValue`
- Add `FindClassField` to find a field in a class or its base classes
- Remove superfluous `ClassDeclaration::base()` in favor of `ClassDeclaration::base_type()`

Limitations;
- Though some work is done in that direction, parametrized base class where time is not know at the declaration site are not supported. Namely the example below does not compile
```
base class A(T:! Type) {}
class B(T:! Type) extends A(T) {}
```
But this one is functional already
```
base class A(T:! Type) {}
class B extends A(i32) {}
```

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2022-11-29 13:14:30 -08:00
Jon Ross-Perkins f6c5298c15 Make lit tests small (#2391)
Makes explorer/testdata/assoc_const/rewrite_large_type.carbon NOAUTOUPDATE and no-trace because otherwise it takes ~130s to run. With this it's sub-second, explorer is just dumping a lot of trace output (maybe still something to fix).
2022-11-14 11:35:14 -08:00
Jon Ross-Perkins fd455ed36b Add convenience .run targets for test files. (#2384)
e.g., for `//explorer/testdata:tuple/no_ending_comma.carbon.test`, `bazel run //explorer/testdata:tuple/no_ending_comma.carbon.run`
2022-11-14 08:39:56 -08:00
Liz 25d1b62df0 explorer: Typed double linked list test (#2366)
This adds a second double linked list test carbon program, which has
the major difference, that it is not bound to a type but rather uses the
generics system to allow the type to be be specified at creation.
Of course this is heavily inspired by the first linked_list example program,
but this does show of/test a different feature set solving the same problem.
2022-11-11 14:00:19 -08:00
Richard Smith e557d4af3b Make addr me: Self* work for interface methods. (#2374)
Fixes #2223.
2022-11-07 08:11:19 -08:00
Richard Smith 9e8cacae00 Implement support for named constraints (#2359)
Basic support for named constraints as described in [the generics design](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/generics/details.md#named-constraints). Support is provided for `extends` and `impl` declarations in `constraint`, but not yet for member aliases.

The missing prelude named constraints `Add`, `Mul`, `Ordered`, etc. are also added.
2022-11-04 16:23:02 -07:00
cef93fba5e Feature call destructor for tuples and bug fixes for the destructor process (#2255)
This PR includes the following changes:
*  Added destruction process for tuples
*  Fix: In the current version only the last member of a object can be destroyed
*  Fix: In the current version, the destructor of the object is called after each method call 

I hope it is useful

Co-authored-by: m new <michael.burzan@outlook.de>
Co-authored-by: Geoff Romer <gromer@google.com>
2022-11-04 12:13:24 -07:00