@@ -879,6 +879,30 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
879879/// variables introduced by the projection of associated types. This ensures that
880880/// any opaque types used in the signature continue to refer to generic parameters,
881881/// allowing them to be considered for defining uses in the function body
882+ ///
883+ /// For example, consider this code.
884+ ///
885+ /// ```rust
886+ /// trait MyTrait {
887+ /// type MyItem;
888+ /// fn use_it(self) -> Self::MyItem
889+ /// }
890+ /// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
891+ /// type MyItem = impl Iterator<Item = I>;
892+ /// fn use_it(self) -> Self::MyItem {
893+ /// self
894+ /// }
895+ /// }
896+ /// ```
897+ ///
898+ /// When we normalize the signature of `use_it` from the impl block,
899+ /// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
900+ /// However, this projection result may contain inference variables, due
901+ /// to the way that projection works. We didn't have any inference variables
902+ /// in the signature to begin with - leaving them in will cause us to incorrectly
903+ /// conclude that we don't have a defining use of `MyItem`. By mapping inference
904+ /// variables back to the actual generic parameters, we will correctly see that
905+ /// we have a defining use of `MyItem`
882906fn fixup_opaque_types < ' tcx , T > ( tcx : TyCtxt < ' tcx > , val : & T ) -> T where T : TypeFoldable < ' tcx > {
883907 struct FixupFolder < ' tcx > {
884908 tcx : TyCtxt < ' tcx >
@@ -893,6 +917,14 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol
893917 match ty. kind {
894918 ty:: Opaque ( def_id, substs) => {
895919 debug ! ( "fixup_opaque_types: found type {:?}" , ty) ;
920+ // Here, we replace any inference variables that occur within
921+ // the substs of an opaque type. By definition, any type occuring
922+ // in the substs has a corresponding generic parameter, which is what
923+ // we replace it with.
924+ // This replacement is only run on the function signature, so any
925+ // inference variables that we come across must be the rust of projection
926+ // (there's no other way for a user to get inference variables into
927+ // a function signature).
896928 if ty. needs_infer ( ) {
897929 let new_substs = InternalSubsts :: for_item ( self . tcx , def_id, |param, _| {
898930 let old_param = substs[ param. index as usize ] ;
0 commit comments