@@ -95,6 +95,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
95
95
let ( a, b) = if a_is_expected { ( a, b) } else { ( b, a) } ;
96
96
let process = |a : Ty < ' tcx > , b : Ty < ' tcx > | match * a. kind ( ) {
97
97
ty:: Opaque ( def_id, substs) => {
98
+ let origin = if self . defining_use_anchor . is_some ( ) {
99
+ // Check that this is `impl Trait` type is
100
+ // declared by `parent_def_id` -- i.e., one whose
101
+ // value we are inferring. At present, this is
102
+ // always true during the first phase of
103
+ // type-check, but not always true later on during
104
+ // NLL. Once we support named opaque types more fully,
105
+ // this same scenario will be able to arise during all phases.
106
+ //
107
+ // Here is an example using type alias `impl Trait`
108
+ // that indicates the distinction we are checking for:
109
+ //
110
+ // ```rust
111
+ // mod a {
112
+ // pub type Foo = impl Iterator;
113
+ // pub fn make_foo() -> Foo { .. }
114
+ // }
115
+ //
116
+ // mod b {
117
+ // fn foo() -> a::Foo { a::make_foo() }
118
+ // }
119
+ // ```
120
+ //
121
+ // Here, the return type of `foo` references an
122
+ // `Opaque` indeed, but not one whose value is
123
+ // presently being inferred. You can get into a
124
+ // similar situation with closure return types
125
+ // today:
126
+ //
127
+ // ```rust
128
+ // fn foo() -> impl Iterator { .. }
129
+ // fn bar() {
130
+ // let x = || foo(); // returns the Opaque assoc with `foo`
131
+ // }
132
+ // ```
133
+ self . opaque_type_origin ( def_id, cause. span ) ?
134
+ } else {
135
+ self . opaque_ty_origin_unchecked ( def_id, cause. span )
136
+ } ;
98
137
if let ty:: Opaque ( did2, _) = * b. kind ( ) {
99
138
// We could accept this, but there are various ways to handle this situation, and we don't
100
139
// want to make a decision on it right now. Likely this case is so super rare anyway, that
@@ -126,45 +165,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
126
165
cause. clone ( ) ,
127
166
param_env,
128
167
b,
129
- if self . defining_use_anchor . is_some ( ) {
130
- // Check that this is `impl Trait` type is
131
- // declared by `parent_def_id` -- i.e., one whose
132
- // value we are inferring. At present, this is
133
- // always true during the first phase of
134
- // type-check, but not always true later on during
135
- // NLL. Once we support named opaque types more fully,
136
- // this same scenario will be able to arise during all phases.
137
- //
138
- // Here is an example using type alias `impl Trait`
139
- // that indicates the distinction we are checking for:
140
- //
141
- // ```rust
142
- // mod a {
143
- // pub type Foo = impl Iterator;
144
- // pub fn make_foo() -> Foo { .. }
145
- // }
146
- //
147
- // mod b {
148
- // fn foo() -> a::Foo { a::make_foo() }
149
- // }
150
- // ```
151
- //
152
- // Here, the return type of `foo` references an
153
- // `Opaque` indeed, but not one whose value is
154
- // presently being inferred. You can get into a
155
- // similar situation with closure return types
156
- // today:
157
- //
158
- // ```rust
159
- // fn foo() -> impl Iterator { .. }
160
- // fn bar() {
161
- // let x = || foo(); // returns the Opaque assoc with `foo`
162
- // }
163
- // ```
164
- self . opaque_type_origin ( def_id, cause. span ) ?
165
- } else {
166
- self . opaque_ty_origin_unchecked ( def_id, cause. span )
167
- } ,
168
+ origin,
168
169
) )
169
170
}
170
171
_ => None ,
0 commit comments