@@ -1935,10 +1935,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
19351935 // We must collect the defaults *before* we do any unification. Because we have
19361936 // directly attached defaults to the type variables any unification that occurs
19371937 // will erase defaults causing conflicting defaults to be completely ignored.
1938- let default_map: FxHashMap < _ , _ > =
1938+ let default_map: FxHashMap < Ty < ' tcx > , _ > =
19391939 unsolved_variables
19401940 . iter ( )
1941- . filter_map ( |t| self . default ( t) . map ( |d| ( t, d) ) )
1941+ . filter_map ( |t| self . default ( t) . map ( |d| ( * t, d) ) )
19421942 . collect ( ) ;
19431943
19441944 let mut unbound_tyvars = FxHashSet ( ) ;
@@ -2007,37 +2007,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20072007 // we will rollback the inference context to its prior state so we can probe
20082008 // for conflicts and correctly report them.
20092009
2010-
20112010 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+ ) ;
20412014
20422015 // If there are conflicts we rollback, otherwise commit
20432016 if conflicts. len ( ) > 0 {
@@ -2047,37 +2020,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20472020 }
20482021 } ) ;
20492022
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+ } ;
20732051
20742052
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)
20812058 }
20822059 }
20832060
@@ -2088,56 +2065,48 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
20882065 // apply the default that caused conflict first to a local version of the type variable
20892066 // table then apply defaults until we find a conflict. That default must be the one
20902067 // 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 {
20962074 use rustc:: ty:: error:: UnconstrainedNumeric :: Neither ;
20972075 use rustc:: ty:: error:: UnconstrainedNumeric :: { UnconstrainedInt , UnconstrainedFloat } ;
20982076
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| {
21112078 if self . type_var_diverges ( ty) {
2112- self . demand_eqtype ( syntax_pos:: DUMMY_SP , * ty,
2079+ self . demand_eqtype ( syntax_pos:: DUMMY_SP , ty,
21132080 self . tcx . mk_diverging_default ( ) ) ;
21142081 } else {
21152082 match self . type_is_unconstrained_numeric ( ty) {
21162083 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 )
21182085 } ,
21192086 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 )
21212088 } ,
21222089 Neither => {
21232090 if let Some ( default) = default_map. get ( ty) {
21242091 let default = default. clone ( ) ;
2092+ let default_ty = self . normalize_associated_types_in (
2093+ default. origin_span , & default. ty ) ;
21252094 match self . eq_types ( false ,
21262095 & self . misc ( default. origin_span ) ,
21272096 ty,
2128- default . ty ) {
2097+ default_ty ) {
21292098 Ok ( ok) => self . register_infer_ok_obligations ( ok) ,
21302099 Err ( _) => {
2131- result = Some ( default) ;
2100+ return Some ( ( ty , default) ) ;
21322101 }
21332102 }
21342103 }
21352104 }
21362105 }
21372106 }
2138- }
21392107
2140- return result;
2108+ None
2109+ } )
21412110 }
21422111
21432112 fn select_all_obligations_or_error ( & self ) {
0 commit comments