@@ -1935,10 +1935,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1935
1935
// We must collect the defaults *before* we do any unification. Because we have
1936
1936
// directly attached defaults to the type variables any unification that occurs
1937
1937
// will erase defaults causing conflicting defaults to be completely ignored.
1938
- let default_map: FxHashMap < _ , _ > =
1938
+ let default_map: FxHashMap < Ty < ' tcx > , _ > =
1939
1939
unsolved_variables
1940
1940
. iter ( )
1941
- . filter_map ( |t| self . default ( t) . map ( |d| ( t, d) ) )
1941
+ . filter_map ( |t| self . default ( t) . map ( |d| ( * t, d) ) )
1942
1942
. collect ( ) ;
1943
1943
1944
1944
let mut unbound_tyvars = FxHashSet ( ) ;
@@ -2007,37 +2007,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2007
2007
// we will rollback the inference context to its prior state so we can probe
2008
2008
// for conflicts and correctly report them.
2009
2009
2010
-
2011
2010
let _ = self . commit_if_ok ( |_: & infer:: CombinedSnapshot | {
2012
- for ty in & unbound_tyvars {
2013
- if self . type_var_diverges ( ty) {
2014
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty,
2015
- self . tcx . mk_diverging_default ( ) ) ;
2016
- } else {
2017
- match self . type_is_unconstrained_numeric ( ty) {
2018
- UnconstrainedInt => {
2019
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . i32 )
2020
- } ,
2021
- UnconstrainedFloat => {
2022
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . f64 )
2023
- }
2024
- Neither => {
2025
- if let Some ( default) = default_map. get ( ty) {
2026
- let default = default. clone ( ) ;
2027
- let default_ty = self . normalize_associated_types_in (
2028
- default. origin_span , & default. ty ) ;
2029
- match self . eq_types ( false ,
2030
- & self . misc ( default. origin_span ) ,
2031
- ty,
2032
- default_ty) {
2033
- Ok ( ok) => self . register_infer_ok_obligations ( ok) ,
2034
- Err ( _) => conflicts. push ( ( * ty, default) ) ,
2035
- }
2036
- }
2037
- }
2038
- }
2039
- }
2040
- }
2011
+ conflicts. extend (
2012
+ self . apply_defaults_and_return_conflicts ( & unbound_tyvars, & default_map, None )
2013
+ ) ;
2041
2014
2042
2015
// If there are conflicts we rollback, otherwise commit
2043
2016
if conflicts. len ( ) > 0 {
@@ -2047,37 +2020,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2047
2020
}
2048
2021
} ) ;
2049
2022
2050
- if conflicts. len ( ) > 0 {
2051
- // Loop through each conflicting default, figuring out the default that caused
2052
- // a unification failure and then report an error for each.
2053
- for ( conflict, default) in conflicts {
2054
- let conflicting_default =
2055
- self . find_conflicting_default ( & unbound_tyvars, & default_map, conflict)
2056
- . unwrap_or ( type_variable:: Default {
2057
- ty : self . next_ty_var (
2058
- TypeVariableOrigin :: MiscVariable ( syntax_pos:: DUMMY_SP ) ) ,
2059
- origin_span : syntax_pos:: DUMMY_SP ,
2060
- // what do I put here?
2061
- def_id : self . tcx . hir . local_def_id ( ast:: CRATE_NODE_ID )
2062
- } ) ;
2063
-
2064
- // This is to ensure that we elimnate any non-determinism from the error
2065
- // reporting by fixing an order, it doesn't matter what order we choose
2066
- // just that it is consistent.
2067
- let ( first_default, second_default) =
2068
- if default. def_id < conflicting_default. def_id {
2069
- ( default, conflicting_default)
2070
- } else {
2071
- ( conflicting_default, default)
2072
- } ;
2023
+ // Loop through each conflicting default, figuring out the default that caused
2024
+ // a unification failure and then report an error for each.
2025
+ for ( conflict, default) in conflicts {
2026
+ let conflicting_default =
2027
+ self . apply_defaults_and_return_conflicts (
2028
+ & unbound_tyvars,
2029
+ & default_map,
2030
+ Some ( conflict)
2031
+ )
2032
+ . last ( )
2033
+ . map ( |( _, tv) | tv)
2034
+ . unwrap_or ( type_variable:: Default {
2035
+ ty : self . next_ty_var (
2036
+ TypeVariableOrigin :: MiscVariable ( syntax_pos:: DUMMY_SP ) ) ,
2037
+ origin_span : syntax_pos:: DUMMY_SP ,
2038
+ // what do I put here?
2039
+ def_id : self . tcx . hir . local_def_id ( ast:: CRATE_NODE_ID )
2040
+ } ) ;
2041
+
2042
+ // This is to ensure that we elimnate any non-determinism from the error
2043
+ // reporting by fixing an order, it doesn't matter what order we choose
2044
+ // just that it is consistent.
2045
+ let ( first_default, second_default) =
2046
+ if default. def_id < conflicting_default. def_id {
2047
+ ( default, conflicting_default)
2048
+ } else {
2049
+ ( conflicting_default, default)
2050
+ } ;
2073
2051
2074
2052
2075
- self . report_conflicting_default_types (
2076
- first_default. origin_span ,
2077
- self . body_id ,
2078
- first_default,
2079
- second_default)
2080
- }
2053
+ self . report_conflicting_default_types (
2054
+ first_default. origin_span ,
2055
+ self . body_id ,
2056
+ first_default,
2057
+ second_default)
2081
2058
}
2082
2059
}
2083
2060
@@ -2088,56 +2065,48 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2088
2065
// apply the default that caused conflict first to a local version of the type variable
2089
2066
// table then apply defaults until we find a conflict. That default must be the one
2090
2067
// that caused conflict earlier.
2091
- fn find_conflicting_default ( & self ,
2092
- unbound_vars : & FxHashSet < Ty < ' tcx > > ,
2093
- default_map : & FxHashMap < & Ty < ' tcx > , type_variable:: Default < ' tcx > > ,
2094
- conflict : Ty < ' tcx > )
2095
- -> Option < type_variable:: Default < ' tcx > > {
2068
+ fn apply_defaults_and_return_conflicts < ' b > (
2069
+ & ' b self ,
2070
+ unbound_vars : & ' b FxHashSet < Ty < ' tcx > > ,
2071
+ default_map : & ' b FxHashMap < Ty < ' tcx > , type_variable:: Default < ' tcx > > ,
2072
+ conflict : Option < Ty < ' tcx > > ,
2073
+ ) -> impl Iterator < Item =( Ty < ' tcx > , type_variable:: Default < ' tcx > ) > + ' b {
2096
2074
use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
2097
2075
use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
2098
2076
2099
- // Ensure that we apply the conflicting default first
2100
- let mut unbound_tyvars = Vec :: with_capacity ( unbound_vars. len ( ) + 1 ) ;
2101
- unbound_tyvars. push ( conflict) ;
2102
- unbound_tyvars. extend ( unbound_vars. iter ( ) ) ;
2103
-
2104
- let mut result = None ;
2105
- // We run the same code as above applying defaults in order, this time when
2106
- // we find the conflict we just return it for error reporting above.
2107
-
2108
- // We also run this inside snapshot that never commits so we can do error
2109
- // reporting for more then one conflict.
2110
- for ty in & unbound_tyvars {
2077
+ conflict. into_iter ( ) . chain ( unbound_vars. iter ( ) . cloned ( ) ) . flat_map ( move |ty| {
2111
2078
if self . type_var_diverges ( ty) {
2112
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty,
2079
+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty,
2113
2080
self . tcx . mk_diverging_default ( ) ) ;
2114
2081
} else {
2115
2082
match self . type_is_unconstrained_numeric ( ty) {
2116
2083
UnconstrainedInt => {
2117
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . i32 )
2084
+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty, self . tcx . types . i32 )
2118
2085
} ,
2119
2086
UnconstrainedFloat => {
2120
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty, self . tcx . types . f64 )
2087
+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty, self . tcx . types . f64 )
2121
2088
} ,
2122
2089
Neither => {
2123
2090
if let Some ( default) = default_map. get ( ty) {
2124
2091
let default = default. clone ( ) ;
2092
+ let default_ty = self . normalize_associated_types_in (
2093
+ default. origin_span , & default. ty ) ;
2125
2094
match self . eq_types ( false ,
2126
2095
& self . misc ( default. origin_span ) ,
2127
2096
ty,
2128
- default . ty ) {
2097
+ default_ty ) {
2129
2098
Ok ( ok) => self . register_infer_ok_obligations ( ok) ,
2130
2099
Err ( _) => {
2131
- result = Some ( default) ;
2100
+ return Some ( ( ty , default) ) ;
2132
2101
}
2133
2102
}
2134
2103
}
2135
2104
}
2136
2105
}
2137
2106
}
2138
- }
2139
2107
2140
- return result;
2108
+ None
2109
+ } )
2141
2110
}
2142
2111
2143
2112
fn select_all_obligations_or_error ( & self ) {
0 commit comments