mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Detect control flow in entities nested inside functions (#5336)
Right now, return_scope_stack is being used to determine whether logic
is in a function scope. However, we need to handle nested entities
inside function scopes. For example where this crashes right now:
```
base class C(B:! bool) {}
fn F() {
class B {
extend base: C(true or false);
}
}
```
This is doing a few things to make this kind of code not crash:
- Split `scope_stack().Push` into `PushForDeclName`, `PushForEntity`,
`PushForExpr`, and `PushForFunction` so that better decisions can be
made about behaviors.
- Hide `return_scope_stack` in the API, instead using interfaces to get
at the underlying data.
- Also using `PushForFunction` to update it similar to the other stacks
that `ScopeStack` manages.
- Add `IsInFunctionScope` as the best way to determine presence in
function scope.
- Remove `PeekIsLexicalScope` since destruction really wants function
scope information anyways.
- Clean up `destroy_id_stack` handling to be for function scopes rather
than lexical scopes.
- Return after related `context.TODO`s in a couple more spots, so that
code doesn't proceed to add control flow in spite of the lack of
support.
---------
Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
co-authored by
Geoff Romer
parent
51498547c9
commit
03e693873b
@@ -12,12 +12,11 @@ namespace Carbon::Check {
|
||||
|
||||
// Gets the function that lexically encloses the current location.
|
||||
auto GetCurrentFunctionForReturn(Context& context) -> SemIR::Function& {
|
||||
CARBON_CHECK(!context.return_scope_stack().empty(),
|
||||
CARBON_CHECK(context.scope_stack().IsInFunctionScope(),
|
||||
"Handling return but not in a function");
|
||||
auto function_id = context.insts()
|
||||
.GetAs<SemIR::FunctionDecl>(
|
||||
context.return_scope_stack().back().decl_id)
|
||||
.function_id;
|
||||
auto decl_id = context.scope_stack().GetReturnScopeDeclId();
|
||||
auto function_id =
|
||||
context.insts().GetAs<SemIR::FunctionDecl>(decl_id).function_id;
|
||||
return context.functions().Get(function_id);
|
||||
}
|
||||
|
||||
@@ -33,9 +32,9 @@ auto GetCurrentReturnSlot(Context& context) -> SemIR::InstId {
|
||||
// Gets the currently in scope `returned var`, if any, that would be returned
|
||||
// by a `return var;`.
|
||||
static auto GetCurrentReturnedVar(Context& context) -> SemIR::InstId {
|
||||
CARBON_CHECK(!context.return_scope_stack().empty(),
|
||||
CARBON_CHECK(context.scope_stack().IsInFunctionScope(),
|
||||
"Handling return but not in a function");
|
||||
return context.return_scope_stack().back().returned_var;
|
||||
return context.scope_stack().GetReturnedVar();
|
||||
}
|
||||
|
||||
// Produces a note that the given function has no explicit return type.
|
||||
|
||||
Reference in New Issue
Block a user