@@ -95,6 +95,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9595 let ( a, b) = if a_is_expected { ( a, b) } else { ( b, a) } ;
9696 let process = |a : Ty < ' tcx > , b : Ty < ' tcx > | match * a. kind ( ) {
9797 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+ } ;
98137 if let ty:: Opaque ( did2, _) = * b. kind ( ) {
99138 // We could accept this, but there are various ways to handle this situation, and we don't
100139 // 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> {
126165 cause. clone ( ) ,
127166 param_env,
128167 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,
168169 ) )
169170 }
170171 _ => None ,
0 commit comments