@@ -88,7 +88,7 @@ use hir::def::{Def, CtorKind};
88
88
use hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
89
89
use rustc_back:: slice:: ref_slice;
90
90
use rustc:: infer:: { self , InferCtxt , InferOk , RegionVariableOrigin } ;
91
- use rustc:: infer:: type_variable:: { self , TypeVariableOrigin } ;
91
+ use rustc:: infer:: type_variable:: { TypeVariableOrigin } ;
92
92
use rustc:: ty:: subst:: { Kind , Subst , Substs } ;
93
93
use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , Reveal } ;
94
94
use rustc:: ty:: { ParamTy , ParameterEnvironment } ;
@@ -105,7 +105,7 @@ use session::{Session, CompileResult};
105
105
use TypeAndSubsts ;
106
106
use lint;
107
107
use util:: common:: { ErrorReported , indenter} ;
108
- use util:: nodemap:: { DefIdMap , FxHashMap , FxHashSet , NodeMap } ;
108
+ use util:: nodemap:: { DefIdMap , FxHashMap , NodeMap } ;
109
109
110
110
use std:: cell:: { Cell , RefCell } ;
111
111
use std:: cmp;
@@ -1978,218 +1978,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1978
1978
}
1979
1979
}
1980
1980
1981
+ // Implements type inference fallback algorithm
1981
1982
fn select_all_obligations_and_apply_defaults ( & self ) {
1982
- if self . tcx . sess . features . borrow ( ) . default_type_parameter_fallback {
1983
- self . new_select_all_obligations_and_apply_defaults ( ) ;
1984
- } else {
1985
- self . old_select_all_obligations_and_apply_defaults ( ) ;
1986
- }
1987
- }
1988
-
1989
- // Implements old type inference fallback algorithm
1990
- fn old_select_all_obligations_and_apply_defaults ( & self ) {
1991
1983
self . select_obligations_where_possible ( ) ;
1992
1984
self . default_type_parameters ( ) ;
1993
1985
self . select_obligations_where_possible ( ) ;
1994
1986
}
1995
1987
1996
- fn new_select_all_obligations_and_apply_defaults ( & self ) {
1997
- use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
1998
- use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
1999
-
2000
- // For the time being this errs on the side of being memory wasteful but provides better
2001
- // error reporting.
2002
- // let type_variables = self.type_variables.clone();
2003
-
2004
- // There is a possibility that this algorithm will have to run an arbitrary number of times
2005
- // to terminate so we bound it by the compiler's recursion limit.
2006
- for _ in 0 ..self . tcx . sess . recursion_limit . get ( ) {
2007
- // First we try to solve all obligations, it is possible that the last iteration
2008
- // has made it possible to make more progress.
2009
- self . select_obligations_where_possible ( ) ;
2010
-
2011
- let mut conflicts = Vec :: new ( ) ;
2012
-
2013
- // Collect all unsolved type, integral and floating point variables.
2014
- let unsolved_variables = self . unsolved_variables ( ) ;
2015
-
2016
- // We must collect the defaults *before* we do any unification. Because we have
2017
- // directly attached defaults to the type variables any unification that occurs
2018
- // will erase defaults causing conflicting defaults to be completely ignored.
2019
- let default_map: FxHashMap < Ty < ' tcx > , _ > =
2020
- unsolved_variables
2021
- . iter ( )
2022
- . filter_map ( |t| self . default ( t) . map ( |d| ( * t, d) ) )
2023
- . collect ( ) ;
2024
-
2025
- let mut unbound_tyvars = FxHashSet ( ) ;
2026
-
2027
- debug ! ( "select_all_obligations_and_apply_defaults: defaults={:?}" , default_map) ;
2028
-
2029
- // We loop over the unsolved variables, resolving them and if they are
2030
- // and unconstrainted numeric type we add them to the set of unbound
2031
- // variables. We do this so we only apply literal fallback to type
2032
- // variables without defaults.
2033
- for ty in & unsolved_variables {
2034
- let resolved = self . resolve_type_vars_if_possible ( ty) ;
2035
- if self . type_var_diverges ( resolved) {
2036
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty,
2037
- self . tcx . mk_diverging_default ( ) ) ;
2038
- } else {
2039
- match self . type_is_unconstrained_numeric ( resolved) {
2040
- UnconstrainedInt | UnconstrainedFloat => {
2041
- unbound_tyvars. insert ( resolved) ;
2042
- } ,
2043
- Neither => { }
2044
- }
2045
- }
2046
- }
2047
-
2048
- // We now remove any numeric types that also have defaults, and instead insert
2049
- // the type variable with a defined fallback.
2050
- for ty in & unsolved_variables {
2051
- if let Some ( _default) = default_map. get ( ty) {
2052
- let resolved = self . resolve_type_vars_if_possible ( ty) ;
2053
-
2054
- debug ! ( "select_all_obligations_and_apply_defaults: \
2055
- ty: {:?} with default: {:?}",
2056
- ty, _default) ;
2057
-
2058
- match resolved. sty {
2059
- ty:: TyInfer ( ty:: TyVar ( _) ) => {
2060
- unbound_tyvars. insert ( ty) ;
2061
- }
2062
-
2063
- ty:: TyInfer ( ty:: IntVar ( _) ) | ty:: TyInfer ( ty:: FloatVar ( _) ) => {
2064
- unbound_tyvars. insert ( ty) ;
2065
- if unbound_tyvars. contains ( resolved) {
2066
- unbound_tyvars. remove ( resolved) ;
2067
- }
2068
- }
2069
-
2070
- _ => { }
2071
- }
2072
- }
2073
- }
2074
-
2075
- // If there are no more fallbacks to apply at this point we have applied all possible
2076
- // defaults and type inference will proceed as normal.
2077
- if unbound_tyvars. is_empty ( ) {
2078
- break ;
2079
- }
2080
-
2081
- // Finally we go through each of the unbound type variables and unify them with
2082
- // the proper fallback, reporting a conflicting default error if any of the
2083
- // unifications fail. We know it must be a conflicting default because the
2084
- // variable would only be in `unbound_tyvars` and have a concrete value if
2085
- // it had been solved by previously applying a default.
2086
-
2087
- // We wrap this in a transaction for error reporting, if we detect a conflict
2088
- // we will rollback the inference context to its prior state so we can probe
2089
- // for conflicts and correctly report them.
2090
-
2091
- let _ = self . commit_if_ok ( |_: & infer:: CombinedSnapshot | {
2092
- conflicts. extend (
2093
- self . apply_defaults_and_return_conflicts ( & unbound_tyvars, & default_map, None )
2094
- ) ;
2095
-
2096
- // If there are conflicts we rollback, otherwise commit
2097
- if conflicts. len ( ) > 0 {
2098
- Err ( ( ) )
2099
- } else {
2100
- Ok ( ( ) )
2101
- }
2102
- } ) ;
2103
-
2104
- // Loop through each conflicting default, figuring out the default that caused
2105
- // a unification failure and then report an error for each.
2106
- for ( conflict, default) in conflicts {
2107
- let conflicting_default =
2108
- self . apply_defaults_and_return_conflicts (
2109
- & unbound_tyvars,
2110
- & default_map,
2111
- Some ( conflict)
2112
- )
2113
- . last ( )
2114
- . map ( |( _, tv) | tv)
2115
- . unwrap_or ( type_variable:: Default {
2116
- ty : self . next_ty_var (
2117
- TypeVariableOrigin :: MiscVariable ( syntax_pos:: DUMMY_SP ) ) ,
2118
- origin_span : syntax_pos:: DUMMY_SP ,
2119
- // what do I put here?
2120
- def_id : self . tcx . hir . local_def_id ( ast:: CRATE_NODE_ID )
2121
- } ) ;
2122
-
2123
- // This is to ensure that we elimnate any non-determinism from the error
2124
- // reporting by fixing an order, it doesn't matter what order we choose
2125
- // just that it is consistent.
2126
- let ( first_default, second_default) =
2127
- if default. def_id < conflicting_default. def_id {
2128
- ( default, conflicting_default)
2129
- } else {
2130
- ( conflicting_default, default)
2131
- } ;
2132
-
2133
-
2134
- self . report_conflicting_default_types (
2135
- first_default. origin_span ,
2136
- self . body_id ,
2137
- first_default,
2138
- second_default)
2139
- }
2140
- }
2141
-
2142
- self . select_obligations_where_possible ( ) ;
2143
- }
2144
-
2145
- // For use in error handling related to default type parameter fallback. We explicitly
2146
- // apply the default that caused conflict first to a local version of the type variable
2147
- // table then apply defaults until we find a conflict. That default must be the one
2148
- // that caused conflict earlier.
2149
- fn apply_defaults_and_return_conflicts < ' b > (
2150
- & ' b self ,
2151
- unbound_vars : & ' b FxHashSet < Ty < ' tcx > > ,
2152
- default_map : & ' b FxHashMap < Ty < ' tcx > , type_variable:: Default < ' tcx > > ,
2153
- conflict : Option < Ty < ' tcx > > ,
2154
- ) -> impl Iterator < Item =( Ty < ' tcx > , type_variable:: Default < ' tcx > ) > + ' b {
2155
- use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
2156
- use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
2157
-
2158
- conflict. into_iter ( ) . chain ( unbound_vars. iter ( ) . cloned ( ) ) . flat_map ( move |ty| {
2159
- if self . type_var_diverges ( ty) {
2160
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty,
2161
- self . tcx . mk_diverging_default ( ) ) ;
2162
- } else {
2163
- match self . type_is_unconstrained_numeric ( ty) {
2164
- UnconstrainedInt => {
2165
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty, self . tcx . types . i32 )
2166
- } ,
2167
- UnconstrainedFloat => {
2168
- self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty, self . tcx . types . f64 )
2169
- } ,
2170
- Neither => {
2171
- if let Some ( default) = default_map. get ( ty) {
2172
- let default = default. clone ( ) ;
2173
- let default_ty = self . normalize_associated_types_in (
2174
- default. origin_span , & default. ty ) ;
2175
- match self . eq_types ( false ,
2176
- & self . misc ( default. origin_span ) ,
2177
- ty,
2178
- default_ty) {
2179
- Ok ( ok) => self . register_infer_ok_obligations ( ok) ,
2180
- Err ( _) => {
2181
- return Some ( ( ty, default) ) ;
2182
- }
2183
- }
2184
- }
2185
- }
2186
- }
2187
- }
2188
-
2189
- None
2190
- } )
2191
- }
2192
-
2193
1988
fn select_all_obligations_or_error ( & self ) {
2194
1989
debug ! ( "select_all_obligations_or_error" ) ;
2195
1990
0 commit comments