diff --git a/frontend/lib/resolution/Resolver.cpp b/frontend/lib/resolution/Resolver.cpp index 0d7396096a17..abd856a02108 100644 --- a/frontend/lib/resolution/Resolver.cpp +++ b/frontend/lib/resolution/Resolver.cpp @@ -5438,6 +5438,13 @@ getDecoratedClassForNew(Context* context, const New* node, switch (node->management()) { case New::DEFAULT_MANAGEMENT: + // Management might've been provided for us already; otherwise + // fall back to the default: 'owned'. + if (!classType->decorator().isUnknownManagement()) + break; + + // Fall through to 'owned' management. + case New::OWNED: decorator = ClassTypeDecorator(ClassTypeDecorator::MANAGED); manager = AnyOwnedType::get(context); diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index e813d8bd50bd..cef45d7ad52f 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -946,17 +946,21 @@ generateRecordBinaryOperator(Context* context, UniqueString op, static const TypedFnSignature* generateRecordAssignment(Context* context, const CompositeType* lhsType) { + // rhs used to be 'maybe const' but now 'const' is default. + // + // TODO: it's possible that we need to compute the dyno equivalent of + // FLAG_COPY_MUTATES to get the right constness here. return generateRecordBinaryOperator(context, USTR("="), lhsType, - /*this*/ QualifiedType::CONST_REF, - /*lhs*/ QualifiedType::CONST_REF, - /*rhs*/ QualifiedType::CONST_REF); + /*this*/ QualifiedType::TYPE, + /*lhs*/ QualifiedType::REF, + /*rhs*/ QualifiedType::CONST_REF ); } static const TypedFnSignature* generateRecordComparison(Context* context, const CompositeType* lhsType) { return generateRecordBinaryOperator(context, USTR("=="), lhsType, - /*this*/ QualifiedType::REF, - /*lhs*/ QualifiedType::REF, + /*this*/ QualifiedType::TYPE, + /*lhs*/ QualifiedType::CONST_REF, /*rhs*/ QualifiedType::CONST_REF); } diff --git a/frontend/test/resolution/testNew.cpp b/frontend/test/resolution/testNew.cpp index aa416f7f39b4..664fb4d0fe6a 100644 --- a/frontend/test/resolution/testNew.cpp +++ b/frontend/test/resolution/testNew.cpp @@ -1040,6 +1040,23 @@ static void testUserGenericNew() { assert(guard.realizeErrors() == 1); } +static void testExplicitManagementNew() { + auto ctx = buildStdContext(); + ErrorGuard guard(ctx); + + auto var = resolveTypeOfXInit(ctx, + R"""( + class C{} + + proc getType() type do return unmanaged C; + + var x = new (getType())(); + )"""); + + assert(var.type()->isClassType()); + assert(var.type()->toClassType()->decorator().isUnmanaged()); +} + int main() { testEmptyRecordUserInit(); @@ -1056,6 +1073,7 @@ int main() { testCompilerGeneratedGenericNewClass(); testSimpleUserGenericNew(); testUserGenericNew(); + testExplicitManagementNew(); return 0; } diff --git a/frontend/test/resolution/testOperatorOverloads.cpp b/frontend/test/resolution/testOperatorOverloads.cpp index cf746177dd11..80f79d04a84b 100644 --- a/frontend/test/resolution/testOperatorOverloads.cpp +++ b/frontend/test/resolution/testOperatorOverloads.cpp @@ -230,10 +230,12 @@ static void test4() { var x : int; } - var a : R; - var b : R; - - var x = a == b; + proc foo() { + const a : R; + const b : R; + return a == b; + } + var x = foo(); )""""; QualifiedType initType = resolveTypeOfXInit(context, program);