From 408e4866f8a6fc431f0f8432dd24bb492c4e4b77 Mon Sep 17 00:00:00 2001 From: Chloe Stefantsova Date: Thu, 7 Dec 2023 14:01:44 +0000 Subject: [PATCH] [cfe] Account for extension type self-dependency via raw types Closes https://github.com/dart-lang/sdk/issues/54241 Change-Id: I7afcaab225f93763f0dd2852bb51227c05abe4bb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340403 Reviewed-by: Johnni Winther Commit-Queue: Chloe Stefantsova --- ...ce_extension_type_declaration_builder.dart | 67 ++++++++++++++++++- .../testcases/extension_types/issue54241.dart | 6 ++ .../issue54241.dart.strong.expect | 27 ++++++++ .../issue54241.dart.strong.transformed.expect | 27 ++++++++ .../issue54241.dart.textual_outline.expect | 3 + ...54241.dart.textual_outline_modelled.expect | 3 + .../issue54241.dart.weak.expect | 27 ++++++++ .../issue54241.dart.weak.modular.expect | 27 ++++++++ .../issue54241.dart.weak.outline.expect | 24 +++++++ .../issue54241.dart.weak.transformed.expect | 27 ++++++++ 10 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.strong.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.weak.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/extension_types/issue54241.dart.weak.transformed.expect diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart index 421a0ba0a7e1..87eebb9e6b8c 100644 --- a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:front_end/src/fasta/builder/record_type_builder.dart'; -import 'package:front_end/src/fasta/kernel/body_builder_context.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart'; import 'package:kernel/core_types.dart'; @@ -20,10 +18,16 @@ import '../builder/library_builder.dart'; import '../builder/member_builder.dart'; import '../builder/metadata_builder.dart'; import '../builder/name_iterator.dart'; +import '../builder/record_type_builder.dart'; import '../builder/type_builder.dart'; +import '../dill/dill_class_builder.dart'; +import '../dill/dill_extension_type_declaration_builder.dart'; +import '../dill/dill_type_alias_builder.dart'; +import '../kernel/body_builder_context.dart'; import '../kernel/hierarchy/hierarchy_builder.dart'; import '../kernel/kernel_helper.dart'; import '../kernel/type_algorithms.dart'; +import '../kernel/type_builder_computer.dart'; import '../messages.dart'; import '../problems.dart'; import '../scope.dart'; @@ -373,6 +377,65 @@ class SourceExtensionTypeDeclarationBuilder return true; } } + } else if (declaration != null && declaration.typeVariablesCount > 0) { + List? typeParameters; + List? typeParametersFromKernel; + bool isFromKernel = false; + switch (declaration) { + case ClassBuilder(): + typeParameters = declaration.typeVariables; + if (declaration is DillClassBuilder) { + isFromKernel = true; + typeParametersFromKernel = declaration.cls.typeParameters; + } + case TypeAliasBuilder(): + typeParameters = declaration.typeVariables; + if (declaration is DillTypeAliasBuilder) { + isFromKernel = true; + typeParametersFromKernel = declaration.typedef.typeParameters; + } + case ExtensionTypeDeclarationBuilder(): + typeParameters = declaration.typeParameters; + if (declaration is DillExtensionTypeDeclarationBuilder) { + isFromKernel = true; + typeParametersFromKernel = + declaration.extensionTypeDeclaration.typeParameters; + } + case BuiltinTypeDeclarationBuilder(): + case InvalidTypeDeclarationBuilder(): + case OmittedTypeDeclarationBuilder(): + case ExtensionBuilder(): + case TypeVariableBuilderBase(): + } + if (typeParameters != null) { + TypeBuilderComputer? typeBuilderComputer; + for (int i = 0; i < typeParameters.length; i++) { + TypeVariableBuilderBase typeParameter = typeParameters[i]; + if (!isFromKernel) { + if (_checkRepresentationDependency( + typeParameter.defaultType!, + rootExtensionTypeDeclaration, + seenExtensionTypeDeclarations.toSet(), + usedTypeAliasBuilders.toSet())) { + return true; + } + } else if (typeParametersFromKernel != null) { + assert( + typeParameters.length == typeParametersFromKernel.length); + typeBuilderComputer ??= + new TypeBuilderComputer(libraryBuilder.loader); + if (_checkRepresentationDependency( + typeParametersFromKernel[i] + .defaultType + .accept(typeBuilderComputer), + rootExtensionTypeDeclaration, + seenExtensionTypeDeclarations.toSet(), + usedTypeAliasBuilders.toSet())) { + return true; + } + } + } + } } case FunctionTypeBuilder( :List? typeVariables, diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart b/pkg/front_end/testcases/extension_types/issue54241.dart new file mode 100644 index 000000000000..663fc6cd4eea --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +class A {} +extension type E(Function() it) {} diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.strong.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.strong.expect new file mode 100644 index 000000000000..9bc456eecaff --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.strong.expect @@ -0,0 +1,27 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ { + lowered final self::E /* = invalid-type */ #this = it; + return #this; +} +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it); diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.strong.transformed.expect new file mode 100644 index 000000000000..9bc456eecaff --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.strong.transformed.expect @@ -0,0 +1,27 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ { + lowered final self::E /* = invalid-type */ #this = it; + return #this; +} +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it); diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline.expect new file mode 100644 index 000000000000..96f13b99ae37 --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline.expect @@ -0,0 +1,3 @@ +class A {} + +extension type E(Function() it) {} diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..96f13b99ae37 --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.textual_outline_modelled.expect @@ -0,0 +1,3 @@ +class A {} + +extension type E(Function() it) {} diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.weak.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.expect new file mode 100644 index 000000000000..9bc456eecaff --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.expect @@ -0,0 +1,27 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ { + lowered final self::E /* = invalid-type */ #this = it; + return #this; +} +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it); diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.weak.modular.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.modular.expect new file mode 100644 index 000000000000..9bc456eecaff --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.modular.expect @@ -0,0 +1,27 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ { + lowered final self::E /* = invalid-type */ #this = it; + return #this; +} +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it); diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.outline.expect new file mode 100644 index 000000000000..041f753eec2e --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.outline.expect @@ -0,0 +1,24 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + ; +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it); diff --git a/pkg/front_end/testcases/extension_types/issue54241.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.transformed.expect new file mode 100644 index 000000000000..9bc456eecaff --- /dev/null +++ b/pkg/front_end/testcases/extension_types/issue54241.dart.weak.transformed.expect @@ -0,0 +1,27 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type. +// extension type E(Function() it) {} +// ^ +// +import self as self; +import "dart:core" as core; + +class A extends core::Object { + synthetic constructor •() → self::A + : super core::Object::•() + ; +} +extension type E(invalid-type it) { + abstract extension-type-member representation-field get it() → = dynamic>() → dynamic; + constructor • = self::E|constructor#; + constructor tearoff • = self::E|constructor#_#new#tearOff; +} +static extension-type-member method E|constructor#( = dynamic>() → dynamic it) → self::E /* = invalid-type */ { + lowered final self::E /* = invalid-type */ #this = it; + return #this; +} +static extension-type-member method E|constructor#_#new#tearOff( = dynamic>() → dynamic it) → self::E /* = invalid-type */ + return self::E|constructor#(it);