@@ -879,6 +879,30 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
879
879
/// variables introduced by the projection of associated types. This ensures that
880
880
/// any opaque types used in the signature continue to refer to generic parameters,
881
881
/// 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`
882
906
fn fixup_opaque_types < ' tcx , T > ( tcx : TyCtxt < ' tcx > , val : & T ) -> T where T : TypeFoldable < ' tcx > {
883
907
struct FixupFolder < ' tcx > {
884
908
tcx : TyCtxt < ' tcx >
@@ -893,6 +917,14 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol
893
917
match ty. kind {
894
918
ty:: Opaque ( def_id, substs) => {
895
919
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).
896
928
if ty. needs_infer ( ) {
897
929
let new_substs = InternalSubsts :: for_item ( self . tcx , def_id, |param, _| {
898
930
let old_param = substs[ param. index as usize ] ;
0 commit comments