Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7f933de

Browse files
committed
Merge two duplicates of the same logic into a common function
1 parent 2bf63a5 commit 7f933de

File tree

3 files changed

+56
-76
lines changed

3 files changed

+56
-76
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::infer::{InferCtxt, InferOk};
22
use crate::traits;
33
use hir::def_id::{DefId, LocalDefId};
4-
use hir::OpaqueTyOrigin;
4+
use hir::{HirId, OpaqueTyOrigin};
55
use rustc_data_structures::sync::Lrc;
66
use rustc_data_structures::vec_map::VecMap;
77
use rustc_hir as hir;
@@ -21,6 +21,7 @@ mod table;
2121

2222
pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
2323

24+
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2425
use super::InferResult;
2526

2627
/// Information about the opaque types whose values we
@@ -38,6 +39,48 @@ pub struct OpaqueTypeDecl<'tcx> {
3839
}
3940

4041
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
42+
pub fn replace_opaque_types_with_inference_vars(
43+
&self,
44+
ty: Ty<'tcx>,
45+
body_id: HirId,
46+
span: Span,
47+
param_env: ty::ParamEnv<'tcx>,
48+
) -> InferOk<'tcx, Ty<'tcx>> {
49+
let mut obligations = vec![];
50+
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
51+
tcx: self.tcx,
52+
lt_op: |lt| lt,
53+
ct_op: |ct| ct,
54+
ty_op: |ty| match *ty.kind() {
55+
// Closures can't create hidden types for opaque types of their parent, as they
56+
// do not have all the outlives information available. Also `type_of` looks for
57+
// hidden types in the owner (so the closure's parent), so it would not find these
58+
// definitions.
59+
ty::Opaque(def_id, _substs)
60+
if matches!(
61+
self.opaque_type_origin(def_id, span),
62+
Some(OpaqueTyOrigin::FnReturn(..))
63+
) =>
64+
{
65+
let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
66+
let cause = ObligationCause::misc(span, body_id);
67+
let ty_var = self.next_ty_var(TypeVariableOrigin {
68+
kind: TypeVariableOriginKind::TypeInference,
69+
span: cause.span,
70+
});
71+
obligations.extend(
72+
self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
73+
.unwrap()
74+
.obligations,
75+
);
76+
ty_var
77+
}
78+
_ => ty,
79+
},
80+
});
81+
InferOk { value, obligations }
82+
}
83+
4184
pub fn handle_opaque_type(
4285
&self,
4386
a: Ty<'tcx>,

compiler/rustc_typeck/src/check/check.rs

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use super::compare_method::check_type_bounds;
33
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
44
use super::*;
55

6-
use hir::OpaqueTyOrigin;
76
use rustc_attr as attr;
87
use rustc_errors::{Applicability, ErrorGuaranteed};
98
use rustc_hir as hir;
@@ -13,9 +12,8 @@ use rustc_hir::lang_items::LangItem;
1312
use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
1413
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1514
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
16-
use rustc_infer::traits::ObligationCause;
1715
use rustc_middle::hir::nested_filter;
18-
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable};
16+
use rustc_middle::ty::fold::TypeFoldable;
1917
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
2018
use rustc_middle::ty::subst::GenericArgKind;
2119
use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -97,45 +95,13 @@ pub(super) fn check_fn<'a, 'tcx>(
9795

9896
let declared_ret_ty = fn_sig.output();
9997

100-
let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder {
101-
tcx: fcx.tcx,
102-
ty_op: |ty| match *ty.kind() {
103-
ty::Opaque(def_id, substs) => {
104-
let span = tcx.def_span(def_id);
105-
if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) =
106-
fcx.infcx.opaque_type_origin(def_id, span)
107-
{
108-
let hidden_ty = fcx.infcx.next_ty_var(TypeVariableOrigin {
109-
kind: TypeVariableOriginKind::MiscVariable,
110-
span: span,
111-
});
112-
113-
let cause = ObligationCause::misc(span, body.value.hir_id);
114-
match fcx.infcx.register_hidden_type(
115-
ty::OpaqueTypeKey { def_id, substs },
116-
cause.clone(),
117-
param_env,
118-
hidden_ty,
119-
origin,
120-
) {
121-
Ok(infer_ok) => {
122-
fcx.register_infer_ok_obligations(infer_ok);
123-
hidden_ty
124-
}
125-
Err(err) => {
126-
fcx.report_mismatched_types(&cause, ty, hidden_ty, err).emit();
127-
tcx.ty_error()
128-
}
129-
}
130-
} else {
131-
ty
132-
}
133-
}
134-
_ => ty,
135-
},
136-
lt_op: |lt| lt,
137-
ct_op: |ct| ct,
138-
});
98+
let ret_ty =
99+
fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
100+
declared_ret_ty,
101+
body.value.hir_id,
102+
DUMMY_SP,
103+
param_env,
104+
));
139105
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
140106
fcx.ret_type_span = Some(decl.output.span());
141107

compiler/rustc_typeck/src/check/closure.rs

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
44

55
use crate::astconv::AstConv;
66
use crate::rustc_middle::ty::subst::Subst;
7-
use hir::OpaqueTyOrigin;
87
use rustc_hir as hir;
98
use rustc_hir::def_id::DefId;
109
use rustc_hir::lang_items::LangItem;
1110
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1211
use rustc_infer::infer::LateBoundRegionConversionTime;
1312
use rustc_infer::infer::{InferOk, InferResult};
14-
use rustc_infer::traits::ObligationCause;
1513
use rustc_middle::ty::fold::TypeFoldable;
1614
use rustc_middle::ty::subst::InternalSubsts;
1715
use rustc_middle::ty::{self, Ty};
@@ -641,37 +639,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
641639
}
642640

643641
fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
644-
ty.fold_with(&mut ty::fold::BottomUpFolder {
645-
tcx: self.infcx.tcx,
646-
lt_op: |lt| lt,
647-
ct_op: |ct| ct,
648-
ty_op: |ty| match *ty.kind() {
649-
// Closures can't create hidden types for opaque types of their parent, as they
650-
// do not have all the outlives information available. Also `type_of` looks for
651-
// hidden types in the owner (so the closure's parent), so it would not find these
652-
// definitions.
653-
ty::Opaque(def_id, _substs)
654-
if matches!(
655-
self.infcx.opaque_type_origin(def_id, DUMMY_SP),
656-
Some(OpaqueTyOrigin::FnReturn(..))
657-
) =>
658-
{
659-
let ty_var = self.next_ty_var(TypeVariableOrigin {
660-
kind: TypeVariableOriginKind::TypeInference,
661-
span,
662-
});
663-
let cause = ObligationCause::misc(span, body_id);
664-
self.register_predicates(
665-
self.infcx
666-
.handle_opaque_type(ty, ty_var, true, &cause, self.param_env)
667-
.unwrap()
668-
.obligations,
669-
);
670-
ty_var
671-
}
672-
_ => ty,
673-
},
674-
})
642+
let InferOk { value, obligations } =
643+
self.replace_opaque_types_with_inference_vars(ty, body_id, span, self.param_env);
644+
self.register_predicates(obligations);
645+
value
675646
}
676647

677648
/// Invoked when we are translating the generator that results

0 commit comments

Comments
 (0)