@@ -606,9 +606,10 @@ pub fn instantiate_trait_ref<'tcx>(
606
606
def:: DefTrait ( trait_def_id) => {
607
607
let trait_ref = ast_path_to_trait_ref ( this,
608
608
rscope,
609
+ path. span ,
609
610
trait_def_id,
610
611
self_ty,
611
- path,
612
+ path. segments . last ( ) . unwrap ( ) ,
612
613
projections) ;
613
614
if let Some ( id) = impl_id {
614
615
this. tcx ( ) . impl_trait_refs . borrow_mut ( ) . insert ( id, trait_ref. clone ( ) ) ;
@@ -637,9 +638,10 @@ fn object_path_to_poly_trait_ref<'a,'tcx>(
637
638
let mut tmp = Vec :: new ( ) ;
638
639
let trait_ref = ty:: Binder ( ast_path_to_trait_ref ( this,
639
640
& shifted_rscope,
641
+ path. span ,
640
642
trait_def_id,
641
643
None ,
642
- path,
644
+ path. segments . last ( ) . unwrap ( ) ,
643
645
Some ( & mut tmp) ) ) ;
644
646
projections. extend ( tmp. into_iter ( ) . map ( ty:: Binder ) ) ;
645
647
trait_ref
@@ -648,24 +650,25 @@ fn object_path_to_poly_trait_ref<'a,'tcx>(
648
650
fn ast_path_to_trait_ref < ' a , ' tcx > (
649
651
this : & AstConv < ' tcx > ,
650
652
rscope : & RegionScope ,
653
+ span : Span ,
651
654
trait_def_id : ast:: DefId ,
652
655
self_ty : Option < Ty < ' tcx > > ,
653
- path : & ast:: Path ,
656
+ trait_segment : & ast:: PathSegment ,
654
657
mut projections : Option < & mut Vec < ty:: ProjectionPredicate < ' tcx > > > )
655
658
-> Rc < ty:: TraitRef < ' tcx > >
656
659
{
657
- debug ! ( "ast_path_to_trait_ref {:?}" , path ) ;
660
+ debug ! ( "ast_path_to_trait_ref {:?}" , trait_segment ) ;
658
661
let trait_def = this. get_trait_def ( trait_def_id) ;
659
662
660
- let ( regions, types, assoc_bindings) = match path . segments . last ( ) . unwrap ( ) . parameters {
663
+ let ( regions, types, assoc_bindings) = match trait_segment . parameters {
661
664
ast:: AngleBracketedParameters ( ref data) => {
662
665
// For now, require that parenthetical notation be used
663
666
// only with `Fn()` etc.
664
667
if !this. tcx ( ) . sess . features . borrow ( ) . unboxed_closures && trait_def. paren_sugar {
665
- span_err ! ( this. tcx( ) . sess, path . span, E0215 ,
668
+ span_err ! ( this. tcx( ) . sess, span, E0215 ,
666
669
"angle-bracket notation is not stable when \
667
670
used with the `Fn` family of traits, use parentheses") ;
668
- span_help ! ( this. tcx( ) . sess, path . span,
671
+ span_help ! ( this. tcx( ) . sess, span,
669
672
"add `#![feature(unboxed_closures)]` to \
670
673
the crate attributes to enable") ;
671
674
}
@@ -676,10 +679,10 @@ fn ast_path_to_trait_ref<'a,'tcx>(
676
679
// For now, require that parenthetical notation be used
677
680
// only with `Fn()` etc.
678
681
if !this. tcx ( ) . sess . features . borrow ( ) . unboxed_closures && !trait_def. paren_sugar {
679
- span_err ! ( this. tcx( ) . sess, path . span, E0216 ,
682
+ span_err ! ( this. tcx( ) . sess, span, E0216 ,
680
683
"parenthetical notation is only stable when \
681
684
used with the `Fn` family of traits") ;
682
- span_help ! ( this. tcx( ) . sess, path . span,
685
+ span_help ! ( this. tcx( ) . sess, span,
683
686
"add `#![feature(unboxed_closures)]` to \
684
687
the crate attributes to enable") ;
685
688
}
@@ -689,7 +692,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
689
692
} ;
690
693
691
694
let substs = create_substs_for_ast_path ( this,
692
- path . span ,
695
+ span,
693
696
& trait_def. generics ,
694
697
self_ty,
695
698
types,
@@ -1047,33 +1050,42 @@ fn trait_defines_associated_type_named(this: &AstConv,
1047
1050
1048
1051
fn qpath_to_ty < ' tcx > ( this : & AstConv < ' tcx > ,
1049
1052
rscope : & RegionScope ,
1050
- ast_ty : & ast:: Ty , // the TyQPath
1051
- qpath : & ast:: QPath )
1053
+ span : Span ,
1054
+ opt_self_ty : Option < & ast:: Ty > ,
1055
+ trait_def_id : ast:: DefId ,
1056
+ trait_segment : & ast:: PathSegment ,
1057
+ item_segment : & ast:: PathSegment )
1052
1058
-> Ty < ' tcx >
1053
1059
{
1054
- debug ! ( "qpath_to_ty(ast_ty={})" ,
1055
- ast_ty. repr( this. tcx( ) ) ) ;
1060
+ let tcx = this. tcx ( ) ;
1056
1061
1057
- let self_type = ast_ty_to_ty ( this, rscope, & * qpath. self_type ) ;
1062
+ let self_ty = if let Some ( ty) = opt_self_ty {
1063
+ ast_ty_to_ty ( this, rscope, ty)
1064
+ } else {
1065
+ let path_str = ty:: item_path_str ( tcx, trait_def_id) ;
1066
+ span_err ! ( tcx. sess, span, E0223 ,
1067
+ "ambiguous associated type; specify the type using the syntax \
1068
+ `<Type as {}>::{}`",
1069
+ path_str, & token:: get_ident( item_segment. identifier) ) ;
1070
+ return tcx. types . err ;
1071
+ } ;
1058
1072
1059
- debug ! ( "qpath_to_ty: self_type={}" , self_type . repr( this . tcx( ) ) ) ;
1073
+ debug ! ( "qpath_to_ty: self_type={}" , self_ty . repr( tcx) ) ;
1060
1074
1061
- let trait_ref = instantiate_trait_ref ( this,
1075
+ let trait_ref = ast_path_to_trait_ref ( this,
1062
1076
rscope,
1063
- & qpath . trait_path ,
1064
- ast_ty . id ,
1065
- None ,
1066
- Some ( self_type ) ,
1077
+ span ,
1078
+ trait_def_id ,
1079
+ Some ( self_ty ) ,
1080
+ trait_segment ,
1067
1081
None ) ;
1068
1082
1069
- debug ! ( "qpath_to_ty: trait_ref={}" , trait_ref. repr( this . tcx( ) ) ) ;
1083
+ debug ! ( "qpath_to_ty: trait_ref={}" , trait_ref. repr( tcx) ) ;
1070
1084
1071
1085
// `<T as Trait>::U<V>` shouldn't parse right now.
1072
- assert ! ( qpath . item_path . parameters. is_empty( ) ) ;
1086
+ assert ! ( item_segment . parameters. is_empty( ) ) ;
1073
1087
1074
- return this. projected_ty ( ast_ty. span ,
1075
- trait_ref,
1076
- qpath. item_path . identifier . name ) ;
1088
+ this. projected_ty ( span, trait_ref, item_segment. identifier . name )
1077
1089
}
1078
1090
1079
1091
/// Convert a type supplied as value for a type argument from AST into our
@@ -1189,13 +1201,17 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
1189
1201
ast:: TyPolyTraitRef ( ref bounds) => {
1190
1202
conv_ty_poly_trait_ref ( this, rscope, ast_ty. span , & bounds[ ..] )
1191
1203
}
1192
- ast:: TyPath ( ref path) => {
1204
+ ast:: TyPath ( _) | ast:: TyQPath ( _) => {
1205
+ let simple_path = |& : | match ast_ty. node {
1206
+ ast : : TyPath ( ref path) => path,
1207
+ _ => tcx. sess. span_bug( ast_ty. span, "expected non-qualified path")
1208
+ } ;
1193
1209
let a_def = match tcx. def_map . borrow ( ) . get ( & ast_ty. id ) {
1194
1210
None => {
1195
1211
tcx. sess
1196
1212
. span_bug ( ast_ty. span ,
1197
1213
& format ! ( "unbound path {}" ,
1198
- path . repr( tcx) ) )
1214
+ ast_ty . repr( tcx) ) )
1199
1215
}
1200
1216
Some ( & d) => d
1201
1217
} ;
@@ -1208,24 +1224,24 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
1208
1224
let trait_ref = object_path_to_poly_trait_ref ( this,
1209
1225
rscope,
1210
1226
trait_def_id,
1211
- path ,
1227
+ simple_path ( ) ,
1212
1228
& mut projection_bounds) ;
1213
1229
1214
- trait_ref_to_object_type ( this, rscope, path . span ,
1230
+ trait_ref_to_object_type ( this, rscope, ast_ty . span ,
1215
1231
trait_ref, projection_bounds, & [ ] )
1216
1232
}
1217
1233
def:: DefTy ( did, _) | def:: DefStruct ( did) => {
1218
- ast_path_to_ty ( this, rscope, did, path ) . ty
1234
+ ast_path_to_ty ( this, rscope, did, simple_path ( ) ) . ty
1219
1235
}
1220
1236
def:: DefTyParam ( space, index, _, name) => {
1221
- check_path_args ( tcx, path , NO_TPS | NO_REGIONS ) ;
1237
+ check_path_args ( tcx, simple_path ( ) , NO_TPS | NO_REGIONS ) ;
1222
1238
ty:: mk_param ( tcx, space, index, name)
1223
1239
}
1224
1240
def:: DefSelfTy ( _) => {
1225
1241
// n.b.: resolve guarantees that the this type only appears in a
1226
1242
// trait, which we rely upon in various places when creating
1227
1243
// substs
1228
- check_path_args ( tcx, path , NO_TPS | NO_REGIONS ) ;
1244
+ check_path_args ( tcx, simple_path ( ) , NO_TPS | NO_REGIONS ) ;
1229
1245
ty:: mk_self_type ( tcx)
1230
1246
}
1231
1247
def:: DefMod ( id) => {
@@ -1236,20 +1252,20 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
1236
1252
def:: DefPrimTy ( _) => {
1237
1253
panic ! ( "DefPrimTy arm missed in previous ast_ty_to_prim_ty call" ) ;
1238
1254
}
1239
- def:: DefAssociatedTy ( trait_id , _) => {
1240
- let path_str = ty :: item_path_str ( tcx , trait_id ) ;
1241
- span_err ! ( tcx . sess , ast_ty . span , E0223 ,
1242
- "ambiguous associated \
1243
- type; specify the type \
1244
- using the syntax `<Type \
1245
- as {}>::{}`" ,
1246
- path_str ,
1247
- & token :: get_ident (
1248
- path . segments
1249
- . last ( )
1250
- . unwrap ( )
1251
- . identifier ) ) ;
1252
- this . tcx ( ) . types . err
1255
+ def:: DefAssociatedTy ( trait_did , _) => {
1256
+ let ( opt_self_ty , trait_segment , item_segment ) = match ast_ty . node {
1257
+ ast :: TyQPath ( ref qpath ) => {
1258
+ ( Some ( & * qpath . self_type ) , qpath . trait_path . segments . last ( ) . unwrap ( ) ,
1259
+ & qpath . item_path )
1260
+ }
1261
+ ast :: TyPath ( ref path ) => {
1262
+ ( None , & path . segments [ path . segments . len ( ) - 2 ] ,
1263
+ path . segments . last ( ) . unwrap ( ) )
1264
+ }
1265
+ _ => unreachable ! ( )
1266
+ } ;
1267
+ qpath_to_ty ( this , rscope , ast_ty . span , opt_self_ty ,
1268
+ trait_did , trait_segment , item_segment )
1253
1269
}
1254
1270
def:: DefAssociatedPath ( provenance, assoc_ident) => {
1255
1271
associated_path_def_to_ty ( this, ast_ty, provenance, assoc_ident. name )
@@ -1262,9 +1278,6 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
1262
1278
}
1263
1279
}
1264
1280
}
1265
- ast:: TyQPath ( ref qpath) => {
1266
- qpath_to_ty ( this, rscope, ast_ty, & * * qpath)
1267
- }
1268
1281
ast:: TyFixedLengthVec ( ref ty, ref e) => {
1269
1282
match const_eval:: eval_const_expr_partial ( tcx, & * * e, Some ( tcx. types . uint ) ) {
1270
1283
Ok ( ref r) => {
0 commit comments