Auto merge of #121796 - oli-obk:eager_opaque_checks3, r=lcnr · rust-lang/rust@4ccbb7d (original) (raw)
`@@ -150,9 +150,6 @@ impl<'tcx> InferCtxt<'tcx> {
`
150
150
`}
`
151
151
`}
`
152
152
`DefiningAnchor::Bubble => {}
`
153
``
`-
DefiningAnchor::Error => {
`
154
``
`-
return None;
`
155
``
`-
}
`
156
153
`}
`
157
154
`if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
`
158
155
`// We could accept this, but there are various ways to handle this situation, and we don't
`
`@@ -378,28 +375,14 @@ impl<'tcx> InferCtxt<'tcx> {
`
378
375
`/// in its defining scope.
`
379
376
`#[instrument(skip(self), level = "trace", ret)]
`
380
377
`pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option {
`
381
``
`-
let opaque_hir_id = self.tcx.local_def_id_to_hir_id(def_id);
`
382
``
`-
let parent_def_id = match self.defining_use_anchor {
`
383
``
`-
DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
`
``
378
`+
let defined_opaque_types = match self.defining_use_anchor {
`
``
379
`+
DefiningAnchor::Bubble => return None,
`
384
380
`DefiningAnchor::Bind(bind) => bind,
`
385
381
`};
`
386
382
``
387
383
`let origin = self.tcx.opaque_type_origin(def_id);
`
388
``
`-
let in_definition_scope = match origin {
`
389
``
`` -
// Async impl Trait
``
390
``
`-
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
`
391
``
`` -
// Anonymous impl Trait
``
392
``
`-
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
`
393
``
`` -
// Named type Foo = impl Bar;
``
394
``
`-
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
`
395
``
`-
if in_assoc_ty {
`
396
``
`-
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
`
397
``
`-
} else {
`
398
``
`-
may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
`
399
``
`-
}
`
400
``
`-
}
`
401
``
`-
};
`
402
``
`-
in_definition_scope.then_some(origin)
`
``
384
+
``
385
`+
defined_opaque_types.contains(&def_id).then_some(origin)
`
403
386
`}
`
404
387
`}
`
405
388
``
`@@ -656,43 +639,3 @@ impl<'tcx> InferCtxt<'tcx> {
`
656
639
`}
`
657
640
`}
`
658
641
`}
`
659
``
-
660
``
`` -
/// Returns true
if opaque_hir_id
is a sibling or a child of a sibling of def_id
.
``
661
``
`-
///
`
662
``
`-
/// Example:
`
663
``
/// ```ignore UNSOLVED (is this a bug?)
664
``
`-
/// # #![feature(type_alias_impl_trait)]
`
665
``
`-
/// pub mod foo {
`
666
``
`-
/// pub mod bar {
`
667
``
`-
/// pub trait Bar { /* ... */ }
`
668
``
`-
/// pub type Baz = impl Bar;
`
669
``
`-
///
`
670
``
`-
/// # impl Bar for () {}
`
671
``
`-
/// fn f1() -> Baz { /* ... */ }
`
672
``
`-
/// }
`
673
``
`-
/// fn f2() -> bar::Baz { /* ... */ }
`
674
``
`-
/// }
`
675
``
/// ```
676
``
`-
///
`
677
``
`` -
/// Here, def_id
is the LocalDefId
of the defining use of the opaque type (e.g., f1
or f2
),
``
678
``
`` -
/// and opaque_hir_id
is the HirId
of the definition of the opaque type Baz
.
``
679
``
`` -
/// For the above example, this function returns true
for f1
and false
for f2
.
``
680
``
`-
fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool {
`
681
``
`-
let mut hir_id = tcx.local_def_id_to_hir_id(def_id);
`
682
``
-
683
``
`-
// Named opaque types can be defined by any siblings or children of siblings.
`
684
``
`-
let scope = tcx.hir().get_defining_scope(opaque_hir_id);
`
685
``
`-
// We walk up the node tree until we hit the root or the scope of the opaque type.
`
686
``
`-
while hir_id != scope && hir_id != hir::CRATE_HIR_ID {
`
687
``
`-
hir_id = tcx.hir().get_parent_item(hir_id).into();
`
688
``
`-
}
`
689
``
`-
// Syntactically, we are allowed to define the concrete type if:
`
690
``
`-
let res = hir_id == scope;
`
691
``
`-
trace!(
`
692
``
`-
"may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
`
693
``
`-
tcx.hir_node(hir_id),
`
694
``
`-
tcx.hir_node(opaque_hir_id),
`
695
``
`-
res
`
696
``
`-
);
`
697
``
`-
res
`
698
``
`-
}
`