]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_infer/src/infer/opaque_types.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_infer / src / infer / opaque_types.rs
CommitLineData
353b0b11
FG
1use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2use super::{DefineOpaqueTypes, InferResult};
f2b60f7d 3use crate::errors::OpaqueHiddenTypeDiag;
49aad941
FG
4use crate::infer::{InferCtxt, InferOk};
5use crate::traits::{self, PredicateObligation};
5e7ed085 6use hir::def_id::{DefId, LocalDefId};
9ffffee4 7use hir::OpaqueTyOrigin;
353b0b11 8use rustc_data_structures::fx::FxIndexMap;
3c0e092e 9use rustc_data_structures::sync::Lrc;
94222f64 10use rustc_hir as hir;
49aad941 11use rustc_middle::traits::{DefiningAnchor, ObligationCause};
2b03887a 12use rustc_middle::ty::error::{ExpectedFound, TypeError};
3c0e092e 13use rustc_middle::ty::fold::BottomUpFolder;
2b03887a 14use rustc_middle::ty::GenericArgKind;
5e7ed085 15use rustc_middle::ty::{
064997fb 16 self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
9ffffee4 17 TypeVisitable, TypeVisitableExt, TypeVisitor,
5e7ed085 18};
94222f64 19use rustc_span::Span;
3c0e092e
XL
20use std::ops::ControlFlow;
21
5e7ed085
FG
22mod table;
23
353b0b11 24pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
5e7ed085
FG
25pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
26
94222f64
XL
27/// Information about the opaque types whose values we
28/// are inferring in this function (these are the `impl Trait` that
29/// appear in the return type).
5e7ed085 30#[derive(Clone, Debug)]
94222f64 31pub struct OpaqueTypeDecl<'tcx> {
5e7ed085
FG
32 /// The hidden types that have been inferred for this opaque type.
33 /// There can be multiple, but they are all `lub`ed together at the end
34 /// to obtain the canonical hidden type.
35 pub hidden_type: OpaqueHiddenType<'tcx>,
94222f64
XL
36
37 /// The origin of the opaque type.
38 pub origin: hir::OpaqueTyOrigin,
39}
3c0e092e 40
2b03887a 41impl<'tcx> InferCtxt<'tcx> {
5e7ed085
FG
42 /// This is a backwards compatibility hack to prevent breaking changes from
43 /// lazy TAIT around RPIT handling.
9ffffee4 44 pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
3c0e092e 45 &self,
3c0e092e 46 value: T,
9ffffee4 47 body_id: LocalDefId,
5e7ed085
FG
48 span: Span,
49 param_env: ty::ParamEnv<'tcx>,
3c0e092e 50 ) -> InferOk<'tcx, T> {
49aad941
FG
51 // We handle opaque types differently in the new solver.
52 if self.tcx.trait_solver_next() {
53 return InferOk { value, obligations: vec![] };
54 }
55
5e7ed085
FG
56 if !value.has_opaque_types() {
57 return InferOk { value, obligations: vec![] };
58 }
49aad941 59
5e7ed085 60 let mut obligations = vec![];
064997fb 61 let replace_opaque_type = |def_id: DefId| {
49aad941 62 def_id.as_local().is_some_and(|def_id| self.opaque_type_origin(def_id).is_some())
064997fb 63 };
9c376795 64 let value = value.fold_with(&mut BottomUpFolder {
5e7ed085
FG
65 tcx: self.tcx,
66 lt_op: |lt| lt,
67 ct_op: |ct| ct,
68 ty_op: |ty| match *ty.kind() {
9c376795
FG
69 ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })
70 if replace_opaque_type(def_id) =>
71 {
064997fb
FG
72 let def_span = self.tcx.def_span(def_id);
73 let span = if span.contains(def_span) { def_span } else { span };
74 let code = traits::ObligationCauseCode::OpaqueReturnType(None);
75 let cause = ObligationCause::new(span, body_id, code);
923072b8
FG
76 // FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
77 // for opaque types, and then use that kind to fix the spans for type errors
78 // that we see later on.
5e7ed085 79 let ty_var = self.next_ty_var(TypeVariableOrigin {
f2b60f7d 80 kind: TypeVariableOriginKind::OpaqueTypeInference(def_id),
923072b8 81 span,
5e7ed085
FG
82 });
83 obligations.extend(
84 self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
85 .unwrap()
86 .obligations,
87 );
88 ty_var
89 }
90 _ => ty,
91 },
92 });
93 InferOk { value, obligations }
94 }
95
96 pub fn handle_opaque_type(
97 &self,
98 a: Ty<'tcx>,
99 b: Ty<'tcx>,
100 a_is_expected: bool,
101 cause: &ObligationCause<'tcx>,
102 param_env: ty::ParamEnv<'tcx>,
103 ) -> InferResult<'tcx, ()> {
104 if a.references_error() || b.references_error() {
105 return Ok(InferOk { value: (), obligations: vec![] });
106 }
107 let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
2b03887a 108 let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
9c376795 109 ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => {
064997fb
FG
110 let def_id = def_id.expect_local();
111 let origin = match self.defining_use_anchor {
112 DefiningAnchor::Bind(_) => {
113 // Check that this is `impl Trait` type is
114 // declared by `parent_def_id` -- i.e., one whose
9c376795 115 // value we are inferring. At present, this is
064997fb
FG
116 // always true during the first phase of
117 // type-check, but not always true later on during
118 // NLL. Once we support named opaque types more fully,
119 // this same scenario will be able to arise during all phases.
120 //
121 // Here is an example using type alias `impl Trait`
122 // that indicates the distinction we are checking for:
123 //
124 // ```rust
125 // mod a {
126 // pub type Foo = impl Iterator;
127 // pub fn make_foo() -> Foo { .. }
128 // }
129 //
130 // mod b {
131 // fn foo() -> a::Foo { a::make_foo() }
132 // }
133 // ```
134 //
135 // Here, the return type of `foo` references an
136 // `Opaque` indeed, but not one whose value is
137 // presently being inferred. You can get into a
138 // similar situation with closure return types
139 // today:
140 //
141 // ```rust
142 // fn foo() -> impl Iterator { .. }
143 // fn bar() {
144 // let x = || foo(); // returns the Opaque assoc with `foo`
145 // }
146 // ```
9ffffee4 147 self.opaque_type_origin(def_id)?
064997fb 148 }
9ffffee4 149 DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id),
064997fb 150 DefiningAnchor::Error => return None,
5e7ed085 151 };
9c376795 152 if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
5e7ed085
FG
153 // We could accept this, but there are various ways to handle this situation, and we don't
154 // want to make a decision on it right now. Likely this case is so super rare anyway, that
155 // no one encounters it in practice.
156 // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
157 // where it is of no concern, so we only check for TAITs.
49aad941 158 if let Some(OpaqueTyOrigin::TyAlias { .. }) =
9ffffee4 159 b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
5e7ed085 160 {
f2b60f7d
FG
161 self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
162 span: cause.span,
9c376795 163 hidden_type: self.tcx.def_span(b_def_id),
f2b60f7d
FG
164 opaque_type: self.tcx.def_span(def_id),
165 });
5e7ed085
FG
166 }
167 }
168 Some(self.register_hidden_type(
169 OpaqueTypeKey { def_id, substs },
170 cause.clone(),
171 param_env,
172 b,
173 origin,
2b03887a 174 a_is_expected,
5e7ed085
FG
175 ))
176 }
177 _ => None,
178 };
2b03887a 179 if let Some(res) = process(a, b, true) {
5e7ed085 180 res
2b03887a 181 } else if let Some(res) = process(b, a, false) {
5e7ed085
FG
182 res
183 } else {
2b03887a
FG
184 let (a, b) = self.resolve_vars_if_possible((a, b));
185 Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
5e7ed085 186 }
3c0e092e
XL
187 }
188
189 /// Given the map `opaque_types` containing the opaque
190 /// `impl Trait` types whose underlying, hidden types are being
191 /// inferred, this method adds constraints to the regions
192 /// appearing in those underlying hidden types to ensure that they
193 /// at least do not refer to random scopes within the current
194 /// function. These constraints are not (quite) sufficient to
195 /// guarantee that the regions are actually legal values; that
196 /// final condition is imposed after region inference is done.
197 ///
198 /// # The Problem
199 ///
200 /// Let's work through an example to explain how it works. Assume
201 /// the current function is as follows:
202 ///
203 /// ```text
204 /// fn foo<'a, 'b>(..) -> (impl Bar<'a>, impl Bar<'b>)
205 /// ```
206 ///
207 /// Here, we have two `impl Trait` types whose values are being
208 /// inferred (the `impl Bar<'a>` and the `impl
209 /// Bar<'b>`). Conceptually, this is sugar for a setup where we
210 /// define underlying opaque types (`Foo1`, `Foo2`) and then, in
211 /// the return type of `foo`, we *reference* those definitions:
212 ///
213 /// ```text
214 /// type Foo1<'x> = impl Bar<'x>;
215 /// type Foo2<'x> = impl Bar<'x>;
216 /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
217 /// // ^^^^ ^^
218 /// // | |
219 /// // | substs
220 /// // def_id
221 /// ```
222 ///
223 /// As indicating in the comments above, each of those references
224 /// is (in the compiler) basically a substitution (`substs`)
225 /// applied to the type of a suitable `def_id` (which identifies
226 /// `Foo1` or `Foo2`).
227 ///
228 /// Now, at this point in compilation, what we have done is to
229 /// replace each of the references (`Foo1<'a>`, `Foo2<'b>`) with
230 /// fresh inference variables C1 and C2. We wish to use the values
231 /// of these variables to infer the underlying types of `Foo1` and
232 /// `Foo2`. That is, this gives rise to higher-order (pattern) unification
233 /// constraints like:
234 ///
235 /// ```text
236 /// for<'a> (Foo1<'a> = C1)
237 /// for<'b> (Foo1<'b> = C2)
238 /// ```
239 ///
240 /// For these equation to be satisfiable, the types `C1` and `C2`
241 /// can only refer to a limited set of regions. For example, `C1`
242 /// can only refer to `'static` and `'a`, and `C2` can only refer
243 /// to `'static` and `'b`. The job of this function is to impose that
244 /// constraint.
245 ///
246 /// Up to this point, C1 and C2 are basically just random type
247 /// inference variables, and hence they may contain arbitrary
248 /// regions. In fact, it is fairly likely that they do! Consider
249 /// this possible definition of `foo`:
250 ///
251 /// ```text
252 /// fn foo<'a, 'b>(x: &'a i32, y: &'b i32) -> (impl Bar<'a>, impl Bar<'b>) {
253 /// (&*x, &*y)
254 /// }
255 /// ```
256 ///
257 /// Here, the values for the concrete types of the two impl
258 /// traits will include inference variables:
259 ///
260 /// ```text
261 /// &'0 i32
262 /// &'1 i32
263 /// ```
264 ///
265 /// Ordinarily, the subtyping rules would ensure that these are
266 /// sufficiently large. But since `impl Bar<'a>` isn't a specific
267 /// type per se, we don't get such constraints by default. This
268 /// is where this function comes into play. It adds extra
269 /// constraints to ensure that all the regions which appear in the
270 /// inferred type are regions that could validly appear.
271 ///
272 /// This is actually a bit of a tricky constraint in general. We
273 /// want to say that each variable (e.g., `'0`) can only take on
274 /// values that were supplied as arguments to the opaque type
275 /// (e.g., `'a` for `Foo1<'a>`) or `'static`, which is always in
276 /// scope. We don't have a constraint quite of this kind in the current
277 /// region checker.
278 ///
279 /// # The Solution
280 ///
281 /// We generally prefer to make `<=` constraints, since they
282 /// integrate best into the region solver. To do that, we find the
283 /// "minimum" of all the arguments that appear in the substs: that
284 /// is, some region which is less than all the others. In the case
285 /// of `Foo1<'a>`, that would be `'a` (it's the only choice, after
286 /// all). Then we apply that as a least bound to the variables
287 /// (e.g., `'a <= '0`).
288 ///
289 /// In some cases, there is no minimum. Consider this example:
290 ///
291 /// ```text
292 /// fn baz<'a, 'b>() -> impl Trait<'a, 'b> { ... }
293 /// ```
294 ///
295 /// Here we would report a more complex "in constraint", like `'r
296 /// in ['a, 'b, 'static]` (where `'r` is some region appearing in
297 /// the hidden type).
298 ///
299 /// # Constrain regions, not the hidden concrete type
300 ///
301 /// Note that generating constraints on each region `Rc` is *not*
5e7ed085 302 /// the same as generating an outlives constraint on `Tc` itself.
3c0e092e
XL
303 /// For example, if we had a function like this:
304 ///
04454e1e
FG
305 /// ```
306 /// # #![feature(type_alias_impl_trait)]
307 /// # fn main() {}
308 /// # trait Foo<'a> {}
309 /// # impl<'a, T> Foo<'a> for (&'a u32, T) {}
3c0e092e
XL
310 /// fn foo<'a, T>(x: &'a u32, y: T) -> impl Foo<'a> {
311 /// (x, y)
312 /// }
313 ///
314 /// // Equivalent to:
04454e1e 315 /// # mod dummy { use super::*;
3c0e092e 316 /// type FooReturn<'a, T> = impl Foo<'a>;
04454e1e
FG
317 /// fn foo<'a, T>(x: &'a u32, y: T) -> FooReturn<'a, T> {
318 /// (x, y)
319 /// }
320 /// # }
3c0e092e
XL
321 /// ```
322 ///
323 /// then the hidden type `Tc` would be `(&'0 u32, T)` (where `'0`
324 /// is an inference variable). If we generated a constraint that
325 /// `Tc: 'a`, then this would incorrectly require that `T: 'a` --
326 /// but this is not necessary, because the opaque type we
327 /// create will be allowed to reference `T`. So we only generate a
328 /// constraint that `'0: 'a`.
3c0e092e 329 #[instrument(level = "debug", skip(self))]
5e7ed085 330 pub fn register_member_constraints(
3c0e092e 331 &self,
5e7ed085 332 param_env: ty::ParamEnv<'tcx>,
3c0e092e 333 opaque_type_key: OpaqueTypeKey<'tcx>,
5e7ed085
FG
334 concrete_ty: Ty<'tcx>,
335 span: Span,
3c0e092e 336 ) {
5e7ed085 337 let concrete_ty = self.resolve_vars_if_possible(concrete_ty);
3c0e092e
XL
338 debug!(?concrete_ty);
339
487cf647
FG
340 let variances = self.tcx.variances_of(opaque_type_key.def_id);
341 debug!(?variances);
3c0e092e
XL
342
343 // For a case like `impl Foo<'a, 'b>`, we would generate a constraint
344 // `'r in ['a, 'b, 'static]` for each region `'r` that appears in the
345 // hidden type (i.e., it must be equal to `'a`, `'b`, or `'static`).
346 //
347 // `conflict1` and `conflict2` are the two region bounds that we
348 // detected which were unrelated. They are used for diagnostics.
349
350 // Create the set of choice regions: each region in the hidden
351 // type can be equal to any of the region parameters of the
352 // opaque type definition.
353 let choice_regions: Lrc<Vec<ty::Region<'tcx>>> = Lrc::new(
487cf647
FG
354 opaque_type_key
355 .substs
3c0e092e 356 .iter()
487cf647
FG
357 .enumerate()
358 .filter(|(i, _)| variances[*i] == ty::Variance::Invariant)
359 .filter_map(|(_, arg)| match arg.unpack() {
3c0e092e
XL
360 GenericArgKind::Lifetime(r) => Some(r),
361 GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
362 })
363 .chain(std::iter::once(self.tcx.lifetimes.re_static))
364 .collect(),
365 );
366
367 concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
487cf647 368 tcx: self.tcx,
064997fb 369 op: |r| self.member_constraint(opaque_type_key, span, concrete_ty, r, &choice_regions),
3c0e092e
XL
370 });
371 }
5099ac24 372
9ffffee4
FG
373 /// Returns the origin of the opaque type `def_id` if we're currently
374 /// in its defining scope.
f2b60f7d 375 #[instrument(skip(self), level = "trace", ret)]
9ffffee4 376 pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
5e7ed085 377 let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
064997fb
FG
378 let parent_def_id = match self.defining_use_anchor {
379 DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
380 DefiningAnchor::Bind(bind) => bind,
381 };
9ffffee4
FG
382
383 let origin = self.opaque_type_origin_unchecked(def_id);
384 let in_definition_scope = match origin {
5099ac24
FG
385 // Async `impl Trait`
386 hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
387 // Anonymous `impl Trait`
388 hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
389 // Named `type Foo = impl Bar;`
49aad941
FG
390 hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
391 if in_assoc_ty {
392 self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
393 } else {
394 may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
395 }
5099ac24
FG
396 }
397 };
9ffffee4 398 in_definition_scope.then_some(origin)
5099ac24 399 }
5e7ed085 400
9ffffee4
FG
401 /// Returns the origin of the opaque type `def_id` even if we are not in its
402 /// defining scope.
f2b60f7d 403 #[instrument(skip(self), level = "trace", ret)]
9ffffee4 404 fn opaque_type_origin_unchecked(&self, def_id: LocalDefId) -> OpaqueTyOrigin {
49aad941 405 self.tcx.hir().expect_item(def_id).expect_opaque_ty().origin
5e7ed085 406 }
3c0e092e
XL
407}
408
487cf647
FG
409/// Visitor that requires that (almost) all regions in the type visited outlive
410/// `least_region`. We cannot use `push_outlives_components` because regions in
411/// closure signatures are not included in their outlives components. We need to
412/// ensure all regions outlive the given bound so that we don't end up with,
413/// say, `ReVar` appearing in a return type and causing ICEs when other
414/// functions end up with region constraints involving regions from other
415/// functions.
416///
417/// We also cannot use `for_each_free_region` because for closures it includes
418/// the regions parameters from the enclosing item.
419///
420/// We ignore any type parameters because impl trait values are assumed to
421/// capture all the in-scope type parameters.
422pub struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
423 pub tcx: TyCtxt<'tcx>,
424 pub op: OP,
3c0e092e
XL
425}
426
9ffffee4 427impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP>
3c0e092e
XL
428where
429 OP: FnMut(ty::Region<'tcx>),
430{
9ffffee4 431 fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
3c0e092e
XL
432 &mut self,
433 t: &ty::Binder<'tcx, T>,
434 ) -> ControlFlow<Self::BreakTy> {
923072b8 435 t.super_visit_with(self);
9c376795 436 ControlFlow::Continue(())
3c0e092e
XL
437 }
438
439 fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
440 match *r {
441 // ignore bound regions, keep visiting
9c376795 442 ty::ReLateBound(_, _) => ControlFlow::Continue(()),
3c0e092e
XL
443 _ => {
444 (self.op)(r);
9c376795 445 ControlFlow::Continue(())
3c0e092e
XL
446 }
447 }
448 }
449
450 fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
451 // We're only interested in types involving regions
5099ac24 452 if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
9c376795 453 return ControlFlow::Continue(());
3c0e092e
XL
454 }
455
456 match ty.kind() {
457 ty::Closure(_, ref substs) => {
458 // Skip lifetime parameters of the enclosing item(s)
459
460 substs.as_closure().tupled_upvars_ty().visit_with(self);
461 substs.as_closure().sig_as_fn_ptr_ty().visit_with(self);
462 }
463
464 ty::Generator(_, ref substs, _) => {
465 // Skip lifetime parameters of the enclosing item(s)
466 // Also skip the witness type, because that has no free regions.
467
468 substs.as_generator().tupled_upvars_ty().visit_with(self);
469 substs.as_generator().return_ty().visit_with(self);
470 substs.as_generator().yield_ty().visit_with(self);
471 substs.as_generator().resume_ty().visit_with(self);
472 }
487cf647 473
9c376795
FG
474 ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref substs, .. }) => {
475 // Skip lifetime parameters that are not captures.
487cf647
FG
476 let variances = self.tcx.variances_of(*def_id);
477
478 for (v, s) in std::iter::zip(variances, substs.iter()) {
479 if *v != ty::Variance::Bivariant {
480 s.visit_with(self);
481 }
482 }
483 }
484
353b0b11 485 ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
9c376795
FG
486 // Skip lifetime parameters that are not captures.
487 let variances = self.tcx.variances_of(proj.def_id);
487cf647
FG
488
489 for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
490 if *v != ty::Variance::Bivariant {
491 s.visit_with(self);
492 }
493 }
494 }
495
3c0e092e
XL
496 _ => {
497 ty.super_visit_with(self);
498 }
499 }
500
9c376795 501 ControlFlow::Continue(())
3c0e092e
XL
502 }
503}
504
5e7ed085
FG
505pub enum UseKind {
506 DefiningUse,
507 OpaqueUse,
3c0e092e
XL
508}
509
5e7ed085
FG
510impl UseKind {
511 pub fn is_defining(self) -> bool {
512 match self {
513 UseKind::DefiningUse => true,
514 UseKind::OpaqueUse => false,
515 }
3c0e092e 516 }
5e7ed085 517}
3c0e092e 518
2b03887a 519impl<'tcx> InferCtxt<'tcx> {
3c0e092e 520 #[instrument(skip(self), level = "debug")]
2b03887a 521 fn register_hidden_type(
5e7ed085 522 &self,
3c0e092e 523 opaque_type_key: OpaqueTypeKey<'tcx>,
5e7ed085
FG
524 cause: ObligationCause<'tcx>,
525 param_env: ty::ParamEnv<'tcx>,
526 hidden_ty: Ty<'tcx>,
3c0e092e 527 origin: hir::OpaqueTyOrigin,
2b03887a 528 a_is_expected: bool,
5e7ed085 529 ) -> InferResult<'tcx, ()> {
3c0e092e
XL
530 // Ideally, we'd get the span where *this specific `ty` came
531 // from*, but right now we just use the span from the overall
532 // value being folded. In simple cases like `-> impl Foo`,
533 // these are the same span, but not in cases like `-> (impl
534 // Foo, impl Bar)`.
5e7ed085 535 let span = cause.span;
5e7ed085 536 let prev = self.inner.borrow_mut().opaque_types().register(
49aad941 537 opaque_type_key,
5e7ed085
FG
538 OpaqueHiddenType { ty: hidden_ty, span },
539 origin,
540 );
49aad941
FG
541 let mut obligations = if let Some(prev) = prev {
542 self.at(&cause, param_env)
353b0b11 543 .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
49aad941
FG
544 .obligations
545 } else {
546 Vec::new()
547 };
548
549 self.add_item_bounds_for_hidden_type(
550 opaque_type_key,
551 cause,
552 param_env,
553 hidden_ty,
554 &mut obligations,
555 );
556
557 Ok(InferOk { value: (), obligations })
558 }
3c0e092e 559
49aad941
FG
560 /// Registers an opaque's hidden type -- only should be used when the opaque
561 /// can be defined. For something more fallible -- checks the anchors, tries
562 /// to unify opaques in both dirs, etc. -- use `InferCtxt::handle_opaque_type`.
563 pub fn register_hidden_type_in_new_solver(
564 &self,
565 opaque_type_key: OpaqueTypeKey<'tcx>,
566 param_env: ty::ParamEnv<'tcx>,
567 hidden_ty: Ty<'tcx>,
568 ) -> InferResult<'tcx, ()> {
569 assert!(self.tcx.trait_solver_next());
570 let origin = self
571 .opaque_type_origin(opaque_type_key.def_id)
572 .expect("should be called for defining usages only");
573 self.register_hidden_type(
574 opaque_type_key,
575 ObligationCause::dummy(),
576 param_env,
577 hidden_ty,
578 origin,
579 true,
580 )
581 }
582
583 pub fn add_item_bounds_for_hidden_type(
584 &self,
585 OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
586 cause: ObligationCause<'tcx>,
587 param_env: ty::ParamEnv<'tcx>,
588 hidden_ty: Ty<'tcx>,
589 obligations: &mut Vec<PredicateObligation<'tcx>>,
590 ) {
591 let tcx = self.tcx;
592 let item_bounds = tcx.explicit_item_bounds(def_id);
3c0e092e 593
2b03887a 594 for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
5099ac24
FG
595 let predicate = predicate.fold_with(&mut BottomUpFolder {
596 tcx,
597 ty_op: |ty| match *ty.kind() {
5e7ed085
FG
598 // We can't normalize associated types from `rustc_infer`,
599 // but we can eagerly register inference variables for them.
2b03887a 600 // FIXME(RPITIT): Don't replace RPITITs with inference vars.
49aad941 601 // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
9c376795 602 ty::Alias(ty::Projection, projection_ty)
2b03887a 603 if !projection_ty.has_escaping_bound_vars()
49aad941
FG
604 && !tcx.is_impl_trait_in_trait(projection_ty.def_id)
605 && !tcx.trait_solver_next() =>
2b03887a 606 {
5e7ed085
FG
607 self.infer_projection(
608 param_env,
609 projection_ty,
610 cause.clone(),
5099ac24 611 0,
49aad941 612 obligations,
5099ac24
FG
613 )
614 }
5e7ed085
FG
615 // Replace all other mentions of the same opaque type with the hidden type,
616 // as the bounds must hold on the hidden type after all.
9c376795 617 ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. })
064997fb
FG
618 if def_id.to_def_id() == def_id2 && substs == substs2 =>
619 {
5e7ed085
FG
620 hidden_ty
621 }
2b03887a 622 // FIXME(RPITIT): This can go away when we move to associated types
49aad941 623 // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
9c376795
FG
624 ty::Alias(
625 ty::Projection,
626 ty::AliasTy { def_id: def_id2, substs: substs2, .. },
627 ) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty,
3c0e092e
XL
628 _ => ty,
629 },
630 lt_op: |lt| lt,
631 ct_op: |ct| ct,
632 });
3c0e092e 633
487cf647
FG
634 if let ty::PredicateKind::Clause(ty::Clause::Projection(projection)) =
635 predicate.kind().skip_binder()
636 {
5099ac24 637 if projection.term.references_error() {
49aad941
FG
638 // No point on adding any obligations since there's a type error involved.
639 obligations.clear();
640 return;
3c0e092e
XL
641 }
642 }
3c0e092e
XL
643 // Require that the predicate holds for the concrete type.
644 debug!(?predicate);
487cf647
FG
645 obligations.push(traits::Obligation::new(
646 self.tcx,
647 cause.clone(),
648 param_env,
649 predicate,
650 ));
3c0e092e 651 }
3c0e092e
XL
652 }
653}
654
655/// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `def_id`.
656///
657/// Example:
04454e1e
FG
658/// ```ignore UNSOLVED (is this a bug?)
659/// # #![feature(type_alias_impl_trait)]
3c0e092e
XL
660/// pub mod foo {
661/// pub mod bar {
04454e1e 662/// pub trait Bar { /* ... */ }
3c0e092e
XL
663/// pub type Baz = impl Bar;
664///
04454e1e
FG
665/// # impl Bar for () {}
666/// fn f1() -> Baz { /* ... */ }
3c0e092e 667/// }
04454e1e 668/// fn f2() -> bar::Baz { /* ... */ }
3c0e092e
XL
669/// }
670/// ```
671///
672/// Here, `def_id` is the `LocalDefId` of the defining use of the opaque type (e.g., `f1` or `f2`),
673/// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`.
674/// For the above example, this function returns `true` for `f1` and `false` for `f2`.
675fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool {
676 let mut hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
677
678 // Named opaque types can be defined by any siblings or children of siblings.
679 let scope = tcx.hir().get_defining_scope(opaque_hir_id);
680 // We walk up the node tree until we hit the root or the scope of the opaque type.
681 while hir_id != scope && hir_id != hir::CRATE_HIR_ID {
2b03887a 682 hir_id = tcx.hir().get_parent_item(hir_id).into();
3c0e092e
XL
683 }
684 // Syntactically, we are allowed to define the concrete type if:
685 let res = hir_id == scope;
686 trace!(
687 "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
688 tcx.hir().find(hir_id),
689 tcx.hir().get(opaque_hir_id),
690 res
691 );
692 res
693}