@@ -17,6 +17,7 @@ use rustc_hir::lang_items::LangItem;
1717use rustc_hir:: { ExprKind , GenericArg , Node , QPath , TyKind } ;
1818use rustc_infer:: infer:: canonical:: { Canonical , OriginalQueryValues , QueryResponse } ;
1919use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
20+ use rustc_infer:: infer:: type_variable:: Diverging ;
2021use rustc_infer:: infer:: { InferOk , InferResult } ;
2122use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
2223use rustc_middle:: ty:: fold:: TypeFoldable ;
@@ -656,56 +657,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
656657 _ if self . is_tainted_by_errors ( ) => self . tcx ( ) . ty_error ( ) ,
657658 UnconstrainedInt => self . tcx . types . i32 ,
658659 UnconstrainedFloat => self . tcx . types . f64 ,
659- Neither if self . type_var_diverges ( ty) => self . tcx . mk_diverging_default ( ) ,
660- Neither => {
661- // This type variable was created from the instantiation of an opaque
662- // type. The fact that we're attempting to perform fallback for it
663- // means that the function neither constrained it to a concrete
664- // type, nor to the opaque type itself.
665- //
666- // For example, in this code:
667- //
668- //```
669- // type MyType = impl Copy;
670- // fn defining_use() -> MyType { true }
671- // fn other_use() -> MyType { defining_use() }
672- // ```
673- //
674- // `defining_use` will constrain the instantiated inference
675- // variable to `bool`, while `other_use` will constrain
676- // the instantiated inference variable to `MyType`.
677- //
678- // When we process opaque types during writeback, we
679- // will handle cases like `other_use`, and not count
680- // them as defining usages
681- //
682- // However, we also need to handle cases like this:
683- //
684- // ```rust
685- // pub type Foo = impl Copy;
686- // fn produce() -> Option<Foo> {
687- // None
688- // }
689- // ```
690- //
691- // In the above snippet, the inference variable created by
692- // instantiating `Option<Foo>` will be completely unconstrained.
693- // We treat this as a non-defining use by making the inference
694- // variable fall back to the opaque type itself.
695- if let FallbackMode :: All = mode {
696- if let Some ( opaque_ty) = self . infcx . inner . borrow ( ) . opaque_types_vars . get ( ty) {
697- debug ! (
698- "fallback_if_possible: falling back opaque type var {:?} to {:?}" ,
699- ty, opaque_ty
700- ) ;
701- * opaque_ty
660+ Neither => match self . type_var_diverges ( ty) {
661+ Diverging :: Diverges => self . tcx . mk_diverging_default ( ) ,
662+
663+ Diverging :: NotDiverging => {
664+ // This type variable was created from the instantiation of an opaque
665+ // type. The fact that we're attempting to perform fallback for it
666+ // means that the function neither constrained it to a concrete
667+ // type, nor to the opaque type itself.
668+ //
669+ // For example, in this code:
670+ //
671+ //```
672+ // type MyType = impl Copy;
673+ // fn defining_use() -> MyType { true }
674+ // fn other_use() -> MyType { defining_use() }
675+ // ```
676+ //
677+ // `defining_use` will constrain the instantiated inference
678+ // variable to `bool`, while `other_use` will constrain
679+ // the instantiated inference variable to `MyType`.
680+ //
681+ // When we process opaque types during writeback, we
682+ // will handle cases like `other_use`, and not count
683+ // them as defining usages
684+ //
685+ // However, we also need to handle cases like this:
686+ //
687+ // ```rust
688+ // pub type Foo = impl Copy;
689+ // fn produce() -> Option<Foo> {
690+ // None
691+ // }
692+ // ```
693+ //
694+ // In the above snippet, the inference variable created by
695+ // instantiating `Option<Foo>` will be completely unconstrained.
696+ // We treat this as a non-defining use by making the inference
697+ // variable fall back to the opaque type itself.
698+ if let FallbackMode :: All = mode {
699+ if let Some ( opaque_ty) = self . infcx . inner . borrow ( ) . opaque_types_vars . get ( ty)
700+ {
701+ debug ! (
702+ "fallback_if_possible: falling back opaque type var {:?} to {:?}" ,
703+ ty, opaque_ty
704+ ) ;
705+ * opaque_ty
706+ } else {
707+ return false ;
708+ }
702709 } else {
703710 return false ;
704711 }
705- } else {
706- return false ;
707712 }
708- }
713+ } ,
709714 } ;
710715 debug ! ( "fallback_if_possible: defaulting `{:?}` to `{:?}`" , ty, fallback) ;
711716 self . demand_eqtype ( rustc_span:: DUMMY_SP , ty, fallback) ;
0 commit comments