@@ -59,8 +59,9 @@ use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope,
59
59
ShiftedRscope , BindingRscope } ;
60
60
use middle:: typeck:: rscope;
61
61
use middle:: typeck:: TypeAndSubsts ;
62
+ use util:: common:: ErrorReported ;
62
63
use util:: nodemap:: DefIdMap ;
63
- use util:: ppaux:: { Repr , UserString } ;
64
+ use util:: ppaux:: { mod , Repr , UserString } ;
64
65
65
66
use std:: rc:: Rc ;
66
67
use std:: iter:: AdditiveIterator ;
@@ -585,7 +586,7 @@ fn check_path_args(tcx: &ty::ctxt,
585
586
pub fn ast_ty_to_prim_ty < ' tcx > ( tcx : & ty:: ctxt < ' tcx > , ast_ty : & ast:: Ty )
586
587
-> Option < Ty < ' tcx > > {
587
588
match ast_ty. node {
588
- ast:: TyPath ( ref path, _ , id) => {
589
+ ast:: TyPath ( ref path, id) => {
589
590
let a_def = match tcx. def_map . borrow ( ) . get ( & id) {
590
591
None => {
591
592
tcx. sess . span_bug ( ast_ty. span ,
@@ -642,7 +643,7 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
642
643
}
643
644
644
645
match ast_ty. node {
645
- ast:: TyPath ( ref path, _ , id) => {
646
+ ast:: TyPath ( ref path, id) => {
646
647
let a_def = match this. tcx ( ) . def_map . borrow ( ) . get ( & id) {
647
648
None => {
648
649
this. tcx ( )
@@ -682,64 +683,92 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
682
683
}
683
684
}
684
685
685
- // Handle `~`, `Box`, and `&` being able to mean strs and vecs.
686
- // If a_seq_ty is a str or a vec, make it a str/vec.
687
- // Also handle first-class trait types.
688
- fn mk_pointer < ' tcx , AC : AstConv < ' tcx > , RS : RegionScope > (
689
- this : & AC ,
690
- rscope : & RS ,
691
- a_seq_mutbl : ast:: Mutability ,
692
- a_seq_ty : & ast:: Ty ,
693
- region : ty:: Region ,
694
- constr: |Ty < ' tcx > | -> Ty < ' tcx > )
695
- -> Ty < ' tcx >
686
+ fn ast_ty_to_trait_ref < ' tcx , AC , RS > ( this : & AC ,
687
+ rscope : & RS ,
688
+ ty : & ast:: Ty ,
689
+ bounds : & [ ast:: TyParamBound ] )
690
+ -> Result < ty:: TraitRef < ' tcx > , ErrorReported >
691
+ where AC : AstConv < ' tcx > , RS : RegionScope
696
692
{
697
- let tcx = this. tcx ( ) ;
698
-
699
- debug ! ( "mk_pointer(region={}, a_seq_ty={})" ,
700
- region,
701
- a_seq_ty. repr( tcx) ) ;
693
+ /*!
694
+ * In a type like `Foo + Send`, we want to wait to collect the
695
+ * full set of bounds before we make the object type, because we
696
+ * need them to infer a region bound. (For example, if we tried
697
+ * made a type from just `Foo`, then it wouldn't be enough to
698
+ * infer a 'static bound, and hence the user would get an error.)
699
+ * So this function is used when we're dealing with a sum type to
700
+ * convert the LHS. It only accepts a type that refers to a trait
701
+ * name, and reports an error otherwise.
702
+ */
702
703
703
- match a_seq_ty. node {
704
- ast:: TyVec ( ref ty) => {
705
- let ty = ast_ty_to_ty ( this, rscope, & * * ty) ;
706
- return constr ( ty:: mk_vec ( tcx, ty, None ) ) ;
704
+ match ty. node {
705
+ ast:: TyPath ( ref path, id) => {
706
+ match this. tcx ( ) . def_map . borrow ( ) . get ( & id) {
707
+ Some ( & def:: DefTrait ( trait_def_id) ) => {
708
+ return Ok ( ast_path_to_trait_ref ( this,
709
+ rscope,
710
+ trait_def_id,
711
+ None ,
712
+ path) ) ;
713
+ }
714
+ _ => {
715
+ span_err ! ( this. tcx( ) . sess, ty. span, E0170 , "expected a reference to a trait" ) ;
716
+ Err ( ErrorReported )
717
+ }
718
+ }
707
719
}
708
- ast:: TyPath ( ref path, ref opt_bounds, id) => {
709
- // Note that the "bounds must be empty if path is not a trait"
710
- // restriction is enforced in the below case for ty_path, which
711
- // will run after this as long as the path isn't a trait.
712
- match tcx. def_map . borrow ( ) . get ( & id) {
713
- Some ( & def:: DefPrimTy ( ast:: TyStr ) ) => {
714
- check_path_args ( tcx, path, NO_TPS | NO_REGIONS ) ;
715
- return ty:: mk_str_slice ( tcx, region, a_seq_mutbl) ;
720
+ _ => {
721
+ span_err ! ( this. tcx( ) . sess, ty. span, E0171 ,
722
+ "expected a path on the left-hand side of `+`, not `{}`" ,
723
+ pprust:: ty_to_string( ty) ) ;
724
+ match ty. node {
725
+ ast:: TyRptr ( None , ref mut_ty) => {
726
+ span_note ! ( this. tcx( ) . sess, ty. span,
727
+ "perhaps you meant `&{}({} +{})`? (per RFC 248)" ,
728
+ ppaux:: mutability_to_string( mut_ty. mutbl) ,
729
+ pprust:: ty_to_string( & * mut_ty. ty) ,
730
+ pprust:: bounds_to_string( bounds) ) ;
716
731
}
717
- Some ( & def:: DefTrait ( trait_def_id) ) => {
718
- let result = ast_path_to_trait_ref ( this,
719
- rscope,
720
- trait_def_id,
721
- None ,
722
- path) ;
723
- let empty_vec = [ ] ;
724
- let bounds = match * opt_bounds { None => empty_vec. as_slice ( ) ,
725
- Some ( ref bounds) => bounds. as_slice ( ) } ;
726
- let existential_bounds = conv_existential_bounds ( this,
727
- rscope,
728
- path. span ,
729
- & [ Rc :: new ( result. clone ( ) ) ] ,
730
- bounds) ;
731
- let tr = ty:: mk_trait ( tcx,
732
- result,
733
- existential_bounds) ;
734
- return ty:: mk_rptr ( tcx, region, ty:: mt { mutbl : a_seq_mutbl, ty : tr} ) ;
732
+
733
+ ast:: TyRptr ( Some ( ref lt) , ref mut_ty) => {
734
+ span_note ! ( this. tcx( ) . sess, ty. span,
735
+ "perhaps you meant `&{} {}({} +{})`? (per RFC 248)" ,
736
+ pprust:: lifetime_to_string( lt) ,
737
+ ppaux:: mutability_to_string( mut_ty. mutbl) ,
738
+ pprust:: ty_to_string( & * mut_ty. ty) ,
739
+ pprust:: bounds_to_string( bounds) ) ;
740
+ }
741
+
742
+ _ => {
743
+ span_note ! ( this. tcx( ) . sess, ty. span,
744
+ "perhaps you forget parentheses? (per RFC 248)" ) ;
735
745
}
736
- _ => { }
737
746
}
747
+ Err ( ErrorReported )
738
748
}
739
- _ => { }
740
749
}
741
750
742
- constr ( ast_ty_to_ty ( this, rscope, a_seq_ty) )
751
+ }
752
+
753
+ fn trait_ref_to_object_type < ' tcx , AC , RS > ( this : & AC ,
754
+ rscope : & RS ,
755
+ span : Span ,
756
+ trait_ref : ty:: TraitRef < ' tcx > ,
757
+ bounds : & [ ast:: TyParamBound ] )
758
+ -> Ty < ' tcx >
759
+ where AC : AstConv < ' tcx > , RS : RegionScope
760
+ {
761
+ let existential_bounds = conv_existential_bounds ( this,
762
+ rscope,
763
+ span,
764
+ & [ Rc :: new ( trait_ref. clone ( ) ) ] ,
765
+ bounds) ;
766
+
767
+ let result = ty:: mk_trait ( this. tcx ( ) , trait_ref, existential_bounds) ;
768
+ debug ! ( "trait_ref_to_object_type: result={}" ,
769
+ result. repr( this. tcx( ) ) ) ;
770
+
771
+ result
743
772
}
744
773
745
774
fn qpath_to_ty < ' tcx , AC , RS > ( this : & AC ,
@@ -806,6 +835,17 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
806
835
ast:: TyVec ( ref ty) => {
807
836
ty:: mk_vec ( tcx, ast_ty_to_ty ( this, rscope, & * * ty) , None )
808
837
}
838
+ ast:: TyObjectSum ( ref ty, ref bounds) => {
839
+ match ast_ty_to_trait_ref ( this, rscope, & * * ty, bounds. as_slice ( ) ) {
840
+ Ok ( trait_ref) => {
841
+ trait_ref_to_object_type ( this, rscope, ast_ty. span ,
842
+ trait_ref, bounds. as_slice ( ) )
843
+ }
844
+ Err ( ErrorReported ) => {
845
+ ty:: mk_err ( )
846
+ }
847
+ }
848
+ }
809
849
ast:: TyPtr ( ref mt) => {
810
850
ty:: mk_ptr ( tcx, ty:: mt {
811
851
ty : ast_ty_to_ty ( this, rscope, & * mt. ty ) ,
@@ -815,8 +855,8 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
815
855
ast:: TyRptr ( ref region, ref mt) => {
816
856
let r = opt_ast_region_to_region ( this, rscope, ast_ty. span , region) ;
817
857
debug ! ( "ty_rptr r={}" , r. repr( this. tcx( ) ) ) ;
818
- mk_pointer ( this, rscope, mt . mutbl , & * mt. ty , r ,
819
- |ty| ty :: mk_rptr ( tcx, r, ty:: mt { ty : ty , mutbl : mt. mutbl } ) )
858
+ let t = ast_ty_to_ty ( this, rscope, & * mt. ty ) ;
859
+ ty :: mk_rptr ( tcx, r, ty:: mt { ty : t , mutbl : mt. mutbl } )
820
860
}
821
861
ast:: TyTup ( ref fields) => {
822
862
let flds = fields. iter ( )
@@ -874,7 +914,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
874
914
ast:: TyPolyTraitRef ( ref bounds) => {
875
915
conv_ty_poly_trait_ref ( this, rscope, ast_ty. span , bounds. as_slice ( ) )
876
916
}
877
- ast:: TyPath ( ref path, ref bounds , id) => {
917
+ ast:: TyPath ( ref path, id) => {
878
918
let a_def = match tcx. def_map . borrow ( ) . get ( & id) {
879
919
None => {
880
920
tcx. sess
@@ -884,35 +924,16 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
884
924
}
885
925
Some ( & d) => d
886
926
} ;
887
- // Kind bounds on path types are only supported for traits.
888
- match a_def {
889
- // But don't emit the error if the user meant to do a trait anyway.
890
- def:: DefTrait ( ..) => { } ,
891
- _ if bounds. is_some ( ) =>
892
- tcx. sess . span_err ( ast_ty. span ,
893
- "kind bounds can only be used on trait types" ) ,
894
- _ => { } ,
895
- }
896
927
match a_def {
897
928
def:: DefTrait ( trait_def_id) => {
929
+ // N.B. this case overlaps somewhat with
930
+ // TyObjectSum, see that fn for details
898
931
let result = ast_path_to_trait_ref ( this,
899
932
rscope,
900
933
trait_def_id,
901
934
None ,
902
935
path) ;
903
- let empty_bounds: & [ ast:: TyParamBound ] = & [ ] ;
904
- let ast_bounds = match * bounds {
905
- Some ( ref b) => b. as_slice ( ) ,
906
- None => empty_bounds
907
- } ;
908
- let bounds = conv_existential_bounds ( this,
909
- rscope,
910
- ast_ty. span ,
911
- & [ Rc :: new ( result. clone ( ) ) ] ,
912
- ast_bounds) ;
913
- let result_ty = ty:: mk_trait ( tcx, result, bounds) ;
914
- debug ! ( "ast_ty_to_ty: result_ty={}" , result_ty. repr( this. tcx( ) ) ) ;
915
- result_ty
936
+ trait_ref_to_object_type ( this, rscope, path. span , result, & [ ] )
916
937
}
917
938
def:: DefTy ( did, _) | def:: DefStruct ( did) => {
918
939
ast_path_to_ty ( this, rscope, did, path) . ty
0 commit comments