@@ -64,10 +64,10 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
64
64
ObjectLifetimeDefaultRscope , ShiftedRscope , BindingRscope ,
65
65
ElisionFailureInfo , ElidedLifetime } ;
66
66
use util:: common:: { ErrorReported , FN_OUTPUT_NAME } ;
67
- use util:: nodemap:: FnvHashSet ;
67
+ use util:: nodemap:: { NodeMap , FnvHashSet } ;
68
68
69
69
use rustc_const_math:: ConstInt ;
70
-
70
+ use std :: cell :: RefCell ;
71
71
use syntax:: { abi, ast} ;
72
72
use syntax:: codemap:: { Span , Pos } ;
73
73
use syntax:: errors:: DiagnosticBuilder ;
@@ -81,6 +81,9 @@ use rustc_back::slice;
81
81
pub trait AstConv < ' gcx , ' tcx > {
82
82
fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' gcx , ' tcx > ;
83
83
84
+ /// A cache used for the result of `ast_ty_to_ty_cache`
85
+ fn ast_ty_to_ty_cache ( & self ) -> & RefCell < NodeMap < Ty < ' tcx > > > ;
86
+
84
87
/// Identify the type scheme for an item with a type, like a type
85
88
/// alias, fn, or struct. This allows you to figure out the set of
86
89
/// type parameters defined on the item.
@@ -1416,13 +1419,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1416
1419
rscope : & RegionScope ,
1417
1420
span : Span ,
1418
1421
param_mode : PathParamMode ,
1419
- def : & Def ,
1422
+ def : Def ,
1420
1423
opt_self_ty : Option < Ty < ' tcx > > ,
1421
1424
base_segments : & [ hir:: PathSegment ] )
1422
1425
-> Ty < ' tcx > {
1423
1426
let tcx = self . tcx ( ) ;
1424
1427
1425
- match * def {
1428
+ debug ! ( "base_def_to_ty(def={:?}, opt_self_ty={:?}, base_segments={:?})" ,
1429
+ def, opt_self_ty, base_segments) ;
1430
+
1431
+ match def {
1426
1432
Def :: Trait ( trait_def_id) => {
1427
1433
// N.B. this case overlaps somewhat with
1428
1434
// TyObjectSum, see that fn for details
@@ -1515,20 +1521,27 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1515
1521
rscope : & RegionScope ,
1516
1522
span : Span ,
1517
1523
param_mode : PathParamMode ,
1518
- def : & Def ,
1524
+ mut def : Def ,
1519
1525
opt_self_ty : Option < Ty < ' tcx > > ,
1520
1526
base_segments : & [ hir:: PathSegment ] ,
1521
1527
assoc_segments : & [ hir:: PathSegment ] )
1522
- -> Ty < ' tcx > {
1528
+ -> ( Ty < ' tcx > , Def ) {
1529
+ debug ! ( "finish_resolving_def_to_ty(def={:?}, \
1530
+ base_segments={:?}, \
1531
+ assoc_segments={:?})",
1532
+ def,
1533
+ base_segments,
1534
+ assoc_segments) ;
1523
1535
let mut ty = self . base_def_to_ty ( rscope,
1524
1536
span,
1525
1537
param_mode,
1526
1538
def,
1527
1539
opt_self_ty,
1528
1540
base_segments) ;
1529
- let mut def = * def ;
1541
+ debug ! ( "finish_resolving_def_to_ty: base_def_to_ty returned {:?}" , ty ) ;
1530
1542
// If any associated type segments remain, attempt to resolve them.
1531
1543
for segment in assoc_segments {
1544
+ debug ! ( "finish_resolving_def_to_ty: segment={:?}" , segment) ;
1532
1545
if ty. sty == ty:: TyError {
1533
1546
break ;
1534
1547
}
@@ -1540,7 +1553,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1540
1553
ty = a_ty;
1541
1554
def = a_def;
1542
1555
}
1543
- ty
1556
+ ( ty , def )
1544
1557
}
1545
1558
1546
1559
/// Parses the programmer's textual representation of a type into our
@@ -1551,7 +1564,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1551
1564
1552
1565
let tcx = self . tcx ( ) ;
1553
1566
1554
- match ast_ty. node {
1567
+ let cache = self . ast_ty_to_ty_cache ( ) ;
1568
+ match cache. borrow ( ) . get ( & ast_ty. id ) {
1569
+ Some ( ty) => { return ty; }
1570
+ None => { }
1571
+ }
1572
+
1573
+ let result_ty = match ast_ty. node {
1555
1574
hir:: TyVec ( ref ty) => {
1556
1575
tcx. mk_slice ( self . ast_ty_to_ty ( rscope, & ty) )
1557
1576
}
@@ -1599,6 +1618,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1599
1618
self . conv_ty_poly_trait_ref ( rscope, ast_ty. span , bounds)
1600
1619
}
1601
1620
hir:: TyPath ( ref maybe_qself, ref path) => {
1621
+ debug ! ( "ast_ty_to_ty: maybe_qself={:?} path={:?}" , maybe_qself, path) ;
1602
1622
let path_res = if let Some ( & d) = tcx. def_map . borrow ( ) . get ( & ast_ty. id ) {
1603
1623
d
1604
1624
} else if let Some ( hir:: QSelf { position : 0 , .. } ) = * maybe_qself {
@@ -1615,13 +1635,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1615
1635
let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| {
1616
1636
self . ast_ty_to_ty ( rscope, & qself. ty )
1617
1637
} ) ;
1618
- let ty = self . finish_resolving_def_to_ty ( rscope,
1619
- ast_ty. span ,
1620
- PathParamMode :: Explicit ,
1621
- & def,
1622
- opt_self_ty,
1623
- & path. segments [ ..base_ty_end] ,
1624
- & path. segments [ base_ty_end..] ) ;
1638
+ let ( ty , _def ) = self . finish_resolving_def_to_ty ( rscope,
1639
+ ast_ty. span ,
1640
+ PathParamMode :: Explicit ,
1641
+ def,
1642
+ opt_self_ty,
1643
+ & path. segments [ ..base_ty_end] ,
1644
+ & path. segments [ base_ty_end..] ) ;
1625
1645
1626
1646
if path_res. depth != 0 && ty. sty != ty:: TyError {
1627
1647
// Write back the new resolution.
@@ -1675,7 +1695,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1675
1695
// handled specially and will not descend into this routine.
1676
1696
self . ty_infer ( None , None , None , ast_ty. span )
1677
1697
}
1678
- }
1698
+ } ;
1699
+
1700
+ cache. borrow_mut ( ) . insert ( ast_ty. id , result_ty) ;
1701
+
1702
+ result_ty
1679
1703
}
1680
1704
1681
1705
pub fn ty_of_arg ( & self ,
0 commit comments