@@ -1442,25 +1442,49 @@ fn valid_range_bounds(tcx: ty::ctxt, from: @ast::expr, to: @ast::expr)
1442
1442
ast_util:: compare_lit_exprs ( tcx, from, to) <= 0
1443
1443
}
1444
1444
1445
- fn check_pat_variant ( fcx : @fn_ctxt , map : pat_util:: pat_id_map ,
1446
- pat : @ast:: pat , path : @ast:: path , subpats : [ @ast:: pat ] ,
1447
- expected : ty:: t ) {
1445
+ type pat_ctxt = {
1446
+ fcx : @fn_ctxt ,
1447
+ map : pat_util:: pat_id_map ,
1448
+ alt_region : ty:: region ,
1449
+ block_region : ty:: region ,
1450
+ /* Equal to either alt_region or block_region. */
1451
+ pat_region : ty:: region
1452
+ } ;
1453
+
1454
+ fn instantiate_self_regions ( pcx : pat_ctxt , args : [ ty:: t ] ) -> [ ty:: t ] {
1455
+ vec:: map ( args, { |arg_ty|
1456
+ if ty:: type_has_rptrs ( arg_ty) {
1457
+ ty:: fold_ty ( pcx. fcx . ccx . tcx , ty:: fm_rptr ( { |r|
1458
+ alt r {
1459
+ ty : : re_inferred | ty:: re_caller ( _) { pcx. pat_region }
1460
+ _ { r }
1461
+ }
1462
+ } ) , arg_ty)
1463
+ } else {
1464
+ arg_ty
1465
+ }
1466
+ } )
1467
+ }
1468
+
1469
+ fn check_pat_variant ( pcx : pat_ctxt , pat : @ast:: pat , path : @ast:: path ,
1470
+ subpats : [ @ast:: pat ] , expected : ty:: t ) {
1448
1471
// Typecheck the path.
1449
- let tcx = fcx. ccx . tcx ;
1450
- let v_def = lookup_def ( fcx, path. span , pat. id ) ;
1472
+ let tcx = pcx . fcx . ccx . tcx ;
1473
+ let v_def = lookup_def ( pcx . fcx , path. span , pat. id ) ;
1451
1474
let v_def_ids = ast_util:: variant_def_ids ( v_def) ;
1452
1475
let ctor_tpt = ty:: lookup_item_type ( tcx, v_def_ids. enm ) ;
1453
- instantiate_path ( fcx, path, ctor_tpt, pat. span , pat. id ) ;
1476
+ instantiate_path ( pcx . fcx , path, ctor_tpt, pat. span , pat. id ) ;
1454
1477
1455
1478
// Take the enum type params out of `expected`.
1456
- alt structure_of ( fcx, pat. span , expected) {
1479
+ alt structure_of ( pcx . fcx , pat. span , expected) {
1457
1480
ty:: ty_enum ( _, expected_tps) {
1458
1481
let ctor_ty = ty:: node_id_to_type ( tcx, pat. id ) ;
1459
- demand:: with_substs ( fcx, pat. span , expected, ctor_ty,
1482
+ demand:: with_substs ( pcx . fcx , pat. span , expected, ctor_ty,
1460
1483
expected_tps) ;
1461
1484
// Get the number of arguments in this enum variant.
1462
- let arg_types = variant_arg_types ( fcx. ccx , pat. span ,
1485
+ let arg_types = variant_arg_types ( pcx . fcx . ccx , pat. span ,
1463
1486
v_def_ids. var , expected_tps) ;
1487
+ arg_types = instantiate_self_regions ( pcx, arg_types) ;
1464
1488
let subpats_len = subpats. len ( ) , arg_len = arg_types. len ( ) ;
1465
1489
if arg_len > 0 u {
1466
1490
// N-ary variant.
@@ -1475,7 +1499,7 @@ fn check_pat_variant(fcx: @fn_ctxt, map: pat_util::pat_id_map,
1475
1499
}
1476
1500
1477
1501
vec:: iter2 ( subpats, arg_types) { |subpat, arg_ty|
1478
- check_pat ( fcx , map , subpat, arg_ty) ;
1502
+ check_pat ( pcx , subpat, arg_ty) ;
1479
1503
}
1480
1504
} else if subpats_len > 0 u {
1481
1505
tcx. sess . span_err
@@ -1497,23 +1521,23 @@ fn check_pat_variant(fcx: @fn_ctxt, map: pat_util::pat_id_map,
1497
1521
1498
1522
// Pattern checking is top-down rather than bottom-up so that bindings get
1499
1523
// their types immediately.
1500
- fn check_pat ( fcx : @fn_ctxt , map : pat_util:: pat_id_map , pat : @ast:: pat ,
1501
- expected : ty:: t ) {
1502
- let tcx = fcx. ccx . tcx ;
1524
+ fn check_pat ( pcx : pat_ctxt , pat : @ast:: pat , expected : ty:: t ) {
1525
+ let tcx = pcx. fcx . ccx . tcx ;
1503
1526
alt pat. node {
1504
1527
ast:: pat_wild {
1505
1528
write_ty( tcx, pat. id , expected) ;
1506
1529
}
1507
1530
ast:: pat_lit ( lt) {
1508
- check_expr_with ( fcx, lt, expected) ;
1531
+ check_expr_with ( pcx . fcx , lt, expected) ;
1509
1532
write_ty ( tcx, pat. id , expr_ty ( tcx, lt) ) ;
1510
1533
}
1511
1534
ast:: pat_range ( begin, end) {
1512
- check_expr_with ( fcx, begin, expected) ;
1513
- check_expr_with ( fcx, end, expected) ;
1514
- let b_ty = resolve_type_vars_if_possible ( fcx, expr_ty ( tcx, begin) ) ;
1535
+ check_expr_with ( pcx. fcx , begin, expected) ;
1536
+ check_expr_with ( pcx. fcx , end, expected) ;
1537
+ let b_ty = resolve_type_vars_if_possible ( pcx. fcx ,
1538
+ expr_ty ( tcx, begin) ) ;
1515
1539
if !ty:: same_type ( tcx, b_ty, resolve_type_vars_if_possible (
1516
- fcx, expr_ty ( tcx, end) ) ) {
1540
+ pcx . fcx , expr_ty ( tcx, end) ) ) {
1517
1541
tcx. sess . span_err ( pat. span , "mismatched types in range" ) ;
1518
1542
} else if !ty:: type_is_numeric ( b_ty) {
1519
1543
tcx. sess . span_err ( pat. span , "non-numeric type used in range" ) ;
@@ -1525,29 +1549,30 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
1525
1549
}
1526
1550
ast:: pat_ident ( name, sub)
1527
1551
if !pat_util:: pat_is_variant ( tcx. def_map , pat) {
1528
- let vid = lookup_local ( fcx, pat. span , pat. id ) ;
1552
+ let vid = lookup_local ( pcx . fcx , pat. span , pat. id ) ;
1529
1553
let typ = ty:: mk_var ( tcx, vid) ;
1530
- typ = demand:: simple ( fcx, pat. span , expected, typ) ;
1531
- let canon_id = map. get ( path_to_ident ( name) ) ;
1554
+ typ = demand:: simple ( pcx . fcx , pat. span , expected, typ) ;
1555
+ let canon_id = pcx . map . get ( path_to_ident ( name) ) ;
1532
1556
if canon_id != pat. id {
1533
- let ct = ty:: mk_var ( tcx, lookup_local ( fcx, pat. span , canon_id) ) ;
1534
- typ = demand:: simple ( fcx, pat. span , ct, typ) ;
1557
+ let tv_id = lookup_local ( pcx. fcx , pat. span , canon_id) ;
1558
+ let ct = ty:: mk_var ( tcx, tv_id) ;
1559
+ typ = demand:: simple ( pcx. fcx , pat. span , ct, typ) ;
1535
1560
}
1536
1561
write_ty ( tcx, pat. id , typ) ;
1537
1562
alt sub {
1538
- some( p) { check_pat ( fcx , map , p, expected) ; }
1563
+ some( p) { check_pat ( pcx , p, expected) ; }
1539
1564
_ { }
1540
1565
}
1541
1566
}
1542
1567
ast:: pat_ident ( path, _) {
1543
- check_pat_variant ( fcx , map , pat, path, [ ] , expected) ;
1568
+ check_pat_variant ( pcx , pat, path, [ ] , expected) ;
1544
1569
}
1545
1570
ast:: pat_enum ( path, subpats) {
1546
- check_pat_variant ( fcx , map , pat, path, subpats, expected) ;
1571
+ check_pat_variant ( pcx , pat, path, subpats, expected) ;
1547
1572
}
1548
1573
ast:: pat_rec ( fields, etc) {
1549
1574
let ex_fields;
1550
- alt structure_of ( fcx, pat. span , expected) {
1575
+ alt structure_of ( pcx . fcx , pat. span , expected) {
1551
1576
ty:: ty_rec ( fields) { ex_fields = fields; }
1552
1577
_ {
1553
1578
tcx. sess . span_fatal
@@ -1570,7 +1595,9 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
1570
1595
}
1571
1596
for f: ast:: field_pat in fields {
1572
1597
alt vec:: find ( ex_fields, bind matches ( f. ident , _) ) {
1573
- some ( field) { check_pat ( fcx, map, f. pat , field. mt . ty ) ; }
1598
+ some ( field) {
1599
+ check_pat ( pcx, f. pat , field. mt . ty ) ;
1600
+ }
1574
1601
none {
1575
1602
tcx. sess . span_fatal ( pat. span ,
1576
1603
#fmt[ "mismatched types: did not \
@@ -1583,7 +1610,7 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
1583
1610
}
1584
1611
ast:: pat_tup ( elts) {
1585
1612
let ex_elts;
1586
- alt structure_of ( fcx, pat. span , expected) {
1613
+ alt structure_of ( pcx . fcx , pat. span , expected) {
1587
1614
ty:: ty_tup ( elts) { ex_elts = elts; }
1588
1615
_ {
1589
1616
tcx. sess . span_fatal
@@ -1600,13 +1627,17 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
1600
1627
fields", vec:: len ( ex_elts) , e_count] ) ;
1601
1628
}
1602
1629
let i = 0 u;
1603
- for elt in elts { check_pat ( fcx, map, elt, ex_elts[ i] ) ; i += 1 u; }
1630
+ for elt in elts {
1631
+ check_pat ( pcx, elt, ex_elts[ i] ) ;
1632
+ i += 1 u;
1633
+ }
1634
+
1604
1635
write_ty ( tcx, pat. id , expected) ;
1605
1636
}
1606
1637
ast:: pat_box ( inner) {
1607
- alt structure_of ( fcx, pat. span , expected) {
1638
+ alt structure_of ( pcx . fcx , pat. span , expected) {
1608
1639
ty:: ty_box ( e_inner) {
1609
- check_pat ( fcx , map , inner, e_inner. ty ) ;
1640
+ check_pat ( pcx , inner, e_inner. ty ) ;
1610
1641
write_ty ( tcx, pat. id , expected) ;
1611
1642
}
1612
1643
_ {
@@ -1618,9 +1649,9 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
1618
1649
}
1619
1650
}
1620
1651
ast:: pat_uniq ( inner) {
1621
- alt structure_of ( fcx, pat. span , expected) {
1652
+ alt structure_of ( pcx . fcx , pat. span , expected) {
1622
1653
ty:: ty_uniq ( e_inner) {
1623
- check_pat ( fcx , map , inner, e_inner. ty ) ;
1654
+ check_pat ( pcx , inner, e_inner. ty ) ;
1624
1655
write_ty ( tcx, pat. id , expected) ;
1625
1656
}
1626
1657
_ {
@@ -2454,16 +2485,25 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2454
2485
write_ty ( tcx, id, ty:: mk_nil ( tcx) ) ;
2455
2486
bot = !may_break ( body) ;
2456
2487
}
2457
- ast:: expr_alt ( expr, arms, _) {
2458
- bot = check_expr ( fcx, expr) ;
2488
+ ast:: expr_alt ( discrim, arms, _) {
2489
+ bot = check_expr ( fcx, discrim) ;
2490
+
2491
+ let parent_block = tcx. region_map . rvalue_to_block . get ( expr. id ) ;
2459
2492
2460
2493
// Typecheck the patterns first, so that we get types for all the
2461
2494
// bindings.
2462
- let pattern_ty = ty:: expr_ty ( tcx, expr ) ;
2495
+ let pattern_ty = ty:: expr_ty ( tcx, discrim ) ;
2463
2496
for arm: ast:: arm in arms {
2464
- let id_map = pat_util:: pat_id_map ( tcx. def_map , arm. pats [ 0 ] ) ;
2497
+ let pcx = {
2498
+ fcx: fcx,
2499
+ map: pat_util:: pat_id_map ( tcx. def_map , arm. pats [ 0 ] ) ,
2500
+ alt_region: ty:: re_block ( parent_block) ,
2501
+ block_region: ty:: re_block ( arm. body . node . id ) ,
2502
+ pat_region: ty:: re_block ( parent_block)
2503
+ } ;
2504
+
2465
2505
for p: @ast:: pat in arm. pats {
2466
- check_pat ( fcx , id_map , p, pattern_ty) ;
2506
+ check_pat ( pcx , p, pattern_ty) ;
2467
2507
}
2468
2508
}
2469
2509
// Now typecheck the blocks.
@@ -2797,8 +2837,18 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
2797
2837
}
2798
2838
_ { /* fall through */ }
2799
2839
}
2800
- let id_map = pat_util:: pat_id_map ( fcx. ccx . tcx . def_map , local. node . pat ) ;
2801
- check_pat ( fcx, id_map, local. node . pat , t) ;
2840
+
2841
+ let block_id = fcx. ccx . tcx . region_map . rvalue_to_block . get ( local. node . id ) ;
2842
+ let region = ty:: re_block ( block_id) ;
2843
+ let pcx = {
2844
+ fcx: fcx,
2845
+ map: pat_util:: pat_id_map ( fcx. ccx . tcx . def_map , local. node . pat ) ,
2846
+ alt_region: region,
2847
+ block_region: region,
2848
+ pat_region: region
2849
+ } ;
2850
+
2851
+ check_pat ( pcx, local. node . pat , t) ;
2802
2852
ret bot;
2803
2853
}
2804
2854
0 commit comments