@@ -653,6 +653,50 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
653
653
}
654
654
}
655
655
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
+
656
700
fn combine_fields ( & ' a self , a_is_expected : bool , trace : TypeTrace < ' tcx > )
657
701
-> CombineFields < ' a , ' tcx > {
658
702
CombineFields { infcx : self ,
@@ -956,13 +1000,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
956
1000
pub fn next_ty_var_id ( & self , diverging : bool ) -> TyVid {
957
1001
self . type_variables
958
1002
. borrow_mut ( )
959
- . new_var ( diverging)
1003
+ . new_var ( diverging, None )
960
1004
}
961
1005
962
1006
pub fn next_ty_var ( & self ) -> Ty < ' tcx > {
963
1007
self . tcx . mk_var ( self . next_ty_var_id ( false ) )
964
1008
}
965
1009
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
+
966
1019
pub fn next_diverging_ty_var ( & self ) -> Ty < ' tcx > {
967
1020
self . tcx . mk_var ( self . next_ty_var_id ( true ) )
968
1021
}
@@ -996,20 +1049,55 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
996
1049
. collect ( )
997
1050
}
998
1051
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
+
999
1077
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
1000
1078
/// type/region parameter to a fresh inference variable.
1001
1079
pub fn fresh_substs_for_generics ( & self ,
1002
1080
span : Span ,
1003
1081
generics : & ty:: Generics < ' tcx > )
1004
1082
-> subst:: Substs < ' tcx >
1005
1083
{
1006
- let type_params =
1007
- generics. types . map (
1008
- |_| self . next_ty_var ( ) ) ;
1084
+ let type_params = subst:: VecPerParamSpace :: empty ( ) ;
1085
+
1009
1086
let region_params =
1010
1087
generics. regions . map (
1011
1088
|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;
1013
1101
}
1014
1102
1015
1103
/// 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> {
1027
1115
assert ! ( generics. regions. len( subst:: SelfSpace ) == 0 ) ;
1028
1116
assert ! ( generics. regions. len( subst:: FnSpace ) == 0 ) ;
1029
1117
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 ( ) ;
1032
1119
1033
1120
let region_param_defs = generics. regions . get_slice ( subst:: TypeSpace ) ;
1034
1121
let regions = self . region_vars_for_defs ( span, region_param_defs) ;
1035
1122
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;
1037
1129
}
1038
1130
1039
1131
pub fn fresh_bound_region ( & self , debruijn : ty:: DebruijnIndex ) -> ty:: Region {
@@ -1268,6 +1360,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1268
1360
self . report_and_explain_type_error ( trace, err) ;
1269
1361
}
1270
1362
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
+
1271
1382
pub fn replace_late_bound_regions_with_fresh_var < T > (
1272
1383
& self ,
1273
1384
span : Span ,
0 commit comments