Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart

Issue 1583623002: dart2js inferrer: don't infer widened type when unreachable (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: reformat Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/inferrer/inferrer_visitor.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index d5492f1a3d1446b582e61d0f3d53f4d2d1626282..dedb4e2ecbdfab549799619f05147a4d5c1f581a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -856,10 +856,13 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
}
/**
- * We optimize certain operations on the [int] class because we know
- * more about their return type than the actual Dart code. For
- * example, we know int + int returns an int. The Dart code for
- * [int.operator+] only says it returns a [num].
+ * We optimize certain operations on the [int] class because we know more
+ * about their return type than the actual Dart code. For example, we know int
+ * + int returns an int. The Dart library code for [int.operator+] only says
+ * it returns a [num].
+ *
+ * Returns the more precise TypeInformation, or `null` to defer to the library
+ * code.
*/
TypeInformation handleIntrisifiedSelector(
Selector selector, TypeMask mask, TypeGraphInferrerEngine inferrer) {
@@ -883,63 +886,78 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
return info.type
.satisfies(classWorld.backend.positiveIntImplementation, classWorld);
}
+ TypeInformation tryLater() => inferrer.types.nonNullEmptyType;
+
+ TypeInformation argument =
+ arguments.isEmpty ? null : arguments.positional.first;
String name = selector.name;
- // We are optimizing for the cases that are not expressed in the
- // Dart code, for example:
- // int + int -> int
- // uint31 | uint31 -> uint31
- if (name == '*' ||
- name == '+' ||
- name == '%' ||
- name == 'remainder' ||
- name == '~/') {
- if (isPositiveInt(receiver) &&
- arguments.hasOnePositionalArgumentThatMatches(isPositiveInt)) {
- // uint31 + uint31 -> uint32
- if (name == '+' &&
- isUInt31(receiver) &&
- arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
- return inferrer.types.uint32Type;
- } else {
+ // These are type inference rules only for useful cases that are not
+ // expressed in the library code, for example:
+ //
+ // int + int -> int
+ // uint31 | uint31 -> uint31
+ //
+ switch (name) {
+ case '*':
+ case '+':
+ case '%':
+ case 'remainder':
+ case '~/':
+ if (isEmpty(argument)) return tryLater();
+ if (isPositiveInt(receiver) && isPositiveInt(argument)) {
+ // uint31 + uint31 -> uint32
+ if (name == '+' && isUInt31(receiver) && isUInt31(argument)) {
+ return inferrer.types.uint32Type;
+ }
return inferrer.types.positiveIntType;
}
- } else if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
- return inferrer.types.intType;
- } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
- return inferrer.types.nonNullEmptyType;
- } else {
+ if (isInt(argument)) {
+ return inferrer.types.intType;
+ }
return null;
- }
- } else if (name == '|' || name == '^') {
- if (isUInt31(receiver) &&
- arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
- return inferrer.types.uint31Type;
- }
- } else if (name == '>>') {
- if (isUInt31(receiver)) {
- return inferrer.types.uint31Type;
- }
- } else if (name == '&') {
- if (isUInt31(receiver) ||
- arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
- return inferrer.types.uint31Type;
- }
- } else if (name == 'unary-') {
- // The receiver being an int, the return value will also be an
- // int.
- return inferrer.types.intType;
- } else if (name == '-') {
- if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
+
+ case '|':
+ case '^':
+ if (isEmpty(argument)) return tryLater();
+ if (isUInt31(receiver) && isUInt31(argument)) {
+ return inferrer.types.uint31Type;
+ }
+ return null;
+
+ case '>>':
+ if (isEmpty(argument)) return tryLater();
+ if (isUInt31(receiver)) {
+ return inferrer.types.uint31Type;
+ }
+ return null;
+
+ case '&':
+ if (isEmpty(argument)) return tryLater();
+ if (isUInt31(receiver) || isUInt31(argument)) {
+ return inferrer.types.uint31Type;
+ }
+ return null;
+
+ case '-':
+ if (isEmpty(argument)) return tryLater();
+ if (isInt(argument)) {
+ return inferrer.types.intType;
+ }
+ return null;
+
+ case 'unary-':
+ // The receiver being an int, the return value will also be an int.
return inferrer.types.intType;
- } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
- return inferrer.types.nonNullEmptyType;
- }
- return null;
- } else if (name == 'abs') {
- return arguments.hasNoArguments() ? inferrer.types.positiveIntType : null;
+
+ case 'abs':
+ return arguments.hasNoArguments()
+ ? inferrer.types.positiveIntType
+ : null;
+
+ default:
+ return null;
}
- return null;
}
TypeMask computeType(TypeGraphInferrerEngine inferrer) {
« no previous file with comments | « pkg/compiler/lib/src/inferrer/inferrer_visitor.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698