@@ -64,10 +64,10 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
6464 ObjectLifetimeDefaultRscope , ShiftedRscope , BindingRscope ,
6565 ElisionFailureInfo , ElidedLifetime } ;
6666use util:: common:: { ErrorReported , FN_OUTPUT_NAME } ;
67- use util:: nodemap:: FnvHashSet ;
67+ use util:: nodemap:: { NodeMap , FnvHashSet } ;
6868
6969use rustc_const_math:: ConstInt ;
70-
70+ use std :: cell :: RefCell ;
7171use syntax:: { abi, ast} ;
7272use syntax:: codemap:: { Span , Pos } ;
7373use syntax:: errors:: DiagnosticBuilder ;
@@ -81,6 +81,9 @@ use rustc_back::slice;
8181pub trait AstConv < ' gcx , ' tcx > {
8282 fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' gcx , ' tcx > ;
8383
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+
8487 /// Identify the type scheme for an item with a type, like a type
8588 /// alias, fn, or struct. This allows you to figure out the set of
8689 /// type parameters defined on the item.
@@ -1416,13 +1419,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
14161419 rscope : & RegionScope ,
14171420 span : Span ,
14181421 param_mode : PathParamMode ,
1419- def : & Def ,
1422+ def : Def ,
14201423 opt_self_ty : Option < Ty < ' tcx > > ,
14211424 base_segments : & [ hir:: PathSegment ] )
14221425 -> Ty < ' tcx > {
14231426 let tcx = self . tcx ( ) ;
14241427
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 {
14261432 Def :: Trait ( trait_def_id) => {
14271433 // N.B. this case overlaps somewhat with
14281434 // TyObjectSum, see that fn for details
@@ -1515,20 +1521,27 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15151521 rscope : & RegionScope ,
15161522 span : Span ,
15171523 param_mode : PathParamMode ,
1518- def : & Def ,
1524+ mut def : Def ,
15191525 opt_self_ty : Option < Ty < ' tcx > > ,
15201526 base_segments : & [ hir:: PathSegment ] ,
15211527 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) ;
15231535 let mut ty = self . base_def_to_ty ( rscope,
15241536 span,
15251537 param_mode,
15261538 def,
15271539 opt_self_ty,
15281540 base_segments) ;
1529- let mut def = * def ;
1541+ debug ! ( "finish_resolving_def_to_ty: base_def_to_ty returned {:?}" , ty ) ;
15301542 // If any associated type segments remain, attempt to resolve them.
15311543 for segment in assoc_segments {
1544+ debug ! ( "finish_resolving_def_to_ty: segment={:?}" , segment) ;
15321545 if ty. sty == ty:: TyError {
15331546 break ;
15341547 }
@@ -1540,7 +1553,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15401553 ty = a_ty;
15411554 def = a_def;
15421555 }
1543- ty
1556+ ( ty , def )
15441557 }
15451558
15461559 /// Parses the programmer's textual representation of a type into our
@@ -1551,7 +1564,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15511564
15521565 let tcx = self . tcx ( ) ;
15531566
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 {
15551574 hir:: TyVec ( ref ty) => {
15561575 tcx. mk_slice ( self . ast_ty_to_ty ( rscope, & ty) )
15571576 }
@@ -1599,6 +1618,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
15991618 self . conv_ty_poly_trait_ref ( rscope, ast_ty. span , bounds)
16001619 }
16011620 hir:: TyPath ( ref maybe_qself, ref path) => {
1621+ debug ! ( "ast_ty_to_ty: maybe_qself={:?} path={:?}" , maybe_qself, path) ;
16021622 let path_res = if let Some ( & d) = tcx. def_map . borrow ( ) . get ( & ast_ty. id ) {
16031623 d
16041624 } else if let Some ( hir:: QSelf { position : 0 , .. } ) = * maybe_qself {
@@ -1615,13 +1635,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
16151635 let opt_self_ty = maybe_qself. as_ref ( ) . map ( |qself| {
16161636 self . ast_ty_to_ty ( rscope, & qself. ty )
16171637 } ) ;
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..] ) ;
16251645
16261646 if path_res. depth != 0 && ty. sty != ty:: TyError {
16271647 // Write back the new resolution.
@@ -1675,7 +1695,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
16751695 // handled specially and will not descend into this routine.
16761696 self . ty_infer ( None , None , None , ast_ty. span )
16771697 }
1678- }
1698+ } ;
1699+
1700+ cache. borrow_mut ( ) . insert ( ast_ty. id , result_ty) ;
1701+
1702+ result_ty
16791703 }
16801704
16811705 pub fn ty_of_arg ( & self ,
0 commit comments