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

Side by Side Diff: pkg/analyzer/test/src/task/strong/checker_test.dart

Issue 1663533002: fixes #25640, errors on function downcasts when we know it's an exact type (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // TODO(jmesserly): this file needs to be refactored, it's a port from 5 // TODO(jmesserly): this file needs to be refactored, it's a port from
6 // package:dev_compiler's tests 6 // package:dev_compiler's tests
7 /// General type checking tests 7 /// General type checking tests
8 library analyzer.test.src.task.strong.checker_test; 8 library analyzer.test.src.task.strong.checker_test;
9 9
10 import 'package:unittest/unittest.dart'; 10 import 'package:unittest/unittest.dart';
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 testChecker('Void subtyping', { 276 testChecker('Void subtyping', {
277 '/main.dart': ''' 277 '/main.dart': '''
278 typedef int Foo(); 278 typedef int Foo();
279 void foo() {} 279 void foo() {}
280 void main () { 280 void main () {
281 Foo x = /*severe:STATIC_TYPE_ERROR*/foo(); 281 Foo x = /*severe:STATIC_TYPE_ERROR*/foo();
282 } 282 }
283 ''' 283 '''
284 }); 284 });
285 285
286 testChecker('Ground type subtyping: dynamic is top', { 286 group('Ground type subtyping:', () {
287 '/main.dart': ''' 287 testChecker('dynamic is top', {
288 '/main.dart': '''
288 289
289 class A {} 290 class A {}
290 class B extends A {} 291 class B extends A {}
291 292
292 void main() { 293 void main() {
293 dynamic y; 294 dynamic y;
294 Object o; 295 Object o;
295 int i = 0; 296 int i = 0;
296 double d = 0.0; 297 double d = 0.0;
297 num n; 298 num n;
298 A a; 299 A a;
299 B b; 300 B b;
300 y = o; 301 y = o;
301 y = i; 302 y = i;
302 y = d; 303 y = d;
303 y = n; 304 y = n;
304 y = a; 305 y = a;
305 y = b; 306 y = b;
306 } 307 }
307 ''' 308 '''
308 }); 309 });
309 310
310 testChecker('Ground type subtyping: dynamic downcasts', { 311 testChecker('dynamic downcasts', {
311 '/main.dart': ''' 312 '/main.dart': '''
312 313
313 class A {} 314 class A {}
314 class B extends A {} 315 class B extends A {}
315 316
316 void main() { 317 void main() {
317 dynamic y; 318 dynamic y;
318 Object o; 319 Object o;
319 int i = 0; 320 int i = 0;
320 double d = 0.0; 321 double d = 0.0;
321 num n; 322 num n;
322 A a; 323 A a;
323 B b; 324 B b;
324 o = y; 325 o = y;
325 i = /*info:DYNAMIC_CAST*/y; 326 i = /*info:DYNAMIC_CAST*/y;
326 d = /*info:DYNAMIC_CAST*/y; 327 d = /*info:DYNAMIC_CAST*/y;
327 n = /*info:DYNAMIC_CAST*/y; 328 n = /*info:DYNAMIC_CAST*/y;
328 a = /*info:DYNAMIC_CAST*/y; 329 a = /*info:DYNAMIC_CAST*/y;
329 b = /*info:DYNAMIC_CAST*/y; 330 b = /*info:DYNAMIC_CAST*/y;
330 } 331 }
331 ''' 332 '''
332 }); 333 });
333 334
334 testChecker('Ground type subtyping: assigning a class', { 335 testChecker('assigning a class', {
335 '/main.dart': ''' 336 '/main.dart': '''
336 337
337 class A {} 338 class A {}
338 class B extends A {} 339 class B extends A {}
339 340
340 void main() { 341 void main() {
341 dynamic y; 342 dynamic y;
342 Object o; 343 Object o;
343 int i = 0; 344 int i = 0;
344 double d = 0.0; 345 double d = 0.0;
345 num n; 346 num n;
346 A a; 347 A a;
347 B b; 348 B b;
348 y = a; 349 y = a;
349 o = a; 350 o = a;
350 i = /*severe:STATIC_TYPE_ERROR*/a; 351 i = /*severe:STATIC_TYPE_ERROR*/a;
351 d = /*severe:STATIC_TYPE_ERROR*/a; 352 d = /*severe:STATIC_TYPE_ERROR*/a;
352 n = /*severe:STATIC_TYPE_ERROR*/a; 353 n = /*severe:STATIC_TYPE_ERROR*/a;
353 a = a; 354 a = a;
354 b = /*info:DOWN_CAST_IMPLICIT*/a; 355 b = /*info:DOWN_CAST_IMPLICIT*/a;
355 } 356 }
356 ''' 357 '''
357 }); 358 });
358 359
359 testChecker('Ground type subtyping: assigning a subclass', { 360 testChecker('assigning a subclass', {
360 '/main.dart': ''' 361 '/main.dart': '''
361 362
362 class A {} 363 class A {}
363 class B extends A {} 364 class B extends A {}
364 class C extends A {} 365 class C extends A {}
365 366
366 void main() { 367 void main() {
367 dynamic y; 368 dynamic y;
368 Object o; 369 Object o;
369 int i = 0; 370 int i = 0;
370 double d = 0.0; 371 double d = 0.0;
371 num n; 372 num n;
372 A a; 373 A a;
373 B b; 374 B b;
374 C c; 375 C c;
375 y = b; 376 y = b;
376 o = b; 377 o = b;
377 i = /*severe:STATIC_TYPE_ERROR*/b; 378 i = /*severe:STATIC_TYPE_ERROR*/b;
378 d = /*severe:STATIC_TYPE_ERROR*/b; 379 d = /*severe:STATIC_TYPE_ERROR*/b;
379 n = /*severe:STATIC_TYPE_ERROR*/b; 380 n = /*severe:STATIC_TYPE_ERROR*/b;
380 a = b; 381 a = b;
381 b = b; 382 b = b;
382 c = /*severe:STATIC_TYPE_ERROR*/b; 383 c = /*severe:STATIC_TYPE_ERROR*/b;
383 } 384 }
384 ''' 385 '''
385 }); 386 });
386 387
387 testChecker('Ground type subtyping: interfaces', { 388 testChecker('interfaces', {
388 '/main.dart': ''' 389 '/main.dart': '''
389 390
390 class A {} 391 class A {}
391 class B extends A {} 392 class B extends A {}
392 class C extends A {} 393 class C extends A {}
393 class D extends B implements C {} 394 class D extends B implements C {}
394 395
395 void main() { 396 void main() {
396 A top; 397 A top;
397 B left; 398 B left;
398 C right; 399 C right;
(...skipping 17 matching lines...) Expand all
416 right = bot; 417 right = bot;
417 } 418 }
418 { 419 {
419 bot = /*info:DOWN_CAST_IMPLICIT*/top; 420 bot = /*info:DOWN_CAST_IMPLICIT*/top;
420 bot = /*info:DOWN_CAST_IMPLICIT*/left; 421 bot = /*info:DOWN_CAST_IMPLICIT*/left;
421 bot = /*info:DOWN_CAST_IMPLICIT*/right; 422 bot = /*info:DOWN_CAST_IMPLICIT*/right;
422 bot = bot; 423 bot = bot;
423 } 424 }
424 } 425 }
425 ''' 426 '''
427 });
426 }); 428 });
427 429
428 testChecker('Function typing and subtyping: int and object', { 430 group('Function typing and subtyping:', () {
429 '/main.dart': ''' 431 testChecker('int and object', {
432 '/main.dart': '''
430 433
431 typedef Object Top(int x); // Top of the lattice 434 typedef Object Top(int x); // Top of the lattice
432 typedef int Left(int x); // Left branch 435 typedef int Left(int x); // Left branch
433 typedef int Left2(int x); // Left branch 436 typedef int Left2(int x); // Left branch
434 typedef Object Right(Object x); // Right branch 437 typedef Object Right(Object x); // Right branch
435 typedef int Bot(Object x); // Bottom of the lattice 438 typedef int Bot(Object x); // Bottom of the lattice
436 439
437 Object top(int x) => x; 440 Object globalTop(int x) => x;
438 int left(int x) => x; 441 int globalLeft(int x) => x;
439 Object right(Object x) => x; 442 Object globalRight(Object x) => x;
440 int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x; 443 int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
441 int bot(Object x) => x as int; 444 int globalBot(Object x) => x as int;
442 445
443 void main() { 446 void main() {
447 // Note: use locals so we only know the type, not that it's a specific
448 // function declaration. (we can issue better errors in that case.)
449 var top = globalTop;
450 var left = globalLeft;
451 var right = globalRight;
452 var bot = globalBot;
vsm 2016/02/03 23:52:00 Perhaps a test to cover the static method case (er
Jennifer Messerly 2016/02/04 00:41:30 instance methods are covered by this test (line 16
453
444 { // Check typedef equality 454 { // Check typedef equality
445 Left f = left; 455 Left f = left;
446 Left2 g = f; 456 Left2 g = f;
447 } 457 }
448 { 458 {
449 Top f; 459 Top f;
450 f = top; 460 f = top;
451 f = left; 461 f = left;
452 f = right; 462 f = right;
453 f = bot; 463 f = bot;
(...skipping 14 matching lines...) Expand all
468 } 478 }
469 { 479 {
470 Bot f; 480 Bot f;
471 f = /*warning:DOWN_CAST_COMPOSITE*/top; 481 f = /*warning:DOWN_CAST_COMPOSITE*/top;
472 f = /*warning:DOWN_CAST_COMPOSITE*/left; 482 f = /*warning:DOWN_CAST_COMPOSITE*/left;
473 f = /*warning:DOWN_CAST_COMPOSITE*/right; 483 f = /*warning:DOWN_CAST_COMPOSITE*/right;
474 f = bot; 484 f = bot;
475 } 485 }
476 } 486 }
477 ''' 487 '''
478 }); 488 });
479 489
480 testChecker('Function typing and subtyping: classes', { 490 testChecker('classes', {
481 '/main.dart': ''' 491 '/main.dart': '''
482 492
483 class A {} 493 class A {}
484 class B extends A {} 494 class B extends A {}
485 495
486 typedef A Top(B x); // Top of the lattice 496 typedef A Top(B x); // Top of the lattice
487 typedef B Left(B x); // Left branch 497 typedef B Left(B x); // Left branch
488 typedef B Left2(B x); // Left branch 498 typedef B Left2(B x); // Left branch
489 typedef A Right(A x); // Right branch 499 typedef A Right(A x); // Right branch
490 typedef B Bot(A x); // Bottom of the lattice 500 typedef B Bot(A x); // Bottom of the lattice
491 501
(...skipping 10 matching lines...) Expand all
502 } 512 }
503 { 513 {
504 Top f; 514 Top f;
505 f = top; 515 f = top;
506 f = left; 516 f = left;
507 f = right; 517 f = right;
508 f = bot; 518 f = bot;
509 } 519 }
510 { 520 {
511 Left f; 521 Left f;
512 f = /*warning:DOWN_CAST_COMPOSITE*/top; 522 f = /*severe:STATIC_TYPE_ERROR*/top;
vsm 2016/02/03 23:52:00 nice!
513 f = left; 523 f = left;
514 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? 524 f = /*severe:STATIC_TYPE_ERROR*/right;
515 f = bot; 525 f = bot;
516 } 526 }
517 { 527 {
518 Right f; 528 Right f;
519 f = /*warning:DOWN_CAST_COMPOSITE*/top; 529 f = /*severe:STATIC_TYPE_ERROR*/top;
520 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? 530 f = /*severe:STATIC_TYPE_ERROR*/left;
521 f = right; 531 f = right;
522 f = bot; 532 f = bot;
523 } 533 }
524 { 534 {
525 Bot f; 535 Bot f;
526 f = /*warning:DOWN_CAST_COMPOSITE*/top; 536 f = /*severe:STATIC_TYPE_ERROR*/top;
527 f = /*warning:DOWN_CAST_COMPOSITE*/left; 537 f = /*severe:STATIC_TYPE_ERROR*/left;
528 f = /*warning:DOWN_CAST_COMPOSITE*/right; 538 f = /*severe:STATIC_TYPE_ERROR*/right;
529 f = bot; 539 f = bot;
530 } 540 }
531 } 541 }
532 ''' 542 '''
533 }); 543 });
534 544
535 testChecker('Function typing and subtyping: dynamic', { 545 testChecker('dynamic', {
536 '/main.dart': ''' 546 '/main.dart': '''
537 547
538 class A {} 548 class A {}
539 549
540 typedef dynamic Top(dynamic x); // Top of the lattice 550 typedef dynamic Top(dynamic x); // Top of the lattice
541 typedef dynamic Left(A x); // Left branch 551 typedef dynamic Left(A x); // Left branch
542 typedef A Right(dynamic x); // Right branch 552 typedef A Right(dynamic x); // Right branch
543 typedef A Bottom(A x); // Bottom of the lattice 553 typedef A Bottom(A x); // Bottom of the lattice
544 554
545 dynamic left(A x) => x; 555 dynamic left(A x) => x;
546 A bot(A x) => x; 556 A bot(A x) => x;
547 dynamic top(dynamic x) => x; 557 dynamic top(dynamic x) => x;
548 A right(dynamic x) => /*info:DYNAMIC_CAST*/x; 558 A right(dynamic x) => /*info:DYNAMIC_CAST*/x;
549 559
550 void main() { 560 void main() {
551 { 561 {
552 Top f; 562 Top f;
553 f = top; 563 f = top;
554 f = left; 564 f = left;
555 f = right; 565 f = right;
556 f = bot; 566 f = bot;
557 } 567 }
558 { 568 {
559 Left f; 569 Left f;
560 f = /*warning:DOWN_CAST_COMPOSITE*/top; 570 f = /*severe:STATIC_TYPE_ERROR*/top;
561 f = left; 571 f = left;
562 f = /*warning:DOWN_CAST_COMPOSITE*/right; 572 f = /*severe:STATIC_TYPE_ERROR*/right;
563 f = bot; 573 f = bot;
564 } 574 }
565 { 575 {
566 Right f; 576 Right f;
567 f = /*warning:DOWN_CAST_COMPOSITE*/top; 577 f = /*severe:STATIC_TYPE_ERROR*/top;
568 f = /*warning:DOWN_CAST_COMPOSITE*/left; 578 f = /*severe:STATIC_TYPE_ERROR*/left;
569 f = right; 579 f = right;
570 f = bot; 580 f = bot;
571 } 581 }
572 { 582 {
573 Bottom f; 583 Bottom f;
574 f = /*warning:DOWN_CAST_COMPOSITE*/top; 584 f = /*severe:STATIC_TYPE_ERROR*/top;
575 f = /*warning:DOWN_CAST_COMPOSITE*/left; 585 f = /*severe:STATIC_TYPE_ERROR*/left;
576 f = /*warning:DOWN_CAST_COMPOSITE*/right; 586 f = /*severe:STATIC_TYPE_ERROR*/right;
577 f = bot; 587 f = bot;
578 } 588 }
579 } 589 }
580 ''' 590 '''
581 }); 591 });
582 592
583 testChecker('Function typing and subtyping: function literal variance', { 593 testChecker('function literal variance', {
584 '/main.dart': ''' 594 '/main.dart': '''
585 595
586 class A {} 596 class A {}
587 class B extends A {} 597 class B extends A {}
588 598
589 typedef T Function2<S, T>(S z); 599 typedef T Function2<S, T>(S z);
590 600
591 A top(B x) => x; 601 A top(B x) => x;
592 B left(B x) => x; 602 B left(B x) => x;
593 A right(A x) => x; 603 A right(A x) => x;
594 B bot(A x) => x as B; 604 B bot(A x) => x as B;
595 605
596 void main() { 606 void main() {
597 { 607 {
598 Function2<B, A> f; 608 Function2<B, A> f;
599 f = top; 609 f = top;
600 f = left; 610 f = left;
601 f = right; 611 f = right;
602 f = bot; 612 f = bot;
603 } 613 }
604 { 614 {
605 Function2<B, B> f; 615 Function2<B, B> f;
606 f = /*warning:DOWN_CAST_COMPOSITE*/top; 616 f = /*severe:STATIC_TYPE_ERROR*/top;
607 f = left; 617 f = left;
608 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? 618 f = /*severe:STATIC_TYPE_ERROR*/right;
609 f = bot; 619 f = bot;
610 } 620 }
611 { 621 {
612 Function2<A, A> f; 622 Function2<A, A> f;
613 f = /*warning:DOWN_CAST_COMPOSITE*/top; 623 f = /*severe:STATIC_TYPE_ERROR*/top;
614 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? 624 f = /*severe:STATIC_TYPE_ERROR*/left;
615 f = right; 625 f = right;
616 f = bot; 626 f = bot;
617 } 627 }
618 { 628 {
619 Function2<A, B> f; 629 Function2<A, B> f;
620 f = /*warning:DOWN_CAST_COMPOSITE*/top; 630 f = /*severe:STATIC_TYPE_ERROR*/top;
621 f = /*warning:DOWN_CAST_COMPOSITE*/left; 631 f = /*severe:STATIC_TYPE_ERROR*/left;
622 f = /*warning:DOWN_CAST_COMPOSITE*/right; 632 f = /*severe:STATIC_TYPE_ERROR*/right;
623 f = bot; 633 f = bot;
624 } 634 }
625 } 635 }
626 ''' 636 '''
627 }); 637 });
628 638
629 testChecker('Function typing and subtyping: function variable variance', { 639 testChecker('function variable variance', {
630 '/main.dart': ''' 640 '/main.dart': '''
631 641
632 class A {} 642 class A {}
633 class B extends A {} 643 class B extends A {}
634 644
635 typedef T Function2<S, T>(S z); 645 typedef T Function2<S, T>(S z);
636 646
637 void main() { 647 void main() {
638 { 648 {
639 Function2<B, A> top; 649 Function2<B, A> top;
640 Function2<B, B> left; 650 Function2<B, B> left;
(...skipping 15 matching lines...) Expand all
656 right = right; 666 right = right;
657 right = bot; 667 right = bot;
658 668
659 bot = /*warning:DOWN_CAST_COMPOSITE*/top; 669 bot = /*warning:DOWN_CAST_COMPOSITE*/top;
660 bot = /*warning:DOWN_CAST_COMPOSITE*/left; 670 bot = /*warning:DOWN_CAST_COMPOSITE*/left;
661 bot = /*warning:DOWN_CAST_COMPOSITE*/right; 671 bot = /*warning:DOWN_CAST_COMPOSITE*/right;
662 bot = bot; 672 bot = bot;
663 } 673 }
664 } 674 }
665 ''' 675 '''
666 }); 676 });
667 677
668 testChecker('Function typing and subtyping: higher order function literals', { 678 testChecker('higher order function literals 1', {
669 '/main.dart': ''' 679 '/main.dart': '''
670 680
671 class A {} 681 class A {}
672 class B extends A {} 682 class B extends A {}
673 683
674 typedef T Function2<S, T>(S z); 684 typedef T Function2<S, T>(S z);
675 685
676 typedef A BToA(B x); // Top of the base lattice 686 typedef A BToA(B x); // Top of the base lattice
677 typedef B AToB(A x); // Bot of the base lattice 687 typedef B AToB(A x); // Bot of the base lattice
678 688
679 BToA top(AToB f) => f; 689 BToA top(AToB f) => f;
680 AToB left(AToB f) => f; 690 AToB left(AToB f) => f;
681 BToA right(BToA f) => f; 691 BToA right(BToA f) => f;
682 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; 692 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
683 AToB bot(BToA f) => f as AToB; 693 AToB bot(BToA f) => f as AToB;
Jennifer Messerly 2016/02/02 22:15:05 it's hard to see in the diff, but the original cod
684 694
695 void main() {
696 {
697 Function2<AToB, BToA> f; // Top
698 f = top;
699 f = left;
700 f = right;
701 f = bot;
702 }
703 {
704 Function2<AToB, AToB> f; // Left
705 f = /*severe:STATIC_TYPE_ERROR*/top;
706 f = left;
707 f = /*severe:STATIC_TYPE_ERROR*/right;
708 f = bot;
709 }
710 {
711 Function2<BToA, BToA> f; // Right
712 f = /*severe:STATIC_TYPE_ERROR*/top;
713 f = /*severe:STATIC_TYPE_ERROR*/left;
714 f = right;
715 f = bot;
716 }
717 {
718 Function2<BToA, AToB> f; // Bot
719 f = bot;
720 f = /*severe:STATIC_TYPE_ERROR*/left;
721 f = /*severe:STATIC_TYPE_ERROR*/top;
722 f = /*severe:STATIC_TYPE_ERROR*/left;
723 }
724 }
725 '''
726 });
727
728 testChecker('higher order function literals 2', {
729 '/main.dart': '''
730
731 class A {}
732 class B extends A {}
733
734 typedef T Function2<S, T>(S z);
735
736 typedef A BToA(B x); // Top of the base lattice
737 typedef B AToB(A x); // Bot of the base lattice
738
685 Function2<B, A> top(AToB f) => f; 739 Function2<B, A> top(AToB f) => f;
686 Function2<A, B> left(AToB f) => f; 740 Function2<A, B> left(AToB f) => f;
687 Function2<B, A> right(BToA f) => f; 741 Function2<B, A> right(BToA f) => f;
688 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; 742 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
689 Function2<A, B> bot(BToA f) => f as Function2<A, B>; 743 Function2<A, B> bot(BToA f) => f as Function2<A, B>;
690 744
745 void main() {
746 {
747 Function2<AToB, BToA> f; // Top
748 f = top;
749 f = left;
750 f = right;
751 f = bot;
752 }
753 {
754 Function2<AToB, AToB> f; // Left
755 f = /*severe:STATIC_TYPE_ERROR*/top;
756 f = left;
757 f = /*severe:STATIC_TYPE_ERROR*/right;
758 f = bot;
759 }
760 {
761 Function2<BToA, BToA> f; // Right
762 f = /*severe:STATIC_TYPE_ERROR*/top;
763 f = /*severe:STATIC_TYPE_ERROR*/left;
764 f = right;
765 f = bot;
766 }
767 {
768 Function2<BToA, AToB> f; // Bot
769 f = bot;
770 f = /*severe:STATIC_TYPE_ERROR*/left;
771 f = /*severe:STATIC_TYPE_ERROR*/top;
772 f = /*severe:STATIC_TYPE_ERROR*/left;
773 }
774 }
775 '''
776 });
777
778 testChecker('higher order function literals 3', {
779 '/main.dart': '''
780
781 class A {}
782 class B extends A {}
783
784 typedef T Function2<S, T>(S z);
785
786 typedef A BToA(B x); // Top of the base lattice
787 typedef B AToB(A x); // Bot of the base lattice
691 788
692 BToA top(Function2<A, B> f) => f; 789 BToA top(Function2<A, B> f) => f;
693 AToB left(Function2<A, B> f) => f; 790 AToB left(Function2<A, B> f) => f;
694 BToA right(Function2<B, A> f) => f; 791 BToA right(Function2<B, A> f) => f;
695 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; 792 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
696 AToB bot(Function2<B, A> f) => f as AToB; 793 AToB bot(Function2<B, A> f) => f as AToB;
697 794
698 void main() { 795 void main() {
699 { 796 {
700 Function2<AToB, BToA> f; // Top 797 Function2<AToB, BToA> f; // Top
701 f = top; 798 f = top;
702 f = left; 799 f = left;
703 f = right; 800 f = right;
704 f = bot; 801 f = bot;
705 } 802 }
706 { 803 {
707 Function2<AToB, AToB> f; // Left 804 Function2<AToB, AToB> f; // Left
708 f = /*warning:DOWN_CAST_COMPOSITE*/top; 805 f = /*severe:STATIC_TYPE_ERROR*/top;
709 f = left; 806 f = left;
710 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? 807 f = /*severe:STATIC_TYPE_ERROR*/right;
711 f = bot; 808 f = bot;
712 } 809 }
713 { 810 {
714 Function2<BToA, BToA> f; // Right 811 Function2<BToA, BToA> f; // Right
715 f = /*warning:DOWN_CAST_COMPOSITE*/top; 812 f = /*severe:STATIC_TYPE_ERROR*/top;
716 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? 813 f = /*severe:STATIC_TYPE_ERROR*/left;
717 f = right; 814 f = right;
718 f = bot; 815 f = bot;
719 } 816 }
720 { 817 {
721 Function2<BToA, AToB> f; // Bot 818 Function2<BToA, AToB> f; // Bot
722 f = bot; 819 f = bot;
723 f = /*warning:DOWN_CAST_COMPOSITE*/left; 820 f = /*severe:STATIC_TYPE_ERROR*/left;
724 f = /*warning:DOWN_CAST_COMPOSITE*/top; 821 f = /*severe:STATIC_TYPE_ERROR*/top;
725 f = /*warning:DOWN_CAST_COMPOSITE*/left; 822 f = /*severe:STATIC_TYPE_ERROR*/left;
726 } 823 }
727 } 824 }
728 ''' 825 '''
729 }); 826 });
730 827
731 testChecker( 828 testChecker('higher order function variables', {
732 'Function typing and subtyping: higher order function variables', { 829 '/main.dart': '''
733 '/main.dart': '''
734 830
735 class A {} 831 class A {}
736 class B extends A {} 832 class B extends A {}
737 833
738 typedef T Function2<S, T>(S z); 834 typedef T Function2<S, T>(S z);
739 835
740 void main() { 836 void main() {
741 { 837 {
742 Function2<Function2<A, B>, Function2<B, A>> top; 838 Function2<Function2<A, B>, Function2<B, A>> top;
743 Function2<Function2<B, A>, Function2<B, A>> right; 839 Function2<Function2<B, A>, Function2<B, A>> right;
(...skipping 17 matching lines...) Expand all
761 right = right; 857 right = right;
762 right = bot; 858 right = bot;
763 859
764 bot = /*warning:DOWN_CAST_COMPOSITE*/top; 860 bot = /*warning:DOWN_CAST_COMPOSITE*/top;
765 bot = /*warning:DOWN_CAST_COMPOSITE*/left; 861 bot = /*warning:DOWN_CAST_COMPOSITE*/left;
766 bot = /*warning:DOWN_CAST_COMPOSITE*/right; 862 bot = /*warning:DOWN_CAST_COMPOSITE*/right;
767 bot = bot; 863 bot = bot;
768 } 864 }
769 } 865 }
770 ''' 866 '''
771 }); 867 });
772 868
773 testChecker('Function typing and subtyping: named and optional parameters', { 869 testChecker('named and optional parameters', {
774 '/main.dart': ''' 870 '/main.dart': '''
775 871
776 class A {} 872 class A {}
777 873
778 typedef A FR(A x); 874 typedef A FR(A x);
779 typedef A FO([A x]); 875 typedef A FO([A x]);
780 typedef A FN({A x}); 876 typedef A FN({A x});
781 typedef A FRR(A x, A y); 877 typedef A FRR(A x, A y);
782 typedef A FRO(A x, [A y]); 878 typedef A FRO(A x, [A y]);
783 typedef A FRN(A x, {A n}); 879 typedef A FRN(A x, {A n});
784 typedef A FOO([A x, A y]); 880 typedef A FOO([A x, A y]);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 nnn = /*severe:STATIC_TYPE_ERROR*/o; 976 nnn = /*severe:STATIC_TYPE_ERROR*/o;
881 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; 977 nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
882 nnn = /*severe:STATIC_TYPE_ERROR*/rr; 978 nnn = /*severe:STATIC_TYPE_ERROR*/rr;
883 nnn = /*severe:STATIC_TYPE_ERROR*/ro; 979 nnn = /*severe:STATIC_TYPE_ERROR*/ro;
884 nnn = /*severe:STATIC_TYPE_ERROR*/rn; 980 nnn = /*severe:STATIC_TYPE_ERROR*/rn;
885 nnn = /*severe:STATIC_TYPE_ERROR*/oo; 981 nnn = /*severe:STATIC_TYPE_ERROR*/oo;
886 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; 982 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
887 nnn = nnn; 983 nnn = nnn;
888 } 984 }
889 ''' 985 '''
890 }); 986 });
891 987
892 testChecker('Function subtyping: objects with call methods', { 988 testChecker('Function subtyping: objects with call methods', {
893 '/main.dart': ''' 989 '/main.dart': '''
894 990
895 typedef int I2I(int x); 991 typedef int I2I(int x);
896 typedef num N2N(num x); 992 typedef num N2N(num x);
897 class A { 993 class A {
898 int call(int x) => x; 994 int call(int x) => x;
899 } 995 }
900 class B { 996 class B {
901 num call(num x) => x; 997 num call(num x) => x;
902 } 998 }
903 int i2i(int x) => x; 999 int i2i(int x) => x;
904 num n2n(num x) => x; 1000 num n2n(num x) => x;
905 void main() { 1001 void main() {
906 { 1002 {
907 I2I f; 1003 I2I f;
908 f = new A(); 1004 f = new A();
909 f = /*severe:STATIC_TYPE_ERROR*/new B(); 1005 f = /*severe:STATIC_TYPE_ERROR*/new B();
910 f = i2i; 1006 f = i2i;
911 f = /*warning:DOWN_CAST_COMPOSITE*/n2n; 1007 f = /*severe:STATIC_TYPE_ERROR*/n2n;
912 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; 1008 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
913 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; 1009 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
914 } 1010 }
915 { 1011 {
916 N2N f; 1012 N2N f;
917 f = /*severe:STATIC_TYPE_ERROR*/new A(); 1013 f = /*severe:STATIC_TYPE_ERROR*/new A();
918 f = new B(); 1014 f = new B();
919 f = /*warning:DOWN_CAST_COMPOSITE*/i2i; 1015 f = /*severe:STATIC_TYPE_ERROR*/i2i;
920 f = n2n; 1016 f = n2n;
921 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; 1017 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
922 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; 1018 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
923 } 1019 }
924 { 1020 {
925 A f; 1021 A f;
926 f = new A(); 1022 f = new A();
927 f = /*severe:STATIC_TYPE_ERROR*/new B(); 1023 f = /*severe:STATIC_TYPE_ERROR*/new B();
928 f = /*severe:STATIC_TYPE_ERROR*/i2i; 1024 f = /*severe:STATIC_TYPE_ERROR*/i2i;
929 f = /*severe:STATIC_TYPE_ERROR*/n2n; 1025 f = /*severe:STATIC_TYPE_ERROR*/n2n;
(...skipping 13 matching lines...) Expand all
943 Function f; 1039 Function f;
944 f = new A(); 1040 f = new A();
945 f = new B(); 1041 f = new B();
946 f = i2i; 1042 f = i2i;
947 f = n2n; 1043 f = n2n;
948 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; 1044 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
949 f = (n2n as Function); 1045 f = (n2n as Function);
950 } 1046 }
951 } 1047 }
952 ''' 1048 '''
953 }); 1049 });
954 1050
955 testChecker('Function typing and subtyping: void', { 1051 testChecker('void', {
956 '/main.dart': ''' 1052 '/main.dart': '''
957 1053
958 class A { 1054 class A {
959 void bar() => null; 1055 void bar() => null;
960 void foo() => bar; // allowed 1056 void foo() => bar; // allowed
961 } 1057 }
962 ''' 1058 '''
963 }); 1059 });
964 1060
965 testChecker('Function subtyping: uninferred closure', { 1061 testChecker('uninferred closure', {
966 '/main.dart': ''' 1062 '/main.dart': '''
967 typedef num Num2Num(num x); 1063 typedef num Num2Num(num x);
968 void main() { 1064 void main() {
969 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; }; 1065 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
970 print(g(42)); 1066 print(g(42));
971 } 1067 }
972 ''' 1068 '''
1069 });
973 }); 1070 });
974 1071
975 testChecker('Relaxed casts', { 1072 testChecker('Relaxed casts', {
976 '/main.dart': ''' 1073 '/main.dart': '''
977 1074
978 class A {} 1075 class A {}
979 1076
980 class L<T> {} 1077 class L<T> {}
981 class M<T> extends L<T> {} 1078 class M<T> extends L<T> {}
982 // L<dynamic|Object> 1079 // L<dynamic|Object>
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 /*=S*/ then/*<S>*/(Object onValue(T t)) => null; 1506 /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
1410 } 1507 }
1411 1508
1412 class DerivedFuture4<A> extends Future<A> { 1509 class DerivedFuture4<A> extends Future<A> {
1413 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; 1510 /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
1414 } 1511 }
1415 ''' 1512 '''
1416 }); 1513 });
1417 1514
1418 testChecker('generic function wrong number of arguments', { 1515 testChecker('generic function wrong number of arguments', {
1419 '/main.dart': r''' 1516 '/main.dart': r'''
1420 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; 1517 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
1421 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; 1518 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
1422 1519
1423 main() { 1520 main() {
1424 // resolving thses shouldn't crash. 1521 // resolving thses shouldn't crash.
1425 foo(1, 2, 3); 1522 foo(1, 2, 3);
1426 String x = foo('1', '2', '3'); 1523 String x = foo('1', '2', '3');
1427 foo(1); 1524 foo(1);
1428 String x = foo('1'); 1525 String x = foo('1');
1429 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); 1526 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3);
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 2657
2561 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } 2658 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
2562 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } 2659 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
2563 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); } 2660 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
2564 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } 2661 Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
2565 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); } 2662 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); }
2566 ''' 2663 '''
2567 }); 2664 });
2568 }); 2665 });
2569 } 2666 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698