@@ -653,6 +653,50 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
653653 }
654654 }
655655
656+ /// Returns a type variable's default fallback if any exists. A default
657+ /// must be attached to the variable when created, if it is created
658+ /// without a default, this will return None.
659+ ///
660+ /// This code does not apply to integral or floating point variables,
661+ /// only to use declared defaults.
662+ ///
663+ /// See `new_ty_var_with_default` to create a type variable with a default.
664+ /// See `type_variable::Default` for details about what a default entails.
665+ pub fn default ( & self , ty : Ty < ' tcx > ) -> Option < type_variable:: Default < ' tcx > > {
666+ match ty. sty {
667+ ty:: TyInfer ( ty:: TyVar ( vid) ) => self . type_variables . borrow ( ) . default ( vid) ,
668+ _ => None
669+ }
670+ }
671+
672+ pub fn unsolved_variables ( & self ) -> Vec < ty:: Ty < ' tcx > > {
673+ let mut variables = Vec :: new ( ) ;
674+
675+ let unbound_ty_vars = self . type_variables
676+ . borrow ( )
677+ . unsolved_variables ( )
678+ . into_iter ( )
679+ . map ( |t| self . tcx . mk_var ( t) ) ;
680+
681+ let unbound_int_vars = self . int_unification_table
682+ . borrow_mut ( )
683+ . unsolved_variables ( )
684+ . into_iter ( )
685+ . map ( |v| self . tcx . mk_int_var ( v) ) ;
686+
687+ let unbound_float_vars = self . float_unification_table
688+ . borrow_mut ( )
689+ . unsolved_variables ( )
690+ . into_iter ( )
691+ . map ( |v| self . tcx . mk_float_var ( v) ) ;
692+
693+ variables. extend ( unbound_ty_vars) ;
694+ variables. extend ( unbound_int_vars) ;
695+ variables. extend ( unbound_float_vars) ;
696+
697+ return variables;
698+ }
699+
656700 fn combine_fields ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > )
657701 -> CombineFields < ' a , ' tcx > {
658702 CombineFields { infcx : self ,
@@ -956,13 +1000,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9561000 pub fn next_ty_var_id ( & self , diverging : bool ) -> TyVid {
9571001 self . type_variables
9581002 . borrow_mut ( )
959- . new_var ( diverging)
1003+ . new_var ( diverging, None )
9601004 }
9611005
9621006 pub fn next_ty_var ( & self ) -> Ty < ' tcx > {
9631007 self . tcx . mk_var ( self . next_ty_var_id ( false ) )
9641008 }
9651009
1010+ pub fn next_ty_var_with_default ( & self ,
1011+ default : Option < type_variable:: Default < ' tcx > > ) -> Ty < ' tcx > {
1012+ let ty_var_id = self . type_variables
1013+ . borrow_mut ( )
1014+ . new_var ( false , default) ;
1015+
1016+ self . tcx . mk_var ( ty_var_id)
1017+ }
1018+
9661019 pub fn next_diverging_ty_var ( & self ) -> Ty < ' tcx > {
9671020 self . tcx . mk_var ( self . next_ty_var_id ( true ) )
9681021 }
@@ -996,20 +1049,55 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9961049 . collect ( )
9971050 }
9981051
1052+ // We have to take `&mut Substs` in order to provide the correct substitutions for defaults
1053+ // along the way, for this reason we don't return them.
1054+ pub fn type_vars_for_defs ( & self ,
1055+ span : Span ,
1056+ space : subst:: ParamSpace ,
1057+ substs : & mut Substs < ' tcx > ,
1058+ defs : & [ ty:: TypeParameterDef < ' tcx > ] ) {
1059+
1060+ let mut vars = Vec :: with_capacity ( defs. len ( ) ) ;
1061+
1062+ for def in defs. iter ( ) {
1063+ let default = def. default . map ( |default| {
1064+ type_variable:: Default {
1065+ ty : default. subst_spanned ( self . tcx , substs, Some ( span) ) ,
1066+ origin_span : span,
1067+ def_id : def. default_def_id
1068+ }
1069+ } ) ;
1070+
1071+ let ty_var = self . next_ty_var_with_default ( default) ;
1072+ substs. types . push ( space, ty_var) ;
1073+ vars. push ( ty_var)
1074+ }
1075+ }
1076+
9991077 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
10001078 /// type/region parameter to a fresh inference variable.
10011079 pub fn fresh_substs_for_generics ( & self ,
10021080 span : Span ,
10031081 generics : & ty:: Generics < ' tcx > )
10041082 -> subst:: Substs < ' tcx >
10051083 {
1006- let type_params =
1007- generics. types . map (
1008- |_| self . next_ty_var ( ) ) ;
1084+ let type_params = subst:: VecPerParamSpace :: empty ( ) ;
1085+
10091086 let region_params =
10101087 generics. regions . map (
10111088 |d| self . next_region_var ( EarlyBoundRegion ( span, d. name ) ) ) ;
1012- subst:: Substs :: new ( type_params, region_params)
1089+
1090+ let mut substs = subst:: Substs :: new ( type_params, region_params) ;
1091+
1092+ for space in subst:: ParamSpace :: all ( ) . iter ( ) {
1093+ self . type_vars_for_defs (
1094+ span,
1095+ * space,
1096+ & mut substs,
1097+ generics. types . get_slice ( * space) ) ;
1098+ }
1099+
1100+ return substs;
10131101 }
10141102
10151103 /// Given a set of generics defined on a trait, returns a substitution mapping each output
@@ -1027,13 +1115,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10271115 assert ! ( generics. regions. len( subst:: SelfSpace ) == 0 ) ;
10281116 assert ! ( generics. regions. len( subst:: FnSpace ) == 0 ) ;
10291117
1030- let type_parameter_count = generics. types . len ( subst:: TypeSpace ) ;
1031- let type_parameters = self . next_ty_vars ( type_parameter_count) ;
1118+ let type_params = Vec :: new ( ) ;
10321119
10331120 let region_param_defs = generics. regions . get_slice ( subst:: TypeSpace ) ;
10341121 let regions = self . region_vars_for_defs ( span, region_param_defs) ;
10351122
1036- subst:: Substs :: new_trait ( type_parameters, regions, self_ty)
1123+ let mut substs = subst:: Substs :: new_trait ( type_params, regions, self_ty) ;
1124+
1125+ let type_parameter_defs = generics. types . get_slice ( subst:: TypeSpace ) ;
1126+ self . type_vars_for_defs ( span, subst:: TypeSpace , & mut substs, type_parameter_defs) ;
1127+
1128+ return substs;
10371129 }
10381130
10391131 pub fn fresh_bound_region ( & self , debruijn : ty:: DebruijnIndex ) -> ty:: Region {
@@ -1268,6 +1360,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12681360 self . report_and_explain_type_error ( trace, err) ;
12691361 }
12701362
1363+ pub fn report_conflicting_default_types ( & self ,
1364+ span : Span ,
1365+ expected : type_variable:: Default < ' tcx > ,
1366+ actual : type_variable:: Default < ' tcx > ) {
1367+ let trace = TypeTrace {
1368+ origin : Misc ( span) ,
1369+ values : Types ( ty:: ExpectedFound {
1370+ expected : expected. ty ,
1371+ found : actual. ty
1372+ } )
1373+ } ;
1374+
1375+ self . report_and_explain_type_error ( trace,
1376+ & TypeError :: TyParamDefaultMismatch ( ty:: ExpectedFound {
1377+ expected : expected,
1378+ found : actual
1379+ } ) ) ;
1380+ }
1381+
12711382 pub fn replace_late_bound_regions_with_fresh_var < T > (
12721383 & self ,
12731384 span : Span ,
0 commit comments