Skip to content

Commit ac19f52

Browse files
chloestefantsovaCommit Bot
authored and
Commit Bot
committed
Reland "[cfe] Remove coercions for super parameters"
This is a reland of commit 61465fb Original change's description: > [cfe] Remove coercions for super parameters > > Part of #47525 > > Change-Id: Iadb2f0125318edd73ab84e5b1a9cafae098ec618 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239081 > Reviewed-by: Johnni Winther <[email protected]> > Commit-Queue: Chloe Stefantsova <[email protected]> Change-Id: I57c9f4b541d8c655f6ec855a131801008195c213 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239428 Reviewed-by: Jens Johansen <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent c286b76 commit ac19f52

13 files changed

+1400
-8
lines changed

pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,7 @@ class BodyBuilder extends StackListenerImpl
18541854

18551855
List<Expression>? positionalSuperParametersAsArguments;
18561856
List<NamedExpression>? namedSuperParametersAsArguments;
1857+
Set<String>? namedSuperParameterNames;
18571858
if (formals != null) {
18581859
for (FormalParameterBuilder formal in formals) {
18591860
if (formal.isSuperInitializingFormal) {
@@ -1865,6 +1866,7 @@ class BodyBuilder extends StackListenerImpl
18651866
forNullGuardedAccess: false)
18661867
..fileOffset = formal.charOffset)
18671868
..fileOffset = formal.charOffset);
1869+
(namedSuperParameterNames ??= <String>{}).add(formal.name);
18681870
} else {
18691871
(positionalSuperParametersAsArguments ??= <Expression>[]).add(
18701872
new VariableGetImpl(formal.variable!,
@@ -1886,7 +1888,7 @@ class BodyBuilder extends StackListenerImpl
18861888
superInitializer.fileOffset, noLength))
18871889
..parent = constructor;
18881890
} else if (libraryBuilder.enableSuperParametersInLibrary) {
1889-
Arguments arguments = superInitializer.arguments;
1891+
ArgumentsImpl arguments = superInitializer.arguments as ArgumentsImpl;
18901892

18911893
if (positionalSuperParametersAsArguments != null) {
18921894
if (arguments.positional.isNotEmpty) {
@@ -1904,12 +1906,14 @@ class BodyBuilder extends StackListenerImpl
19041906
} else {
19051907
arguments.positional.addAll(positionalSuperParametersAsArguments);
19061908
setParents(positionalSuperParametersAsArguments, arguments);
1909+
arguments.positionalAreSuperParameters = true;
19071910
}
19081911
}
19091912
if (namedSuperParametersAsArguments != null) {
19101913
// TODO(cstefantsova): Report name conflicts.
19111914
arguments.named.addAll(namedSuperParametersAsArguments);
19121915
setParents(namedSuperParametersAsArguments, arguments);
1916+
arguments.namedSuperParameterNames = namedSuperParameterNames;
19131917
}
19141918
}
19151919
} else if (initializers.last is RedirectingInitializer) {
@@ -1958,7 +1962,7 @@ class BodyBuilder extends StackListenerImpl
19581962
/// >unless the enclosing class is class Object.
19591963
Constructor? superTarget = lookupConstructor(emptyName, isSuper: true);
19601964
Initializer initializer;
1961-
Arguments arguments;
1965+
ArgumentsImpl arguments;
19621966
List<Expression>? positionalArguments;
19631967
List<NamedExpression>? namedArguments;
19641968
if (libraryBuilder.enableSuperParametersInLibrary) {
@@ -1976,13 +1980,19 @@ class BodyBuilder extends StackListenerImpl
19761980
forNullGuardedAccess: false)
19771981
]);
19781982
}
1983+
19791984
if (positionalArguments != null || namedArguments != null) {
19801985
arguments = forest.createArguments(
19811986
noLocation, positionalArguments ?? <Expression>[],
19821987
named: namedArguments);
19831988
} else {
19841989
arguments = forest.createArgumentsEmpty(noLocation);
19851990
}
1991+
1992+
arguments.positionalAreSuperParameters =
1993+
positionalSuperParametersAsArguments != null;
1994+
arguments.namedSuperParameterNames = namedSuperParameterNames;
1995+
19861996
if (superTarget == null ||
19871997
checkArgumentsForFunction(superTarget.function, arguments,
19881998
builder.charOffset, const <TypeParameter>[]) !=

pkg/front_end/lib/src/fasta/kernel/internal_ast.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,17 @@ class ArgumentsImpl extends Arguments {
493493

494494
List<Object?>? argumentsOriginalOrder;
495495

496+
/// True if the arguments are passed to the super-constructor in a
497+
/// super-initializer, and the positional parameters are super-initializer
498+
/// parameters. It is true that either all of the positional parameters are
499+
/// super-initializer parameters or none of them, so a simple boolean
500+
/// accurately reflects the state.
501+
bool positionalAreSuperParameters = false;
502+
503+
/// Names of the named positional parameters. If none of the parameters are
504+
/// super-positional, the field is null.
505+
Set<String>? namedSuperParameterNames;
506+
496507
ArgumentsImpl.internal(
497508
{required List<Expression> positional,
498509
required List<DartType>? types,

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ class TypeInferrerImpl implements TypeInferrer {
493493
DartType? declaredContextType,
494494
DartType? runtimeCheckedType,
495495
bool isVoidAllowed: false,
496+
bool coerceExpression: true,
496497
Template<Message Function(DartType, DartType, bool)>? errorTemplate,
497498
Template<Message Function(DartType, DartType, bool)>?
498499
nullabilityErrorTemplate,
@@ -508,6 +509,7 @@ class TypeInferrerImpl implements TypeInferrer {
508509
declaredContextType: declaredContextType,
509510
runtimeCheckedType: runtimeCheckedType,
510511
isVoidAllowed: isVoidAllowed,
512+
coerceExpression: coerceExpression,
511513
errorTemplate: errorTemplate,
512514
nullabilityErrorTemplate: nullabilityErrorTemplate,
513515
nullabilityNullErrorTemplate: nullabilityNullErrorTemplate,
@@ -526,6 +528,7 @@ class TypeInferrerImpl implements TypeInferrer {
526528
DartType? declaredContextType,
527529
DartType? runtimeCheckedType,
528530
bool isVoidAllowed: false,
531+
bool coerceExpression: true,
529532
Template<Message Function(DartType, DartType, bool)>? errorTemplate,
530533
Template<Message Function(DartType, DartType, bool)>?
531534
nullabilityErrorTemplate,
@@ -577,7 +580,8 @@ class TypeInferrerImpl implements TypeInferrer {
577580
contextType, inferenceResult.inferredType,
578581
isNonNullableByDefault: isNonNullableByDefault,
579582
isVoidAllowed: isVoidAllowed,
580-
isExpressionTypePrecise: preciseTypeErrorTemplate != null);
583+
isExpressionTypePrecise: preciseTypeErrorTemplate != null,
584+
coerceExpression: coerceExpression);
581585

582586
if (assignabilityResult.needsTearOff) {
583587
TypedTearoff typedTearoff = _tearOffCall(inferenceResult.expression,
@@ -781,7 +785,8 @@ class TypeInferrerImpl implements TypeInferrer {
781785
DartType contextType, DartType expressionType,
782786
{required bool isNonNullableByDefault,
783787
required bool isVoidAllowed,
784-
required bool isExpressionTypePrecise}) {
788+
required bool isExpressionTypePrecise,
789+
required bool coerceExpression}) {
785790
// ignore: unnecessary_null_comparison
786791
assert(isNonNullableByDefault != null);
787792
// ignore: unnecessary_null_comparison
@@ -793,7 +798,7 @@ class TypeInferrerImpl implements TypeInferrer {
793798
// should tear off `.call`.
794799
// TODO(paulberry): use resolveTypeParameter. See findInterfaceMember.
795800
bool needsTearoff = false;
796-
if (expressionType is InterfaceType) {
801+
if (coerceExpression && expressionType is InterfaceType) {
797802
Class classNode = expressionType.classNode;
798803
Member? callMember =
799804
classHierarchy.getInterfaceMember(classNode, callName);
@@ -812,7 +817,7 @@ class TypeInferrerImpl implements TypeInferrer {
812817
}
813818
}
814819
ImplicitInstantiation? implicitInstantiation;
815-
if (libraryBuilder.enableConstructorTearOffsInLibrary) {
820+
if (coerceExpression && libraryBuilder.enableConstructorTearOffsInLibrary) {
816821
implicitInstantiation =
817822
computeImplicitInstantiation(expressionType, contextType);
818823
if (implicitInstantiation != null) {
@@ -866,8 +871,15 @@ class TypeInferrerImpl implements TypeInferrer {
866871
return const AssignabilityResult(AssignabilityKind.unassignablePrecise,
867872
needsTearOff: false);
868873
}
869-
// Insert an implicit downcast.
870-
return new AssignabilityResult(AssignabilityKind.assignableCast,
874+
875+
if (coerceExpression) {
876+
// Insert an implicit downcast.
877+
return new AssignabilityResult(AssignabilityKind.assignableCast,
878+
needsTearOff: needsTearoff,
879+
implicitInstantiation: implicitInstantiation);
880+
}
881+
882+
return new AssignabilityResult(AssignabilityKind.unassignable,
871883
needsTearOff: needsTearoff,
872884
implicitInstantiation: implicitInstantiation);
873885
}
@@ -2617,17 +2629,23 @@ class TypeInferrerImpl implements TypeInferrer {
26172629
DartType actualType = actualTypes![i];
26182630
Expression expression;
26192631
NamedExpression? namedExpression;
2632+
bool coerceExpression;
26202633
if (i < numPositionalArgs) {
26212634
expression = arguments.positional[positionalShift + i];
26222635
positionalArgumentTypes.add(actualType);
2636+
coerceExpression = !arguments.positionalAreSuperParameters;
26232637
} else {
26242638
namedExpression = arguments.named[i - numPositionalArgs];
26252639
expression = namedExpression.value;
26262640
namedArgumentTypes
26272641
.add(new NamedType(namedExpression.name, actualType));
2642+
coerceExpression = !(arguments.namedSuperParameterNames
2643+
?.contains(namedExpression.name) ??
2644+
false);
26282645
}
26292646
expression = ensureAssignable(expectedType, actualType, expression,
26302647
isVoidAllowed: expectedType is VoidType,
2648+
coerceExpression: coerceExpression,
26312649
// TODO(johnniwinther): Specialize message for operator
26322650
// invocations.
26332651
errorTemplate: templateArgumentTypeNotAssignable,

pkg/front_end/test/spell_checking_list_common.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ account
4747
accounted
4848
accumulate
4949
accurate
50+
accurately
5051
achieve
5152
act
5253
acting
@@ -489,6 +490,7 @@ closure
489490
closures
490491
clue
491492
code
493+
coerce
492494
coincides
493495
coinductively
494496
collapses
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class A1 {
6+
A1(int x);
7+
}
8+
9+
class B1 extends A1 {
10+
B1.one(dynamic super.x); // Error.
11+
B1.two(dynamic super.x) : super(); // Error.
12+
}
13+
14+
class A2 {
15+
A2({required String x});
16+
}
17+
18+
class B2 extends A2 {
19+
B2.one({required dynamic super.x}); // Error.
20+
B2.two({required dynamic super.x}) : super(); // Error.
21+
}
22+
23+
class A3 {
24+
A3(num Function(double) f);
25+
}
26+
27+
class B3 extends A3 {
28+
B3.one(X Function<X>(double) super.f); // Error.
29+
B3.two(X Function<X>(double) super.f) : super(); // Error.
30+
}
31+
32+
class A4 {
33+
A4({required num Function(double) f});
34+
}
35+
36+
class B4 extends A4 {
37+
B4.one({required X Function<X>(double) super.f}); // Error.
38+
B4.two({required X Function<X>(double) super.f}) : super(); // Error.
39+
}
40+
41+
abstract class C5 {
42+
String call(int x, num y);
43+
}
44+
45+
class A5 {
46+
A5(String Function(int, num) f);
47+
}
48+
49+
class B5 extends A5 {
50+
B5.one(C5 super.f); // Error.
51+
B5.two(C5 super.f) : super(); // Error.
52+
}
53+
54+
class A6 {
55+
A6({required String Function(int, num) f});
56+
}
57+
58+
class B6 extends A6 {
59+
B6.one({required C5 super.f}); // Error.
60+
B6.two({required C5 super.f}) : super(); // Error.
61+
}
62+
63+
class A7 {
64+
A7({required int x1,
65+
required int x2,
66+
required bool Function(Object) f1,
67+
required bool Function(Object) f2,
68+
required void Function(dynamic) g1,
69+
required void Function(dynamic) g2});
70+
}
71+
72+
class B7 extends A7 {
73+
B7({required dynamic super.x1, // Error.
74+
required dynamic x2,
75+
required X Function<X>(Object) super.f1, // Error.
76+
required X Function<X>(Object) f2,
77+
required void Function<X>(X) super.g1, // Error.
78+
required void Function<X>(X) g2}) :
79+
super(x2: x2, f2: f2, g2: g2); // Ok.
80+
}
81+
82+
main() {}

0 commit comments

Comments
 (0)