summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/region_infer
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_borrowck/src/region_infer
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/region_infer')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs8
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs149
2 files changed, 87 insertions, 70 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 50b246b14..e45d3a2c8 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1139,7 +1139,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
_ => arg.fold_with(self),
}
});
- tcx.mk_opaque(def_id, tcx.mk_substs_from_iter(substs))
+ Ty::new_opaque(tcx, def_id, tcx.mk_substs_from_iter(substs))
}
}
@@ -1158,7 +1158,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.universal_regions_outlived_by(r_scc)
.filter(|&u_r| !self.universal_regions.is_local_free_region(u_r))
.find(|&u_r| self.eval_equal(u_r, r_vid))
- .map(|u_r| tcx.mk_re_var(u_r))
+ .map(|u_r| ty::Region::new_var(tcx, u_r))
// In the case of a failure, use `ReErased`. We will eventually
// return `None` in this case.
.unwrap_or(tcx.lifetimes.re_erased)
@@ -1355,7 +1355,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let vid = self.to_region_vid(r);
let scc = self.constraint_sccs.scc(vid);
let repr = self.scc_representatives[scc];
- tcx.mk_re_var(repr)
+ ty::Region::new_var(tcx, repr)
})
}
@@ -1779,7 +1779,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
// If not, report an error.
- let member_region = infcx.tcx.mk_re_var(member_region_vid);
+ let member_region = ty::Region::new_var(infcx.tcx, member_region_vid);
errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
span: m_c.definition_span,
hidden_ty: m_c.hidden_ty,
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 7fc89e89a..1a227f2d1 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -61,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'tcx>,
- opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
+ opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
@@ -72,7 +72,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.collect();
debug!(?member_constraints);
- for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
+ for (opaque_type_key, concrete_type) in opaque_ty_decls {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);
@@ -92,7 +92,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
None => {
subst_regions.push(vid);
- infcx.tcx.mk_re_error_with_message(
+ ty::Region::new_error_with_message(
+ infcx.tcx,
concrete_type.span,
"opaque type with non-universal region substs",
)
@@ -142,7 +143,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let ty = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
- origin,
);
// Sometimes two opaque types are the same only after we remap the generic parameters
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
@@ -158,7 +158,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
)
.emit()
});
- prev.ty = infcx.tcx.ty_error(guar);
+ prev.ty = Ty::new_error(infcx.tcx, guar);
}
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
@@ -214,7 +214,6 @@ pub trait InferCtxtExt<'tcx> {
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: OpaqueHiddenType<'tcx>,
- origin: OpaqueTyOrigin,
) -> Ty<'tcx>;
}
@@ -247,99 +246,117 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: OpaqueHiddenType<'tcx>,
- origin: OpaqueTyOrigin,
) -> Ty<'tcx> {
if let Some(e) = self.tainted_by_errors() {
- return self.tcx.ty_error(e);
+ return Ty::new_error(self.tcx, e);
+ }
+
+ if let Err(guar) =
+ check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span)
+ {
+ return Ty::new_error(self.tcx, guar);
}
let definition_ty = instantiated_ty
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
.ty;
- if let Err(guar) = check_opaque_type_parameter_valid(
+ // `definition_ty` does not live in of the current inference context,
+ // so lets make sure that we don't accidentally misuse our current `infcx`.
+ match check_opaque_type_well_formed(
self.tcx,
- opaque_type_key,
- origin,
+ self.next_trait_solver(),
+ opaque_type_key.def_id,
instantiated_ty.span,
+ definition_ty,
) {
- return self.tcx.ty_error(guar);
+ Ok(hidden_ty) => hidden_ty,
+ Err(guar) => Ty::new_error(self.tcx, guar),
}
+ }
+}
- // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
- // on stable and we'd break that.
- let OpaqueTyOrigin::TyAlias { .. } = origin else {
- return definition_ty;
- };
- let def_id = opaque_type_key.def_id;
- // This logic duplicates most of `check_opaque_meets_bounds`.
- // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
- let param_env = self.tcx.param_env(def_id);
- // HACK This bubble is required for this tests to pass:
- // nested-return-type2-tait2.rs
- // nested-return-type2-tait3.rs
- let infcx =
- self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
- let ocx = ObligationCtxt::new(&infcx);
- // Require the hidden type to be well-formed with only the generics of the opaque type.
- // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
- // hidden type is well formed even without those bounds.
- let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()));
-
- let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id);
+/// This logic duplicates most of `check_opaque_meets_bounds`.
+/// FIXME(oli-obk): Also do region checks here and then consider removing
+/// `check_opaque_meets_bounds` entirely.
+fn check_opaque_type_well_formed<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ next_trait_solver: bool,
+ def_id: LocalDefId,
+ definition_span: Span,
+ definition_ty: Ty<'tcx>,
+) -> Result<Ty<'tcx>, ErrorGuaranteed> {
+ // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
+ // on stable and we'd break that.
+ let opaque_ty_hir = tcx.hir().expect_item(def_id);
+ let OpaqueTyOrigin::TyAlias { .. } = opaque_ty_hir.expect_opaque_ty().origin else {
+ return Ok(definition_ty);
+ };
+ let param_env = tcx.param_env(def_id);
+ // HACK This bubble is required for this tests to pass:
+ // nested-return-type2-tait2.rs
+ // nested-return-type2-tait3.rs
+ // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
+ // and prepopulate this `InferCtxt` with known opaque values, rather than
+ // using the `Bind` anchor here. For now it's fine.
+ let infcx = tcx
+ .infer_ctxt()
+ .with_next_trait_solver(next_trait_solver)
+ .with_opaque_type_inference(if next_trait_solver {
+ DefiningAnchor::Bind(def_id)
+ } else {
+ DefiningAnchor::Bubble
+ })
+ .build();
+ let ocx = ObligationCtxt::new(&infcx);
+ let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
- // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
- // the bounds that the function supplies.
- let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
- if let Err(err) = ocx.eq(
- &ObligationCause::misc(instantiated_ty.span, def_id),
- param_env,
- opaque_ty,
- definition_ty,
- ) {
+ // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
+ // the bounds that the function supplies.
+ let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_substs);
+ ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
+ .map_err(|err| {
infcx
.err_ctxt()
.report_mismatched_types(
- &ObligationCause::misc(instantiated_ty.span, def_id),
+ &ObligationCause::misc(definition_span, def_id),
opaque_ty,
definition_ty,
err,
)
- .emit();
- }
+ .emit()
+ })?;
- ocx.register_obligation(Obligation::misc(
- infcx.tcx,
- instantiated_ty.span,
- def_id,
- param_env,
- predicate,
- ));
+ // Require the hidden type to be well-formed with only the generics of the opaque type.
+ // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
+ // hidden type is well formed even without those bounds.
+ let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
+ definition_ty.into(),
+ )));
+ ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate));
- // Check that all obligations are satisfied by the implementation's
- // version.
- let errors = ocx.select_all_or_error();
+ // Check that all obligations are satisfied by the implementation's
+ // version.
+ let errors = ocx.select_all_or_error();
- // This is still required for many(half of the tests in ui/type-alias-impl-trait)
- // tests to pass
- let _ = infcx.take_opaque_types();
+ // This is still required for many(half of the tests in ui/type-alias-impl-trait)
+ // tests to pass
+ let _ = infcx.take_opaque_types();
- if errors.is_empty() {
- definition_ty
- } else {
- let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
- self.tcx.ty_error(reported)
- }
+ if errors.is_empty() {
+ Ok(definition_ty)
+ } else {
+ Err(infcx.err_ctxt().report_fulfillment_errors(&errors))
}
}
fn check_opaque_type_parameter_valid(
tcx: TyCtxt<'_>,
opaque_type_key: OpaqueTypeKey<'_>,
- origin: OpaqueTyOrigin,
span: Span,
) -> Result<(), ErrorGuaranteed> {
- match origin {
+ let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
+ match opaque_ty_hir.expect_opaque_ty().origin {
// No need to check return position impl trait (RPIT)
// because for type and const parameters they are correct
// by construction: we convert