Skip to content

Commit c375a13

Browse files
committed
Merge branch 'trunk' into toolchain-overload-diagnostics
2 parents 5bef313 + 9704dc6 commit c375a13

File tree

156 files changed

+3555
-2510
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+3555
-2510
lines changed

.codespell_ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Exceptions. See /LICENSE for license information.
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

5+
AggregateT
56
ArchType
67
atleast
78
circularly

core/prelude/destroy.carbon

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,35 @@
44

55
package Core library "prelude/destroy";
66

7+
import library "prelude/types/bool";
8+
import library "prelude/types/int_literal";
9+
710
// Object destruction, including running `fn destroy()`. Note this is distinct
811
// from memory deallocation.
912
interface Destroy {
1013
fn Op[addr self: Self*]();
1114
}
1215

13-
// Provide a default blanket impl for trivial destruction.
14-
impl forall [T:! type] T as Destroy {
16+
// Add destruction for essential builtin types. This can't be done earlier
17+
// because `Destroy` is using them.
18+
// TODO: This should match trivial destruction.
19+
impl bool as Destroy {
20+
fn Op[addr self: Self*]() = "no_op";
21+
}
22+
impl type as Destroy {
23+
fn Op[addr self: Self*]() = "no_op";
24+
}
25+
impl forall [PointeeT:! type] PointeeT* as Destroy {
1526
fn Op[addr self: Self*]() = "no_op";
1627
}
28+
29+
// Handles builtin aggregate type destruction.
30+
private fn CanAggregateDestroy() -> type = "type.can_aggregate_destroy";
31+
impl forall [AggregateT:! CanAggregateDestroy()] AggregateT as Destroy {
32+
fn Op[addr self: Self*]() = "type.aggregate_destroy";
33+
}
34+
35+
// `const` instances always use the non-`const` destructor.
36+
impl forall [NonConstT:! Destroy] const NonConstT as Destroy {
37+
fn Op[addr self: Self*]() { (self unsafe as NonConstT*)->(Destroy.Op)(); }
38+
}

examples/interop/cpp/hello_world.carbon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import Cpp inline "#include <cstdio>";
66

77
fn Run() {
8-
// TODO: Requires operator <<, declaration type Var (cout) and class with
9-
// virtual bases (basic_ostream).
8+
// TODO: Requires member operator << and class with virtual bases
9+
// (basic_ostream).
1010
// Cpp.std.cout << "Hello world!\n";
1111

1212
// TODO: Requires variadic function.
@@ -20,7 +20,7 @@ fn Run() {
2020

2121
// TODO: Requires Core.String API.
2222
// let message: str = "Hello world!\n\n";
23-
// for (c: Core.Char in msg) {
23+
// for (c: Core.Char in message) {
2424
// Cpp.putchar((c as u8) as i32);
2525
// }
2626

toolchain/check/class.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
214214
override_fn.virtual_index = vtable.size();
215215
CARBON_CHECK(override_fn.virtual_index == fn.virtual_index);
216216
} else if (auto base_vtable_specific_function =
217-
context.sem_ir().insts().TryGetAs<SemIR::SpecificFunction>(
217+
context.insts().TryGetAs<SemIR::SpecificFunction>(
218218
derived_vtable_entry_id)) {
219219
if (derived_vtable_entry_const_id.is_symbolic()) {
220220
// Create a new instruction here that is otherwise identical to

toolchain/check/context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ class Context {
299299
auto types() -> SemIR::TypeStore& { return sem_ir().types(); }
300300
// Instructions should be added with `AddInst` or `AddInstInNoBlock` from
301301
// `inst.h`. This is `const` to prevent accidental misuse.
302-
auto insts() -> const SemIR::InstStore& { return sem_ir().insts(); }
302+
auto insts() const -> const SemIR::InstStore& { return sem_ir().insts(); }
303303
auto constant_values() -> SemIR::ConstantValueStore& {
304304
return sem_ir().constant_values();
305305
}

toolchain/check/convert.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static auto CopyValueToTemporary(Context& context, SemIR::InstId init_id)
6363
-> SemIR::InstId {
6464
// TODO: Consider using `None` to mean that we immediately materialize and
6565
// initialize a temporary, rather than two separate instructions.
66-
auto init = context.sem_ir().insts().Get(init_id);
66+
auto init = context.insts().Get(init_id);
6767
auto temporary_id = AddInst<SemIR::TemporaryStorage>(
6868
context, SemIR::LocId(init_id), {.type_id = init.type_id()});
6969
return AddInstWithCleanup<SemIR::Temporary>(context, SemIR::LocId(init_id),

toolchain/check/cpp/import.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/AST/ASTContext.h"
1414
#include "clang/AST/RecordLayout.h"
1515
#include "clang/AST/UnresolvedSet.h"
16+
#include "clang/AST/VTableBuilder.h"
1617
#include "clang/Basic/FileManager.h"
1718
#include "clang/Frontend/ASTUnit.h"
1819
#include "clang/Frontend/CompilerInstance.h"
@@ -598,8 +599,7 @@ static auto IsDeclInjectedClassName(const Context& context,
598599
CARBON_CHECK(ast_context.getCanonicalTagType(scope_record_decl) ==
599600
ast_context.getCanonicalTagType(record_decl));
600601

601-
auto class_decl =
602-
context.sem_ir().insts().GetAs<SemIR::ClassDecl>(clang_decl.inst_id);
602+
auto class_decl = context.insts().GetAs<SemIR::ClassDecl>(clang_decl.inst_id);
603603
CARBON_CHECK(name_id ==
604604
context.sem_ir().classes().Get(class_decl.class_id).name_id);
605605
return true;
@@ -1623,6 +1623,21 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
16231623
AddPlaceholderInstInNoBlock(context, Parse::NodeId::None, function_decl);
16241624
context.imports().push_back(decl_id);
16251625

1626+
auto virtual_modifier = SemIR::Function::VirtualModifier::None;
1627+
int32_t virtual_index = -1;
1628+
if (auto* method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
1629+
if (method_decl->size_overridden_methods()) {
1630+
virtual_modifier = SemIR::Function::VirtualModifier::Override;
1631+
} else if (method_decl->isVirtual()) {
1632+
virtual_modifier = SemIR::Function::VirtualModifier::Virtual;
1633+
}
1634+
if (virtual_modifier != SemIR::Function::VirtualModifier::None) {
1635+
// TODO: Add support for Microsoft/non-Itanium vtables.
1636+
virtual_index = dyn_cast<clang::ItaniumVTableContext>(
1637+
context.ast_context().getVTableContext())
1638+
->getMethodVTableIndex(method_decl);
1639+
}
1640+
}
16261641
auto function_info = SemIR::Function{
16271642
{.name_id = GetFunctionName(context, clang_decl),
16281643
.parent_scope_id = GetParentNameScopeId(context, clang_decl),
@@ -1640,7 +1655,8 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
16401655
.definition_id = SemIR::InstId::None},
16411656
{.call_params_id = function_params_insts->call_params_id,
16421657
.return_slot_pattern_id = function_params_insts->return_slot_pattern_id,
1643-
.virtual_modifier = SemIR::FunctionFields::VirtualModifier::None,
1658+
.virtual_modifier = virtual_modifier,
1659+
.virtual_index = virtual_index,
16441660
.self_param_id = FindSelfPattern(
16451661
context, function_params_insts->implicit_param_patterns_id),
16461662
.clang_decl_id = context.sem_ir().clang_decls().Add(
@@ -1675,14 +1691,6 @@ auto ImportCppFunctionDecl(Context& context, SemIR::LocId loc_id,
16751691
return SemIR::ErrorInst::InstId;
16761692
}
16771693

1678-
if (auto* method_decl = dyn_cast<clang::CXXMethodDecl>(clang_decl)) {
1679-
if (method_decl->isVirtual()) {
1680-
context.TODO(loc_id, "Unsupported: Virtual function");
1681-
MarkFailedDecl(context, clang_decl);
1682-
return SemIR::ErrorInst::InstId;
1683-
}
1684-
}
1685-
16861694
CARBON_CHECK(clang_decl->getFunctionType()->isFunctionProtoType(),
16871695
"Not Prototype function (non-C++ code)");
16881696

@@ -2142,6 +2150,15 @@ auto ImportNameFromCpp(Context& context, SemIR::LocId loc_id,
21422150
builder.Note(loc_id, InCppNameLookup, name_id);
21432151
});
21442152

2153+
if (auto class_decl = context.insts().TryGetAs<SemIR::ClassDecl>(
2154+
context.name_scopes().Get(scope_id).inst_id());
2155+
class_decl.has_value()) {
2156+
if (!context.types().IsComplete(
2157+
context.classes().Get(class_decl->class_id).self_type_id)) {
2158+
return SemIR::ScopeLookupResult::MakeError();
2159+
}
2160+
}
2161+
21452162
auto lookup = ClangLookupName(context, scope_id, name_id);
21462163
if (!lookup) {
21472164
SemIR::InstId builtin_inst_id =

toolchain/check/deduce.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,6 @@ class DeductionWorklist {
113113
case SemIR::IdKind::None:
114114
case SemIR::IdKind::For<SemIR::ClassId>:
115115
case SemIR::IdKind::For<SemIR::IntKind>:
116-
// Decided on 2025-04-02 not to do deduction through facet types, because
117-
// types can implement a generic interface multiple times with different
118-
// arguments. See:
119-
// https://docs.google.com/document/d/1Iut5f2TQBrtBNIduF4vJYOKfw7MbS8xH_J01_Q4e6Rk/edit?pli=1&resourcekey=0-mc_vh5UzrzXfU4kO-3tOjA&tab=t.0#heading=h.95phmuvxog9n
120-
case SemIR::IdKind::For<SemIR::FacetTypeId>:
121116
break;
122117
case CARBON_KIND(SemIR::InstId inst_id): {
123118
Add(inst_id, SemIR::InstId(arg));

toolchain/check/eval.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,6 @@ static auto GetConstantValue(EvalContext& eval_context,
674674
SemIR::FacetTypeInfo info = GetConstantFacetTypeInfo(
675675
eval_context, SemIR::LocId::None,
676676
eval_context.facet_types().Get(facet_type_id), phase);
677-
// TODO: Return `facet_type_id` if we can detect nothing has changed.
678677
return eval_context.facet_types().Add(info);
679678
}
680679

toolchain/check/impl_lookup.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,22 @@ static auto TypeCanAggregateDestroy(Context& context,
548548
-> bool {
549549
auto inst = context.insts().Get(
550550
context.constant_values().GetInstId(query_self_const_id));
551-
return inst.Is<SemIR::StructType>() || inst.Is<SemIR::TupleType>();
551+
CARBON_KIND_SWITCH(inst) {
552+
case CARBON_KIND(SemIR::ClassType class_type): {
553+
// Carbon classes will generate a `Destroy` impl, but we use this to
554+
// provide destruction for `Cpp`-scoped classes.
555+
// TODO: Don't provide this for C++ types that lack a destructor.
556+
auto class_info = context.classes().Get(class_type.class_id);
557+
return context.name_scopes().Get(class_info.scope_id).is_cpp_scope();
558+
}
559+
case SemIR::ArrayType::Kind:
560+
case SemIR::MaybeUnformedType::Kind:
561+
case SemIR::StructType::Kind:
562+
case SemIR::TupleType::Kind:
563+
return true;
564+
default:
565+
return false;
566+
}
552567
}
553568

554569
auto LookupImplWitness(Context& context, SemIR::LocId loc_id,

0 commit comments

Comments
 (0)