@@ -350,6 +350,51 @@ impl<'a> InferenceTable<'a> {
350
350
self . resolve_with_fallback ( t, & |_, _, d, _| d)
351
351
}
352
352
353
+ /// Apply a fallback to unresolved scalar types. Integer type variables and float type
354
+ /// variables are replaced with i32 and f64, respectively.
355
+ ///
356
+ /// This method is only intended to be called just before returning inference results (i.e. in
357
+ /// `InferenceContext::resolve_all()`).
358
+ ///
359
+ /// FIXME: This method currently doesn't apply fallback to unconstrained general type variables
360
+ /// whereas rustc replaces them with `()` or `!`.
361
+ pub ( super ) fn fallback_if_possible ( & mut self ) {
362
+ let int_fallback = TyKind :: Scalar ( Scalar :: Int ( IntTy :: I32 ) ) . intern ( Interner ) ;
363
+ let float_fallback = TyKind :: Scalar ( Scalar :: Float ( FloatTy :: F64 ) ) . intern ( Interner ) ;
364
+
365
+ let scalar_vars: Vec < _ > = self
366
+ . type_variable_table
367
+ . iter ( )
368
+ . enumerate ( )
369
+ . filter_map ( |( index, flags) | {
370
+ let kind = if flags. contains ( TypeVariableFlags :: INTEGER ) {
371
+ TyVariableKind :: Integer
372
+ } else if flags. contains ( TypeVariableFlags :: FLOAT ) {
373
+ TyVariableKind :: Float
374
+ } else {
375
+ return None ;
376
+ } ;
377
+
378
+ // FIXME: This is not really the nicest way to get `InferenceVar`s. Can we get them
379
+ // without directly constructing them from `index`?
380
+ let var = InferenceVar :: from ( index as u32 ) . to_ty ( Interner , kind) ;
381
+ Some ( var)
382
+ } )
383
+ . collect ( ) ;
384
+
385
+ for var in scalar_vars {
386
+ let maybe_resolved = self . resolve_ty_shallow ( & var) ;
387
+ if let TyKind :: InferenceVar ( _, kind) = maybe_resolved. kind ( Interner ) {
388
+ let fallback = match kind {
389
+ TyVariableKind :: Integer => & int_fallback,
390
+ TyVariableKind :: Float => & float_fallback,
391
+ TyVariableKind :: General => unreachable ! ( ) ,
392
+ } ;
393
+ self . unify ( & var, fallback) ;
394
+ }
395
+ }
396
+ }
397
+
353
398
/// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
354
399
pub ( crate ) fn unify < T : ?Sized + Zip < Interner > > ( & mut self , ty1 : & T , ty2 : & T ) -> bool {
355
400
let result = match self . try_unify ( ty1, ty2) {
0 commit comments