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

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;
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;
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('static method variance', {
669 '/main.dart': ''' 679 '/main.dart': '''
670 680
671 class A {} 681 class A {}
672 class B extends A {} 682 class B extends A {}
683
684 class C {
685 static A top(B x) => x;
686 static B left(B x) => x;
687 static A right(A x) => x;
688 static B bot(A x) => x as B;
689 }
690
691 typedef T Function2<S, T>(S z);
692
693 void main() {
694 {
695 Function2<B, A> f;
696 f = C.top;
697 f = C.left;
698 f = C.right;
699 f = C.bot;
700 }
701 {
702 Function2<B, B> f;
703 f = /*severe:STATIC_TYPE_ERROR*/C.top;
704 f = C.left;
705 f = /*severe:STATIC_TYPE_ERROR*/C.right;
706 f = C.bot;
707 }
708 {
709 Function2<A, A> f;
710 f = /*severe:STATIC_TYPE_ERROR*/C.top;
711 f = /*severe:STATIC_TYPE_ERROR*/C.left;
712 f = C.right;
713 f = C.bot;
714 }
715 {
716 Function2<A, B> f;
717 f = /*severe:STATIC_TYPE_ERROR*/C.top;
718 f = /*severe:STATIC_TYPE_ERROR*/C.left;
719 f = /*severe:STATIC_TYPE_ERROR*/C.right;
720 f = C.bot;
721 }
722 }
723 '''
724 });
725
726 testChecker('instance method variance', {
727 '/main.dart': '''
728
729 class A {}
730 class B extends A {}
731
732 class C {
733 A top(B x) => x;
734 B left(B x) => x;
735 A right(A x) => x;
736 B bot(A x) => x as B;
737 }
738
739 typedef T Function2<S, T>(S z);
740
741 void main() {
742 C c = new C();
743 {
744 Function2<B, A> f;
745 f = c.top;
746 f = c.left;
747 f = c.right;
748 f = c.bot;
749 }
750 {
751 Function2<B, B> f;
752 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
753 f = c.left;
754 f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
755 f = c.bot;
756 }
757 {
758 Function2<A, A> f;
759 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
760 f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
761 f = c.right;
762 f = c.bot;
763 }
764 {
765 Function2<A, B> f;
766 f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
767 f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
768 f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
769 f = c.bot;
770 }
771 }
772 '''
773 });
774
775 testChecker('higher order function literals 1', {
776 '/main.dart': '''
777
778 class A {}
779 class B extends A {}
673 780
674 typedef T Function2<S, T>(S z); 781 typedef T Function2<S, T>(S z);
675 782
676 typedef A BToA(B x); // Top of the base lattice 783 typedef A BToA(B x); // Top of the base lattice
677 typedef B AToB(A x); // Bot of the base lattice 784 typedef B AToB(A x); // Bot of the base lattice
678 785
679 BToA top(AToB f) => f; 786 BToA top(AToB f) => f;
680 AToB left(AToB f) => f; 787 AToB left(AToB f) => f;
681 BToA right(BToA f) => f; 788 BToA right(BToA f) => f;
682 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; 789 AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
683 AToB bot(BToA f) => f as AToB; 790 AToB bot(BToA f) => f as AToB;
684 791
792 void main() {
793 {
794 Function2<AToB, BToA> f; // Top
795 f = top;
796 f = left;
797 f = right;
798 f = bot;
799 }
800 {
801 Function2<AToB, AToB> f; // Left
802 f = /*severe:STATIC_TYPE_ERROR*/top;
803 f = left;
804 f = /*severe:STATIC_TYPE_ERROR*/right;
805 f = bot;
806 }
807 {
808 Function2<BToA, BToA> f; // Right
809 f = /*severe:STATIC_TYPE_ERROR*/top;
810 f = /*severe:STATIC_TYPE_ERROR*/left;
811 f = right;
812 f = bot;
813 }
814 {
815 Function2<BToA, AToB> f; // Bot
816 f = bot;
817 f = /*severe:STATIC_TYPE_ERROR*/left;
818 f = /*severe:STATIC_TYPE_ERROR*/top;
819 f = /*severe:STATIC_TYPE_ERROR*/left;
820 }
821 }
822 '''
823 });
824
825 testChecker('higher order function literals 2', {
826 '/main.dart': '''
827
828 class A {}
829 class B extends A {}
830
831 typedef T Function2<S, T>(S z);
832
833 typedef A BToA(B x); // Top of the base lattice
834 typedef B AToB(A x); // Bot of the base lattice
835
685 Function2<B, A> top(AToB f) => f; 836 Function2<B, A> top(AToB f) => f;
686 Function2<A, B> left(AToB f) => f; 837 Function2<A, B> left(AToB f) => f;
687 Function2<B, A> right(BToA f) => f; 838 Function2<B, A> right(BToA f) => f;
688 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f; 839 Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
689 Function2<A, B> bot(BToA f) => f as Function2<A, B>; 840 Function2<A, B> bot(BToA f) => f as Function2<A, B>;
690 841
842 void main() {
843 {
844 Function2<AToB, BToA> f; // Top
845 f = top;
846 f = left;
847 f = right;
848 f = bot;
849 }
850 {
851 Function2<AToB, AToB> f; // Left
852 f = /*severe:STATIC_TYPE_ERROR*/top;
853 f = left;
854 f = /*severe:STATIC_TYPE_ERROR*/right;
855 f = bot;
856 }
857 {
858 Function2<BToA, BToA> f; // Right
859 f = /*severe:STATIC_TYPE_ERROR*/top;
860 f = /*severe:STATIC_TYPE_ERROR*/left;
861 f = right;
862 f = bot;
863 }
864 {
865 Function2<BToA, AToB> f; // Bot
866 f = bot;
867 f = /*severe:STATIC_TYPE_ERROR*/left;
868 f = /*severe:STATIC_TYPE_ERROR*/top;
869 f = /*severe:STATIC_TYPE_ERROR*/left;
870 }
871 }
872 '''
873 });
874
875 testChecker('higher order function literals 3', {
876 '/main.dart': '''
877
878 class A {}
879 class B extends A {}
880
881 typedef T Function2<S, T>(S z);
882
883 typedef A BToA(B x); // Top of the base lattice
884 typedef B AToB(A x); // Bot of the base lattice
691 885
692 BToA top(Function2<A, B> f) => f; 886 BToA top(Function2<A, B> f) => f;
693 AToB left(Function2<A, B> f) => f; 887 AToB left(Function2<A, B> f) => f;
694 BToA right(Function2<B, A> f) => f; 888 BToA right(Function2<B, A> f) => f;
695 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f; 889 AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
696 AToB bot(Function2<B, A> f) => f as AToB; 890 AToB bot(Function2<B, A> f) => f as AToB;
697 891
698 void main() { 892 void main() {
699 { 893 {
700 Function2<AToB, BToA> f; // Top 894 Function2<AToB, BToA> f; // Top
701 f = top; 895 f = top;
702 f = left; 896 f = left;
703 f = right; 897 f = right;
704 f = bot; 898 f = bot;
705 } 899 }
706 { 900 {
707 Function2<AToB, AToB> f; // Left 901 Function2<AToB, AToB> f; // Left
708 f = /*warning:DOWN_CAST_COMPOSITE*/top; 902 f = /*severe:STATIC_TYPE_ERROR*/top;
709 f = left; 903 f = left;
710 f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this? 904 f = /*severe:STATIC_TYPE_ERROR*/right;
711 f = bot; 905 f = bot;
712 } 906 }
713 { 907 {
714 Function2<BToA, BToA> f; // Right 908 Function2<BToA, BToA> f; // Right
715 f = /*warning:DOWN_CAST_COMPOSITE*/top; 909 f = /*severe:STATIC_TYPE_ERROR*/top;
716 f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this? 910 f = /*severe:STATIC_TYPE_ERROR*/left;
717 f = right; 911 f = right;
718 f = bot; 912 f = bot;
719 } 913 }
720 { 914 {
721 Function2<BToA, AToB> f; // Bot 915 Function2<BToA, AToB> f; // Bot
722 f = bot; 916 f = bot;
723 f = /*warning:DOWN_CAST_COMPOSITE*/left; 917 f = /*severe:STATIC_TYPE_ERROR*/left;
724 f = /*warning:DOWN_CAST_COMPOSITE*/top; 918 f = /*severe:STATIC_TYPE_ERROR*/top;
725 f = /*warning:DOWN_CAST_COMPOSITE*/left; 919 f = /*severe:STATIC_TYPE_ERROR*/left;
726 } 920 }
727 } 921 }
728 ''' 922 '''
729 }); 923 });
730 924
731 testChecker( 925 testChecker('higher order function variables', {
732 'Function typing and subtyping: higher order function variables', { 926 '/main.dart': '''
733 '/main.dart': '''
734 927
735 class A {} 928 class A {}
736 class B extends A {} 929 class B extends A {}
737 930
738 typedef T Function2<S, T>(S z); 931 typedef T Function2<S, T>(S z);
739 932
740 void main() { 933 void main() {
741 { 934 {
742 Function2<Function2<A, B>, Function2<B, A>> top; 935 Function2<Function2<A, B>, Function2<B, A>> top;
743 Function2<Function2<B, A>, Function2<B, A>> right; 936 Function2<Function2<B, A>, Function2<B, A>> right;
(...skipping 17 matching lines...) Expand all
761 right = right; 954 right = right;
762 right = bot; 955 right = bot;
763 956
764 bot = /*warning:DOWN_CAST_COMPOSITE*/top; 957 bot = /*warning:DOWN_CAST_COMPOSITE*/top;
765 bot = /*warning:DOWN_CAST_COMPOSITE*/left; 958 bot = /*warning:DOWN_CAST_COMPOSITE*/left;
766 bot = /*warning:DOWN_CAST_COMPOSITE*/right; 959 bot = /*warning:DOWN_CAST_COMPOSITE*/right;
767 bot = bot; 960 bot = bot;
768 } 961 }
769 } 962 }
770 ''' 963 '''
771 }); 964 });
772 965
773 testChecker('Function typing and subtyping: named and optional parameters', { 966 testChecker('named and optional parameters', {
774 '/main.dart': ''' 967 '/main.dart': '''
775 968
776 class A {} 969 class A {}
777 970
778 typedef A FR(A x); 971 typedef A FR(A x);
779 typedef A FO([A x]); 972 typedef A FO([A x]);
780 typedef A FN({A x}); 973 typedef A FN({A x});
781 typedef A FRR(A x, A y); 974 typedef A FRR(A x, A y);
782 typedef A FRO(A x, [A y]); 975 typedef A FRO(A x, [A y]);
783 typedef A FRN(A x, {A n}); 976 typedef A FRN(A x, {A n});
784 typedef A FOO([A x, A y]); 977 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; 1073 nnn = /*severe:STATIC_TYPE_ERROR*/o;
881 nnn = /*warning:DOWN_CAST_COMPOSITE*/n; 1074 nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
882 nnn = /*severe:STATIC_TYPE_ERROR*/rr; 1075 nnn = /*severe:STATIC_TYPE_ERROR*/rr;
883 nnn = /*severe:STATIC_TYPE_ERROR*/ro; 1076 nnn = /*severe:STATIC_TYPE_ERROR*/ro;
884 nnn = /*severe:STATIC_TYPE_ERROR*/rn; 1077 nnn = /*severe:STATIC_TYPE_ERROR*/rn;
885 nnn = /*severe:STATIC_TYPE_ERROR*/oo; 1078 nnn = /*severe:STATIC_TYPE_ERROR*/oo;
886 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn; 1079 nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
887 nnn = nnn; 1080 nnn = nnn;
888 } 1081 }
889 ''' 1082 '''
890 }); 1083 });
891 1084
892 testChecker('Function subtyping: objects with call methods', { 1085 testChecker('Function subtyping: objects with call methods', {
893 '/main.dart': ''' 1086 '/main.dart': '''
894 1087
895 typedef int I2I(int x); 1088 typedef int I2I(int x);
896 typedef num N2N(num x); 1089 typedef num N2N(num x);
897 class A { 1090 class A {
898 int call(int x) => x; 1091 int call(int x) => x;
899 } 1092 }
900 class B { 1093 class B {
901 num call(num x) => x; 1094 num call(num x) => x;
902 } 1095 }
903 int i2i(int x) => x; 1096 int i2i(int x) => x;
904 num n2n(num x) => x; 1097 num n2n(num x) => x;
905 void main() { 1098 void main() {
906 { 1099 {
907 I2I f; 1100 I2I f;
908 f = new A(); 1101 f = new A();
909 f = /*severe:STATIC_TYPE_ERROR*/new B(); 1102 f = /*severe:STATIC_TYPE_ERROR*/new B();
910 f = i2i; 1103 f = i2i;
911 f = /*warning:DOWN_CAST_COMPOSITE*/n2n; 1104 f = /*severe:STATIC_TYPE_ERROR*/n2n;
912 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; 1105 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
913 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; 1106 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
914 } 1107 }
915 { 1108 {
916 N2N f; 1109 N2N f;
917 f = /*severe:STATIC_TYPE_ERROR*/new A(); 1110 f = /*severe:STATIC_TYPE_ERROR*/new A();
918 f = new B(); 1111 f = new B();
919 f = /*warning:DOWN_CAST_COMPOSITE*/i2i; 1112 f = /*severe:STATIC_TYPE_ERROR*/i2i;
920 f = n2n; 1113 f = n2n;
921 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object; 1114 f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
922 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function; 1115 f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
923 } 1116 }
924 { 1117 {
925 A f; 1118 A f;
926 f = new A(); 1119 f = new A();
927 f = /*severe:STATIC_TYPE_ERROR*/new B(); 1120 f = /*severe:STATIC_TYPE_ERROR*/new B();
928 f = /*severe:STATIC_TYPE_ERROR*/i2i; 1121 f = /*severe:STATIC_TYPE_ERROR*/i2i;
929 f = /*severe:STATIC_TYPE_ERROR*/n2n; 1122 f = /*severe:STATIC_TYPE_ERROR*/n2n;
(...skipping 13 matching lines...) Expand all
943 Function f; 1136 Function f;
944 f = new A(); 1137 f = new A();
945 f = new B(); 1138 f = new B();
946 f = i2i; 1139 f = i2i;
947 f = n2n; 1140 f = n2n;
948 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object; 1141 f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
949 f = (n2n as Function); 1142 f = (n2n as Function);
950 } 1143 }
951 } 1144 }
952 ''' 1145 '''
953 }); 1146 });
954 1147
955 testChecker('Function typing and subtyping: void', { 1148 testChecker('void', {
956 '/main.dart': ''' 1149 '/main.dart': '''
957 1150
958 class A { 1151 class A {
959 void bar() => null; 1152 void bar() => null;
960 void foo() => bar; // allowed 1153 void foo() => bar; // allowed
961 } 1154 }
962 ''' 1155 '''
963 }); 1156 });
964 1157
965 testChecker('Function subtyping: uninferred closure', { 1158 testChecker('uninferred closure', {
966 '/main.dart': ''' 1159 '/main.dart': '''
967 typedef num Num2Num(num x); 1160 typedef num Num2Num(num x);
968 void main() { 1161 void main() {
969 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; }; 1162 Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
970 print(g(42)); 1163 print(g(42));
971 } 1164 }
972 ''' 1165 '''
1166 });
973 }); 1167 });
974 1168
975 testChecker('Relaxed casts', { 1169 testChecker('Relaxed casts', {
976 '/main.dart': ''' 1170 '/main.dart': '''
977 1171
978 class A {} 1172 class A {}
979 1173
980 class L<T> {} 1174 class L<T> {}
981 class M<T> extends L<T> {} 1175 class M<T> extends L<T> {}
982 // L<dynamic|Object> 1176 // L<dynamic|Object>
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 /*=S*/ then/*<S>*/(Object onValue(T t)) => null; 1603 /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
1410 } 1604 }
1411 1605
1412 class DerivedFuture4<A> extends Future<A> { 1606 class DerivedFuture4<A> extends Future<A> {
1413 /*=B*/ then/*<B>*/(Object onValue(A a)) => null; 1607 /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
1414 } 1608 }
1415 ''' 1609 '''
1416 }); 1610 });
1417 1611
1418 testChecker('generic function wrong number of arguments', { 1612 testChecker('generic function wrong number of arguments', {
1419 '/main.dart': r''' 1613 '/main.dart': r'''
1420 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x; 1614 /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
1421 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x; 1615 /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
1422 1616
1423 main() { 1617 main() {
1424 // resolving thses shouldn't crash. 1618 // resolving thses shouldn't crash.
1425 foo(1, 2, 3); 1619 foo(1, 2, 3);
1426 String x = foo('1', '2', '3'); 1620 String x = foo('1', '2', '3');
1427 foo(1); 1621 foo(1);
1428 String x = foo('1'); 1622 String x = foo('1');
1429 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3); 1623 x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3);
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 2754
2561 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); } 2755 baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
2562 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); } 2756 Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
2563 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); } 2757 Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
2564 Iterable<int> baz4() sync* { yield* new Iterable<int>(); } 2758 Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
2565 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); } 2759 Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/ne w Iterable()); }
2566 ''' 2760 '''
2567 }); 2761 });
2568 }); 2762 });
2569 } 2763 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/task/strong/info.dart ('k') | pkg/analyzer/test/src/task/strong/inferred_type_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698