@@ -85,15 +85,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
8585 return false ;
8686 }
8787
88- let diverging_fallback = self . calculate_diverging_fallback ( & unresolved_variables) ;
88+ let ( diverging_fallback, diverging_fallback_ty) =
89+ self . calculate_diverging_fallback ( & unresolved_variables) ;
8990
9091 // We do fallback in two passes, to try to generate
9192 // better error messages.
9293 // The first time, we do *not* replace opaque types.
9394 let mut fallback_occurred = false ;
9495 for ty in unresolved_variables {
9596 debug ! ( "unsolved_variable = {:?}" , ty) ;
96- fallback_occurred |= self . fallback_if_possible ( ty, & diverging_fallback) ;
97+ fallback_occurred |=
98+ self . fallback_if_possible ( ty, & diverging_fallback, diverging_fallback_ty) ;
9799 }
98100
99101 fallback_occurred
@@ -117,7 +119,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
117119 fn fallback_if_possible (
118120 & self ,
119121 ty : Ty < ' tcx > ,
120- diverging_fallback : & UnordMap < Ty < ' tcx > , Ty < ' tcx > > ,
122+ diverging_fallback : & UnordSet < Ty < ' tcx > > ,
123+ diverging_fallback_ty : Ty < ' tcx > ,
121124 ) -> bool {
122125 // Careful: we do NOT shallow-resolve `ty`. We know that `ty`
123126 // is an unsolved variable, and we determine its fallback
@@ -141,13 +144,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
141144 _ if let Some ( e) = self . tainted_by_errors ( ) => Ty :: new_error ( self . tcx , e) ,
142145 ty:: Infer ( ty:: IntVar ( _) ) => self . tcx . types . i32 ,
143146 ty:: Infer ( ty:: FloatVar ( _) ) => self . tcx . types . f64 ,
144- _ => match diverging_fallback. get ( & ty) {
145- Some ( & fallback_ty) => {
146- self . never_type_fallback_has_occurred . set ( true ) ;
147- fallback_ty
148- }
149- None => return false ,
150- } ,
147+ _ if diverging_fallback. contains ( & ty) => {
148+ self . never_type_fallback_has_occurred . set ( true ) ;
149+ diverging_fallback_ty
150+ }
151+ _ => return false ,
151152 } ;
152153 debug ! ( "fallback_if_possible(ty={:?}): defaulting to `{:?}`" , ty, fallback) ;
153154
@@ -159,9 +160,18 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
159160 fn calculate_diverging_fallback (
160161 & self ,
161162 unresolved_variables : & [ Ty < ' tcx > ] ,
162- ) -> UnordMap < Ty < ' tcx > , Ty < ' tcx > > {
163+ ) -> ( UnordSet < Ty < ' tcx > > , Ty < ' tcx > ) {
163164 debug ! ( "calculate_diverging_fallback({:?})" , unresolved_variables) ;
164165
166+ let diverging_fallback_ty = match self . diverging_fallback_behavior {
167+ DivergingFallbackBehavior :: ToUnit => self . tcx . types . unit ,
168+ DivergingFallbackBehavior :: ToNever => self . tcx . types . never ,
169+ DivergingFallbackBehavior :: NoFallback => {
170+ // the type doesn't matter, since no fallback will occur
171+ return ( UnordSet :: new ( ) , self . tcx . types . unit ) ;
172+ }
173+ } ;
174+
165175 // Construct a coercion graph where an edge `A -> B` indicates
166176 // a type variable is that is coerced
167177 let coercion_graph = self . create_coercion_graph ( ) ;
@@ -216,7 +226,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
216226
217227 debug ! ( "obligations: {:#?}" , self . fulfillment_cx. borrow_mut( ) . pending_obligations( ) ) ;
218228
219- let mut diverging_fallback = UnordMap :: with_capacity ( diverging_vids. len ( ) ) ;
229+ let mut diverging_fallback = UnordSet :: with_capacity ( diverging_vids. len ( ) ) ;
220230 let unsafe_infer_vars = OnceCell :: new ( ) ;
221231
222232 self . lint_obligations_broken_by_never_type_fallback_change (
@@ -228,38 +238,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
228238 let diverging_ty = Ty :: new_var ( self . tcx , diverging_vid) ;
229239 let root_vid = self . root_var ( diverging_vid) ;
230240
231- let mut fallback_to = |ty| {
232- self . lint_never_type_fallback_flowing_into_unsafe_code (
233- & unsafe_infer_vars,
234- & coercion_graph,
235- root_vid,
236- ) ;
237-
238- diverging_fallback. insert ( diverging_ty, ty) ;
239- } ;
241+ self . lint_never_type_fallback_flowing_into_unsafe_code (
242+ & unsafe_infer_vars,
243+ & coercion_graph,
244+ root_vid,
245+ ) ;
240246
241- match self . diverging_fallback_behavior {
242- DivergingFallbackBehavior :: ToUnit => {
243- debug ! ( "fallback to () - legacy: {:?}" , diverging_vid) ;
244- fallback_to ( self . tcx . types . unit ) ;
245- }
246- DivergingFallbackBehavior :: ToNever => {
247- debug ! (
248- "fallback to ! - `rustc_never_type_options::falback = \" never\" )`: {:?}" ,
249- diverging_vid
250- ) ;
251- fallback_to ( self . tcx . types . never ) ;
252- }
253- DivergingFallbackBehavior :: NoFallback => {
254- debug ! (
255- "no fallback - `rustc_never_type_options::fallback = \" no\" `: {:?}" ,
256- diverging_vid
257- ) ;
258- }
259- }
247+ diverging_fallback. insert ( diverging_ty) ;
260248 }
261249
262- diverging_fallback
250+ ( diverging_fallback, diverging_fallback_ty )
263251 }
264252
265253 fn lint_never_type_fallback_flowing_into_unsafe_code (
0 commit comments