@@ -63,15 +63,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
6363 return false ;
6464 }
6565
66- let diverging_fallback = self . calculate_diverging_fallback ( & unresolved_variables) ;
66+ let ( diverging_fallback, diverging_fallback_ty) =
67+ self . calculate_diverging_fallback ( & unresolved_variables) ;
6768
6869 // We do fallback in two passes, to try to generate
6970 // better error messages.
7071 // The first time, we do *not* replace opaque types.
7172 let mut fallback_occurred = false ;
7273 for ty in unresolved_variables {
7374 debug ! ( "unsolved_variable = {:?}" , ty) ;
74- fallback_occurred |= self . fallback_if_possible ( ty, & diverging_fallback) ;
75+ fallback_occurred |=
76+ self . fallback_if_possible ( ty, & diverging_fallback, diverging_fallback_ty) ;
7577 }
7678
7779 fallback_occurred
@@ -95,7 +97,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
9597 fn fallback_if_possible (
9698 & self ,
9799 ty : Ty < ' tcx > ,
98- diverging_fallback : & UnordMap < Ty < ' tcx > , Ty < ' tcx > > ,
100+ diverging_fallback : & UnordSet < Ty < ' tcx > > ,
101+ diverging_fallback_ty : Ty < ' tcx > ,
99102 ) -> bool {
100103 // Careful: we do NOT shallow-resolve `ty`. We know that `ty`
101104 // is an unsolved variable, and we determine its fallback
@@ -119,13 +122,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
119122 _ if let Some ( e) = self . tainted_by_errors ( ) => Ty :: new_error ( self . tcx , e) ,
120123 ty:: Infer ( ty:: IntVar ( _) ) => self . tcx . types . i32 ,
121124 ty:: Infer ( ty:: FloatVar ( _) ) => self . tcx . types . f64 ,
122- _ => match diverging_fallback. get ( & ty) {
123- Some ( & fallback_ty) => {
124- self . diverging_fallback_has_occurred . set ( true ) ;
125- fallback_ty
126- }
127- None => return false ,
128- } ,
125+ _ if diverging_fallback. contains ( & ty) => {
126+ self . diverging_fallback_has_occurred . set ( true ) ;
127+ diverging_fallback_ty
128+ }
129+ _ => return false ,
129130 } ;
130131 debug ! ( "fallback_if_possible(ty={:?}): defaulting to `{:?}`" , ty, fallback) ;
131132
@@ -137,9 +138,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
137138 fn calculate_diverging_fallback (
138139 & self ,
139140 unresolved_variables : & [ Ty < ' tcx > ] ,
140- ) -> UnordMap < Ty < ' tcx > , Ty < ' tcx > > {
141+ ) -> ( UnordSet < Ty < ' tcx > > , Ty < ' tcx > ) {
141142 debug ! ( "calculate_diverging_fallback({:?})" , unresolved_variables) ;
142143
144+ let diverging_fallback_ty = match self . diverging_fallback_behavior {
145+ DivergingFallbackBehavior :: ToUnit => self . tcx . types . unit ,
146+ DivergingFallbackBehavior :: ToNever => self . tcx . types . never ,
147+ DivergingFallbackBehavior :: NoFallback => {
148+ // the type doesn't matter, since no fallback will occur
149+ return ( UnordSet :: new ( ) , self . tcx . types . unit ) ;
150+ }
151+ } ;
152+
143153 // Construct a coercion graph where an edge `A -> B` indicates
144154 // a type variable is that is coerced
145155 let coercion_graph = self . create_coercion_graph ( ) ;
@@ -194,7 +204,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
194204
195205 debug ! ( "obligations: {:#?}" , self . fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
196206
197- let mut diverging_fallback = UnordMap :: with_capacity ( diverging_vids. len ( ) ) ;
207+ let mut diverging_fallback = UnordSet :: with_capacity ( diverging_vids. len ( ) ) ;
198208 let unsafe_infer_vars = OnceCell :: new ( ) ;
199209
200210 self . lint_obligations_broken_by_never_type_fallback_change (
@@ -206,38 +216,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
206216 let diverging_ty = Ty :: new_var ( self . tcx , diverging_vid) ;
207217 let root_vid = self . root_var ( diverging_vid) ;
208218
209- let mut fallback_to = |ty| {
210- self . lint_never_type_fallback_flowing_into_unsafe_code (
211- & unsafe_infer_vars,
212- & coercion_graph,
213- root_vid,
214- ) ;
215-
216- diverging_fallback. insert ( diverging_ty, ty) ;
217- } ;
219+ self . lint_never_type_fallback_flowing_into_unsafe_code (
220+ & unsafe_infer_vars,
221+ & coercion_graph,
222+ root_vid,
223+ ) ;
218224
219- match self . diverging_fallback_behavior {
220- DivergingFallbackBehavior :: ToUnit => {
221- debug ! ( "fallback to () - legacy: {:?}" , diverging_vid) ;
222- fallback_to ( self . tcx . types . unit ) ;
223- }
224- DivergingFallbackBehavior :: ToNever => {
225- debug ! (
226- "fallback to ! - `rustc_never_type_options::falback = \" never\" )`: {:?}" ,
227- diverging_vid
228- ) ;
229- fallback_to ( self . tcx . types . never ) ;
230- }
231- DivergingFallbackBehavior :: NoFallback => {
232- debug ! (
233- "no fallback - `rustc_never_type_options::fallback = \" no\" `: {:?}" ,
234- diverging_vid
235- ) ;
236- }
237- }
225+ diverging_fallback. insert ( diverging_ty) ;
238226 }
239227
240- diverging_fallback
228+ ( diverging_fallback, diverging_fallback_ty )
241229 }
242230
243231 fn lint_never_type_fallback_flowing_into_unsafe_code (
0 commit comments