summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check
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_hir_analysis/src/check
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_hir_analysis/src/check')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs53
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs272
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs183
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs278
7 files changed, 499 insertions, 355 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 3b2c052e8..120545c8e 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -177,7 +177,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
// Generic statics are rejected, but we still reach this case.
Err(e) => {
- tcx.sess.delay_span_bug(span, e.to_string());
+ tcx.sess.delay_span_bug(span, format!("{e:?}"));
return;
}
};
@@ -224,7 +224,8 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() {
return;
}
- check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin);
+
+ let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin);
}
/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
@@ -299,7 +300,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
}
}
- if let ItemKind::OpaqueTy(hir::OpaqueTy {
+ if let ItemKind::OpaqueTy(&hir::OpaqueTy {
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
in_trait,
..
@@ -307,9 +308,9 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
{
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_identity_ty = if in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
- tcx.mk_projection(def_id.to_def_id(), substs)
+ Ty::new_projection(tcx, def_id.to_def_id(), substs)
} else {
- tcx.mk_opaque(def_id.to_def_id(), substs)
+ Ty::new_opaque(tcx, def_id.to_def_id(), substs)
};
let mut visitor = ProhibitOpaqueVisitor {
opaque_identity_ty,
@@ -395,7 +396,7 @@ fn check_opaque_meets_bounds<'tcx>(
def_id: LocalDefId,
span: Span,
origin: &hir::OpaqueTyOrigin,
-) {
+) -> Result<(), ErrorGuaranteed> {
let defining_use_anchor = match *origin {
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
@@ -409,7 +410,7 @@ fn check_opaque_meets_bounds<'tcx>(
let ocx = ObligationCtxt::new(&infcx);
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
- let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
+ let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
// `ReErased` regions appear in the "parent_substs" of closures/generators.
// We're ignoring them here and replacing them with fresh region variables.
@@ -429,24 +430,26 @@ fn check_opaque_meets_bounds<'tcx>(
Ok(()) => {}
Err(ty_err) => {
let ty_err = ty_err.to_string(tcx);
- tcx.sess.delay_span_bug(
+ return Err(tcx.sess.delay_span_bug(
span,
format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
- );
+ ));
}
}
// Additionally 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(hidden_ty.into()));
+ let predicate =
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate));
// Check that all obligations are satisfied by the implementation's
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
- infcx.err_ctxt().report_fulfillment_errors(&errors);
+ let guar = infcx.err_ctxt().report_fulfillment_errors(&errors);
+ return Err(guar);
}
match origin {
// Checked when type checking the function containing them.
@@ -460,14 +463,15 @@ fn check_opaque_meets_bounds<'tcx>(
if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {}
// Can have different predicates to their defining use
hir::OpaqueTyOrigin::TyAlias { .. } => {
- let wf_tys = ocx.assumed_wf_types(param_env, span, def_id);
+ let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, def_id)?;
let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
- let _ = ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env);
+ ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
}
}
// Clean up after ourselves
let _ = infcx.take_opaque_types();
+ Ok(())
}
fn is_enum_of_nonnullable_ptr<'tcx>(
@@ -562,8 +566,8 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
check_union(tcx, id.owner_id.def_id);
}
DefKind::OpaqueTy => {
- let opaque = tcx.hir().expect_item(id.owner_id.def_id).expect_opaque_ty();
- if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
+ let origin = tcx.opaque_type_origin(id.owner_id.def_id);
+ if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
@@ -704,7 +708,7 @@ pub(super) fn check_specialization_validity<'tcx>(
// grandparent. In that case, if parent is a `default impl`, inherited items use the
// "defaultness" from the grandparent, else they are final.
None => {
- if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
+ if tcx.defaultness(parent_impl.def_id()).is_default() {
None
} else {
Some(Err(parent_impl.def_id()))
@@ -718,7 +722,14 @@ pub(super) fn check_specialization_validity<'tcx>(
let result = opt_result.unwrap_or(Ok(()));
if let Err(parent_impl) = result {
- report_forbidden_specialization(tcx, impl_item, parent_impl);
+ if !tcx.is_impl_trait_in_trait(impl_item) {
+ report_forbidden_specialization(tcx, impl_item, parent_impl);
+ } else {
+ tcx.sess.delay_span_bug(
+ DUMMY_SP,
+ format!("parent item: {:?} not marked as default", parent_impl),
+ );
+ }
}
}
@@ -803,7 +814,7 @@ fn check_impl_items_against_trait<'tcx>(
.as_ref()
.is_some_and(|node_item| node_item.item.defaultness(tcx).has_value());
- if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
+ if !is_implemented && tcx.defaultness(impl_id).is_final() {
missing_items.push(tcx.associated_item(trait_item_id));
}
@@ -1481,7 +1492,9 @@ fn opaque_type_cycle_error(
}
for closure_def_id in visitor.closures {
- let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
+ let Some(closure_local_did) = closure_def_id.as_local() else {
+ continue;
+ };
let typeck_results = tcx.typeck(closure_local_did);
let mut label_match = |ty: Ty<'_>, span| {
@@ -1549,7 +1562,7 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
.build();
- let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
+ let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
for (predicate, cause) in generator_interior_predicates {
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 8bf1e0e84..22e576e34 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -19,12 +19,13 @@ use rustc_middle::ty::{
self, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
};
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal,
};
+use std::borrow::Cow;
use std::iter;
/// Checks that a method from an impl conforms to the signature of
@@ -44,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>(
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
let _: Result<_, ErrorGuaranteed> = try {
- compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?;
- compare_number_of_generics(tcx, impl_m, trait_m, false)?;
- compare_generic_param_kinds(tcx, impl_m, trait_m, false)?;
- compare_number_of_method_arguments(tcx, impl_m, trait_m)?;
- compare_synthetic_generics(tcx, impl_m, trait_m)?;
- compare_asyncness(tcx, impl_m, trait_m)?;
+ check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
compare_method_predicate_entailment(
tcx,
impl_m,
@@ -60,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>(
};
}
+/// Checks a bunch of different properties of the impl/trait methods for
+/// compatibility, such as asyncness, number of argument, self receiver kind,
+/// and number of early- and late-bound generics.
+fn check_method_is_structurally_compatible<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ impl_m: ty::AssocItem,
+ trait_m: ty::AssocItem,
+ impl_trait_ref: ty::TraitRef<'tcx>,
+ delay: bool,
+) -> Result<(), ErrorGuaranteed> {
+ compare_self_type(tcx, impl_m, trait_m, impl_trait_ref, delay)?;
+ compare_number_of_generics(tcx, impl_m, trait_m, delay)?;
+ compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
+ compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
+ compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
+ compare_asyncness(tcx, impl_m, trait_m, delay)?;
+ check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
+ Ok(())
+}
+
/// This function is best explained by example. Consider a trait with it's implementation:
///
/// ```rust
@@ -176,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>(
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
- // Check region bounds.
- check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;
-
// Create obligations for each predicate declared by the impl
// definition in the context of the trait's parameter
// environment. We can't just use `impl_env.caller_bounds`,
@@ -207,7 +220,7 @@ fn compare_method_predicate_entailment<'tcx>(
// the new hybrid bounds we computed.
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
let param_env = ty::ParamEnv::new(
- tcx.mk_predicates(&hybrid_preds.predicates),
+ tcx.mk_clauses(&hybrid_preds.predicates),
Reveal::UserFacing,
hir::Constness::NotConst,
);
@@ -258,7 +271,7 @@ fn compare_method_predicate_entailment<'tcx>(
infer::HigherRankedType,
tcx.fn_sig(impl_m.def_id).subst_identity(),
);
- let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig));
+ let unnormalized_impl_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig));
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id);
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
@@ -275,7 +288,7 @@ fn compare_method_predicate_entailment<'tcx>(
// We also have to add the normalized trait signature
// as we don't normalize during implied bounds computation.
wf_tys.extend(trait_sig.inputs_and_output.iter());
- let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
+ let trait_fty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(trait_sig));
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
@@ -301,14 +314,16 @@ fn compare_method_predicate_entailment<'tcx>(
return Err(emitted);
}
- if check_implied_wf == CheckImpliedWfMode::Check {
+ if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
// We need to check that the impl's args are well-formed given
// the hybrid param-env (impl + trait method where-clauses).
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
ObligationCause::dummy(),
param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_impl_fty.into())),
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
+ unnormalized_impl_fty.into(),
+ ))),
));
}
@@ -471,7 +486,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
if let ty::ReFree(fr) = *r {
- self.tcx.mk_re_free(
+ ty::Region::new_free(
+ self.tcx,
fr.scope,
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
)
@@ -532,6 +548,7 @@ fn compare_asyncness<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
+ delay: bool,
) -> Result<(), ErrorGuaranteed> {
if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async {
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
@@ -542,11 +559,14 @@ fn compare_asyncness<'tcx>(
// We don't know if it's ok, but at least it's already an error.
}
_ => {
- return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync {
- span: tcx.def_span(impl_m.def_id),
- method_name: trait_m.name,
- trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
- }));
+ return Err(tcx
+ .sess
+ .create_err(crate::errors::AsyncTraitImplShouldBeAsync {
+ span: tcx.def_span(impl_m.def_id),
+ method_name: trait_m.name,
+ trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
+ })
+ .emit_unless(delay));
}
};
}
@@ -600,9 +620,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// First, check a few of the same things as `compare_impl_method`,
// just so we don't ICE during substitution later.
- compare_number_of_generics(tcx, impl_m, trait_m, true)?;
- compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
- check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
+ check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
let trait_to_impl_substs = impl_trait_ref.substs;
@@ -633,11 +651,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_sig = ocx.normalize(
&norm_cause,
param_env,
- infcx.instantiate_binder_with_fresh_vars(
- return_span,
- infer::HigherRankedType,
- tcx.fn_sig(impl_m.def_id).subst_identity(),
- ),
+ tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(impl_m.def_id).subst_identity()),
);
impl_sig.error_reported()?;
let impl_return_ty = impl_sig.output();
@@ -647,18 +661,21 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// them with inference variables.
// We will use these inference variables to collect the hidden types of RPITITs.
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_def_id);
- let unnormalized_trait_sig = tcx
- .liberate_late_bound_regions(
- impl_m.def_id,
+ let unnormalized_trait_sig = infcx
+ .instantiate_binder_with_fresh_vars(
+ return_span,
+ infer::HigherRankedType,
tcx.fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs),
)
.fold_with(&mut collector);
- debug_assert_ne!(
- collector.types.len(),
- 0,
- "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
- );
+ if !unnormalized_trait_sig.output().references_error() {
+ debug_assert_ne!(
+ collector.types.len(),
+ 0,
+ "expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
+ );
+ }
let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
trait_sig.error_reported()?;
@@ -684,7 +701,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
&cause,
hir.get_if_local(impl_m.def_id)
.and_then(|node| node.fn_decl())
- .map(|decl| (decl.output.span(), "return type in trait".to_owned())),
+ .map(|decl| (decl.output.span(), Cow::from("return type in trait"))),
Some(infer::ValuePairs::Terms(ExpectedFound {
expected: trait_return_ty.into(),
found: impl_return_ty.into(),
@@ -742,15 +759,17 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let mut collected_tys = FxHashMap::default();
for (def_id, (ty, substs)) in collected_types {
- match infcx.fully_resolve(ty) {
- Ok(ty) => {
+ match infcx.fully_resolve((ty, substs)) {
+ Ok((ty, substs)) => {
// `ty` contains free regions that we created earlier while liberating the
// trait fn signature. However, projection normalization expects `ty` to
// contains `def_id`'s early-bound regions.
let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
debug!(?id_substs, ?substs);
- let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> =
- std::iter::zip(substs, id_substs).collect();
+ let map: FxHashMap<_, _> = std::iter::zip(substs, id_substs)
+ .skip(tcx.generics_of(trait_m.def_id).count())
+ .filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
+ .collect();
debug!(?map);
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
@@ -775,33 +794,27 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// same generics.
let num_trait_substs = trait_to_impl_substs.len();
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
- let ty = tcx.fold_regions(ty, |region, _| {
- match region.kind() {
- // Remap all free regions, which correspond to late-bound regions in the function.
- ty::ReFree(_) => {}
- // Remap early-bound regions as long as they don't come from the `impl` itself.
- ty::ReEarlyBound(ebr) if tcx.parent(ebr.def_id) != impl_m.container_id(tcx) => {}
- _ => return region,
- }
- let Some(ty::ReEarlyBound(e)) = map.get(&region.into()).map(|r| r.expect_region().kind())
- else {
- return tcx.mk_re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound")
- };
- tcx.mk_re_early_bound(ty::EarlyBoundRegion {
- def_id: e.def_id,
- name: e.name,
- index: (e.index as usize - num_trait_substs + num_impl_substs) as u32,
- })
- });
- debug!(%ty);
- collected_tys.insert(def_id, ty::EarlyBinder(ty));
+ let ty = match ty.try_fold_with(&mut RemapHiddenTyRegions {
+ tcx,
+ map,
+ num_trait_substs,
+ num_impl_substs,
+ def_id,
+ impl_def_id: impl_m.container_id(tcx),
+ ty,
+ return_span,
+ }) {
+ Ok(ty) => ty,
+ Err(guar) => Ty::new_error(tcx, guar),
+ };
+ collected_tys.insert(def_id, ty::EarlyBinder::bind(ty));
}
Err(err) => {
let reported = tcx.sess.delay_span_bug(
return_span,
format!("could not fully resolve: {ty} => {err:?}"),
);
- collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported)));
+ collected_tys.insert(def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, reported)));
}
}
}
@@ -877,6 +890,97 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
}
}
+struct RemapHiddenTyRegions<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
+ num_trait_substs: usize,
+ num_impl_substs: usize,
+ def_id: DefId,
+ impl_def_id: DefId,
+ ty: Ty<'tcx>,
+ return_span: Span,
+}
+
+impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
+ type Error = ErrorGuaranteed;
+
+ fn interner(&self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+
+ fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
+ if let ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = *t.kind() {
+ let mut mapped_substs = Vec::with_capacity(substs.len());
+ for (arg, v) in std::iter::zip(substs, self.tcx.variances_of(def_id)) {
+ mapped_substs.push(match (arg.unpack(), v) {
+ // Skip uncaptured opaque substs
+ (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
+ _ => arg.try_fold_with(self)?,
+ });
+ }
+ Ok(Ty::new_opaque(self.tcx, def_id, self.tcx.mk_substs(&mapped_substs)))
+ } else {
+ t.try_super_fold_with(self)
+ }
+ }
+
+ fn try_fold_region(
+ &mut self,
+ region: ty::Region<'tcx>,
+ ) -> Result<ty::Region<'tcx>, Self::Error> {
+ match region.kind() {
+ // Remap all free regions, which correspond to late-bound regions in the function.
+ ty::ReFree(_) => {}
+ // Remap early-bound regions as long as they don't come from the `impl` itself,
+ // in which case we don't really need to renumber them.
+ ty::ReEarlyBound(ebr) if self.tcx.parent(ebr.def_id) != self.impl_def_id => {}
+ _ => return Ok(region),
+ }
+
+ let e = if let Some(region) = self.map.get(&region) {
+ if let ty::ReEarlyBound(e) = region.kind() { e } else { bug!() }
+ } else {
+ let guar = match region.kind() {
+ ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. })
+ | ty::ReFree(ty::FreeRegion {
+ bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
+ ..
+ }) => {
+ let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
+ self.tcx.def_span(opaque_ty.def_id)
+ } else {
+ self.return_span
+ };
+ self.tcx
+ .sess
+ .struct_span_err(
+ return_span,
+ "return type captures more lifetimes than trait definition",
+ )
+ .span_label(self.tcx.def_span(def_id), "this lifetime was captured")
+ .span_note(
+ self.tcx.def_span(self.def_id),
+ "hidden type must only reference lifetimes captured by this impl trait",
+ )
+ .note(format!("hidden type inferred to be `{}`", self.ty))
+ .emit()
+ }
+ _ => self.tcx.sess.delay_span_bug(DUMMY_SP, "should've been able to remap region"),
+ };
+ return Err(guar);
+ };
+
+ Ok(ty::Region::new_early_bound(
+ self.tcx,
+ ty::EarlyBoundRegion {
+ def_id: e.def_id,
+ name: e.name,
+ index: (e.index as usize - self.num_trait_substs + self.num_impl_substs) as u32,
+ },
+ ))
+ }
+}
+
fn report_trait_method_mismatch<'tcx>(
infcx: &InferCtxt<'tcx>,
mut cause: ObligationCause<'tcx>,
@@ -901,7 +1005,7 @@ fn report_trait_method_mismatch<'tcx>(
if trait_m.fn_has_self_parameter =>
{
let ty = trait_sig.inputs()[0];
- let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
+ let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
ExplicitSelf::ByValue => "self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
@@ -963,7 +1067,7 @@ fn report_trait_method_mismatch<'tcx>(
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
- trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
+ trait_err_span.map(|sp| (sp, Cow::from("type in trait"))),
Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })),
terr,
false,
@@ -1095,6 +1199,7 @@ fn compare_self_type<'tcx>(
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
+ delay: bool,
) -> Result<(), ErrorGuaranteed> {
// Try to give more informative error messages about self typing
// mismatches. Note that any mismatch will also be detected
@@ -1143,7 +1248,7 @@ fn compare_self_type<'tcx>(
} else {
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
}
- return Err(err.emit());
+ return Err(err.emit_unless(delay));
}
(true, false) => {
@@ -1164,7 +1269,7 @@ fn compare_self_type<'tcx>(
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
}
- return Err(err.emit());
+ return Err(err.emit_unless(delay));
}
}
@@ -1214,7 +1319,7 @@ fn compare_number_of_generics<'tcx>(
// has mismatched type or const generic arguments, then the method that it's
// inheriting the generics from will also have mismatched arguments, and
// we'll report an error for that instead. Delay a bug for safety, though.
- if tcx.opt_rpitit_info(trait_.def_id).is_some() {
+ if trait_.opt_rpitit_info.is_some() {
return Err(tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"errors comparing numbers of generics of trait/impl functions were not emitted",
@@ -1350,6 +1455,7 @@ fn compare_number_of_method_arguments<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
+ delay: bool,
) -> Result<(), ErrorGuaranteed> {
let impl_m_fty = tcx.fn_sig(impl_m.def_id);
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
@@ -1420,7 +1526,7 @@ fn compare_number_of_method_arguments<'tcx>(
),
);
- return Err(err.emit());
+ return Err(err.emit_unless(delay));
}
Ok(())
@@ -1430,6 +1536,7 @@ fn compare_synthetic_generics<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
+ delay: bool,
) -> Result<(), ErrorGuaranteed> {
// FIXME(chrisvittal) Clean up this function, list of FIXME items:
// 1. Better messages for the span labels
@@ -1549,7 +1656,7 @@ fn compare_synthetic_generics<'tcx>(
}
_ => unreachable!(),
}
- error_found = Some(err.emit());
+ error_found = Some(err.emit_unless(delay));
}
}
if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
@@ -1731,7 +1838,7 @@ pub(super) fn compare_impl_const_raw(
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
- trait_c_span.map(|span| (span, "type in trait".to_owned())),
+ trait_c_span.map(|span| (span, Cow::from("type in trait"))),
Some(infer::ValuePairs::Terms(ExpectedFound {
expected: trait_ty.into(),
found: impl_ty.into(),
@@ -1814,7 +1921,7 @@ fn compare_type_predicate_entailment<'tcx>(
let impl_ty_span = tcx.def_span(impl_ty_def_id);
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
let param_env = ty::ParamEnv::new(
- tcx.mk_predicates(&hybrid_preds.predicates),
+ tcx.mk_clauses(&hybrid_preds.predicates),
Reveal::UserFacing,
hir::Constness::NotConst,
);
@@ -1922,7 +2029,8 @@ pub(super) fn check_type_bounds<'tcx>(
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var);
- tcx.mk_bound(
+ Ty::new_bound(
+ tcx,
ty::INNERMOST,
ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
)
@@ -1932,7 +2040,8 @@ pub(super) fn check_type_bounds<'tcx>(
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
- tcx.mk_re_late_bound(
+ ty::Region::new_late_bound(
+ tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
)
@@ -1941,11 +2050,10 @@ pub(super) fn check_type_bounds<'tcx>(
GenericParamDefKind::Const { .. } => {
let bound_var = ty::BoundVariableKind::Const;
bound_vars.push(bound_var);
- tcx.mk_const(
- ty::ConstKind::Bound(
- ty::INNERMOST,
- ty::BoundVar::from_usize(bound_vars.len() - 1),
- ),
+ ty::Const::new_bound(
+ tcx,
+ ty::INNERMOST,
+ ty::BoundVar::from_usize(bound_vars.len() - 1),
tcx.type_of(param.def_id)
.no_bound_vars()
.expect("const parameter types cannot be generic"),
@@ -1989,7 +2097,7 @@ pub(super) fn check_type_bounds<'tcx>(
.to_predicate(tcx),
),
};
- ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness())
+ ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing, param_env.constness())
};
debug!(?normalize_param_env);
@@ -2003,7 +2111,7 @@ pub(super) fn check_type_bounds<'tcx>(
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
// associated type.
- let impl_ty_span = if tcx.opt_rpitit_info(impl_ty.def_id).is_some() {
+ let impl_ty_span = if impl_ty.opt_rpitit_info.is_some() {
tcx.def_span(impl_ty_def_id)
} else {
match tcx.hir().get_by_def_id(impl_ty_def_id) {
@@ -2015,7 +2123,7 @@ pub(super) fn check_type_bounds<'tcx>(
_ => bug!(),
}
};
- let assumed_wf_types = ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty_def_id);
+ let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?;
let normalize_cause = ObligationCause::new(
impl_ty_span,
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index e0ba255cc..13d1abe2a 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -128,7 +128,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// We don't need to normalize this param-env or anything, since we're only
// substituting it with free params, so no additional param-env normalization
// can occur on top of what has been done in the param_env query itself.
- let param_env = ty::EarlyBinder(tcx.param_env(adt_def_id))
+ let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
.subst(tcx, adt_to_impl_substs)
.with_constness(tcx.constness(drop_impl_def_id));
@@ -183,7 +183,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
}
RegionResolutionError::SubSupConflict(_, _, _, a, _, b, _) => format!("{b}: {a}"),
RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
- format!("{b}: {a}", a = tcx.mk_re_var(a))
+ format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
}
};
guar = Some(
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index e8785235c..1248f991c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -11,7 +11,7 @@ use hir::def_id::DefId;
use rustc_errors::{struct_span_err, DiagnosticMessage};
use rustc_hir as hir;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::spec::abi::Abi;
@@ -53,14 +53,14 @@ fn equate_intrinsic_type<'tcx>(
&& gen_count_ok(own_counts.types, n_tps, "type")
&& gen_count_ok(own_counts.consts, 0, "const")
{
- let fty = tcx.mk_fn_ptr(sig);
+ let fty = Ty::new_fn_ptr(tcx, sig);
let it_def_id = it.owner_id.def_id;
let cause = ObligationCause::new(it.span, it_def_id, ObligationCauseCode::IntrinsicType);
require_same_types(
tcx,
&cause,
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
- tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id).subst_identity()),
+ Ty::new_fn_ptr(tcx, tcx.fn_sig(it.owner_id).subst_identity()),
fty,
);
}
@@ -121,10 +121,11 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
if has_safe_attr != is_in_list {
tcx.sess.struct_span_err(
tcx.def_span(intrinsic_id),
- DiagnosticMessage::Str(format!(
- "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
- tcx.item_name(intrinsic_id)
- ))).emit();
+ DiagnosticMessage::from(format!(
+ "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
+ tcx.item_name(intrinsic_id)
+ )
+ )).emit();
}
is_in_list
@@ -133,7 +134,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
/// and in `library/core/src/intrinsics.rs`.
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
- let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
+ let param = |n| Ty::new_param(tcx, n, Symbol::intern(&format!("P{}", n)));
let intrinsic_id = it.owner_id.to_def_id();
let intrinsic_name = tcx.item_name(intrinsic_id);
let name_str = intrinsic_name.as_str();
@@ -144,16 +145,18 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
]);
let mk_va_list_ty = |mutbl| {
tcx.lang_items().va_list().map(|did| {
- let region = tcx.mk_re_late_bound(
+ let region = ty::Region::new_late_bound(
+ tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
);
- let env_region = tcx.mk_re_late_bound(
+ let env_region = ty::Region::new_late_bound(
+ tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
);
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
- (tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
+ (Ty::new_ref(tcx, env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
})
};
@@ -165,15 +168,15 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let (n_tps, inputs, output) = match split[1] {
"cxchg" | "cxchgweak" => (
1,
- vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)],
- tcx.mk_tup(&[param(0), tcx.types.bool]),
+ vec![Ty::new_mut_ptr(tcx, param(0)), param(0), param(0)],
+ Ty::new_tup(tcx, &[param(0), tcx.types.bool]),
),
- "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)),
- "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+ "load" => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
+ "store" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx)),
"xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax"
- | "umin" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], param(0)),
- "fence" | "singlethreadfence" => (0, Vec::new(), tcx.mk_unit()),
+ | "umin" => (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
+ "fence" | "singlethreadfence" => (0, Vec::new(), Ty::new_unit(tcx)),
op => {
tcx.sess.emit_err(UnrecognizedAtomicOperation { span: it.span, op });
return;
@@ -185,19 +188,19 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let (n_tps, inputs, output) = match intrinsic_name {
sym::abort => (0, Vec::new(), tcx.types.never),
sym::unreachable => (0, Vec::new(), tcx.types.never),
- sym::breakpoint => (0, Vec::new(), tcx.mk_unit()),
+ sym::breakpoint => (0, Vec::new(), Ty::new_unit(tcx)),
sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
(1, Vec::new(), tcx.types.usize)
}
sym::size_of_val | sym::min_align_of_val => {
- (1, vec![tcx.mk_imm_ptr(param(0))], tcx.types.usize)
+ (1, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
}
sym::rustc_peek => (1, vec![param(0)], param(0)),
sym::caller_location => (0, vec![], tcx.caller_location_ty()),
sym::assert_inhabited
| sym::assert_zero_valid
- | sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()),
- sym::forget => (1, vec![param(0)], tcx.mk_unit()),
+ | sym::assert_mem_uninitialized_valid => (1, Vec::new(), Ty::new_unit(tcx)),
+ sym::forget => (1, vec![param(0)], Ty::new_unit(tcx)),
sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)),
sym::prefetch_read_data
| sym::prefetch_write_data
@@ -205,75 +208,79 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
| sym::prefetch_write_instruction => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
tcx.types.i32,
],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
),
- sym::drop_in_place => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()),
+ sym::drop_in_place => (1, vec![Ty::new_mut_ptr(tcx, param(0))], Ty::new_unit(tcx)),
sym::needs_drop => (1, Vec::new(), tcx.types.bool),
- sym::type_name => (1, Vec::new(), tcx.mk_static_str()),
- sym::type_id => (1, Vec::new(), tcx.types.u64),
+ sym::type_name => (1, Vec::new(), Ty::new_static_str(tcx)),
+ sym::type_id => (1, Vec::new(), tcx.types.u128),
sym::offset => (2, vec![param(0), param(1)], param(0)),
sym::arith_offset => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
tcx.types.isize,
],
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
),
sym::option_payload_ptr => {
let option_def_id = tcx.require_lang_item(hir::LangItem::Option, None);
let p0 = param(0);
(
1,
- vec![tcx.mk_ptr(ty::TypeAndMut {
- ty: tcx.mk_adt(
- tcx.adt_def(option_def_id),
- tcx.mk_substs_from_iter([ty::GenericArg::from(p0)].into_iter()),
- ),
- mutbl: hir::Mutability::Not,
- })],
- tcx.mk_ptr(ty::TypeAndMut { ty: p0, mutbl: hir::Mutability::Not }),
+ vec![Ty::new_ptr(
+ tcx,
+ ty::TypeAndMut {
+ ty: Ty::new_adt(
+ tcx,
+ tcx.adt_def(option_def_id),
+ tcx.mk_substs_from_iter([ty::GenericArg::from(p0)].into_iter()),
+ ),
+ mutbl: hir::Mutability::Not,
+ },
+ )],
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: p0, mutbl: hir::Mutability::Not }),
)
}
sym::ptr_mask => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
tcx.types.usize,
],
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
),
sym::copy | sym::copy_nonoverlapping => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
tcx.types.usize,
],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
),
sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
tcx.types.usize,
],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
),
sym::write_bytes | sym::volatile_set_memory => (
1,
vec![
- tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
+ Ty::new_ptr(tcx, ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
tcx.types.u8,
tcx.types.usize,
],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
),
sym::sqrtf32 => (0, vec![tcx.types.f32], tcx.types.f32),
sym::sqrtf64 => (0, vec![tcx.types.f64], tcx.types.f64),
@@ -321,10 +328,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::roundevenf64 => (0, vec![tcx.types.f64], tcx.types.f64),
sym::volatile_load | sym::unaligned_volatile_load => {
- (1, vec![tcx.mk_imm_ptr(param(0))], param(0))
+ (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0))
}
sym::volatile_store | sym::unaligned_volatile_store => {
- (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit())
+ (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
}
sym::ctpop
@@ -336,28 +343,34 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
| sym::bitreverse => (1, vec![param(0)], param(0)),
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
- (1, vec![param(0), param(0)], tcx.mk_tup(&[param(0), tcx.types.bool]))
+ (1, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool]))
}
- sym::ptr_guaranteed_cmp => {
- (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.u8)
- }
+ sym::ptr_guaranteed_cmp => (
+ 1,
+ vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
+ tcx.types.u8,
+ ),
sym::const_allocate => {
- (0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
+ (0, vec![tcx.types.usize, tcx.types.usize], Ty::new_mut_ptr(tcx, tcx.types.u8))
}
sym::const_deallocate => (
0,
- vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
- tcx.mk_unit(),
+ vec![Ty::new_mut_ptr(tcx, tcx.types.u8), tcx.types.usize, tcx.types.usize],
+ Ty::new_unit(tcx),
),
- sym::ptr_offset_from => {
- (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
- }
- sym::ptr_offset_from_unsigned => {
- (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.usize)
- }
+ sym::ptr_offset_from => (
+ 1,
+ vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
+ tcx.types.isize,
+ ),
+ sym::ptr_offset_from_unsigned => (
+ 1,
+ vec![Ty::new_imm_ptr(tcx, param(0)), Ty::new_imm_ptr(tcx, param(0))],
+ tcx.types.usize,
+ ),
sym::unchecked_div | sym::unchecked_rem | sym::exact_div => {
(1, vec![param(0), param(0)], param(0))
}
@@ -376,12 +389,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
}
sym::float_to_int_unchecked => (2, vec![param(0)], param(1)),
- sym::assume => (0, vec![tcx.types.bool], tcx.mk_unit()),
+ sym::assume => (0, vec![tcx.types.bool], Ty::new_unit(tcx)),
sym::likely => (0, vec![tcx.types.bool], tcx.types.bool),
sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool),
- sym::read_via_copy => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)),
- sym::write_via_move => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+ sym::read_via_copy => (1, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
+ sym::write_via_move => {
+ (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+ }
sym::discriminant_value => {
let assoc_items = tcx.associated_item_def_ids(
@@ -392,43 +407,47 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
(
1,
- vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))],
- tcx.mk_projection(discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
+ vec![Ty::new_imm_ref(
+ tcx,
+ ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
+ param(0),
+ )],
+ Ty::new_projection(tcx, discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
)
}
kw::Try => {
- let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
+ let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
[mut_u8],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
false,
hir::Unsafety::Normal,
Abi::Rust,
));
let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
[mut_u8, mut_u8],
- tcx.mk_unit(),
+ Ty::new_unit(tcx),
false,
hir::Unsafety::Normal,
Abi::Rust,
));
(
0,
- vec![tcx.mk_fn_ptr(try_fn_ty), mut_u8, tcx.mk_fn_ptr(catch_fn_ty)],
+ vec![Ty::new_fn_ptr(tcx, try_fn_ty), mut_u8, Ty::new_fn_ptr(tcx, catch_fn_ty)],
tcx.types.i32,
)
}
sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
- Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()),
+ Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], Ty::new_unit(tcx)),
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
Some((va_list_ref_ty, va_list_ty)) => {
- let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty);
- (0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit())
+ let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
+ (0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx))
}
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
@@ -438,11 +457,17 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
- sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+ sym::nontemporal_store => {
+ (1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], Ty::new_unit(tcx))
+ }
sym::raw_eq => {
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
- let param_ty = tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0));
+ let param_ty = Ty::new_imm_ref(
+ tcx,
+ ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
+ param(0),
+ );
(1, vec![param_ty; 2], tcx.types.bool)
}
@@ -451,7 +476,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::const_eval_select => (4, vec![param(0), param(1), param(2)], param(3)),
sym::vtable_size | sym::vtable_align => {
- (0, vec![tcx.mk_imm_ptr(tcx.mk_unit())], tcx.types.usize)
+ (0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
}
other => {
@@ -470,7 +495,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let param = |n| {
let name = Symbol::intern(&format!("P{}", n));
- tcx.mk_ty_param(n, name)
+ Ty::new_param(tcx, n, name)
};
let name = it.ident.name;
@@ -512,7 +537,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)),
sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)),
sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)),
- sym::simd_scatter => (3, vec![param(0), param(1), param(2)], tcx.mk_unit()),
+ sym::simd_scatter => (3, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)),
sym::simd_cast
@@ -541,7 +566,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
name if name.as_str().starts_with("simd_shuffle") => {
match name.as_str()["simd_shuffle".len()..].parse() {
Ok(n) => {
- let params = vec![param(0), param(0), tcx.mk_array(tcx.types.u32, n)];
+ let params = vec![param(0), param(0), Ty::new_array(tcx, tcx.types.u32, n)];
(2, params, param(1))
}
Err(_) => {
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 3971a4c01..ce2da7cb1 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -188,7 +188,7 @@ fn missing_items_err(
full_impl_span: Span,
) {
let missing_items =
- missing_items.iter().filter(|trait_item| tcx.opt_rpitit_info(trait_item.def_id).is_none());
+ missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none());
let missing_items_msg = missing_items
.clone()
@@ -296,7 +296,7 @@ fn default_body_is_unstable(
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
fn bounds_from_generic_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
- predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
+ predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
) -> (String, String) {
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
let mut projections = vec![];
@@ -304,7 +304,7 @@ fn bounds_from_generic_predicates<'tcx>(
debug!("predicate {:?}", predicate);
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
+ ty::ClauseKind::Trait(trait_predicate) => {
let entry = types.entry(trait_predicate.self_ty()).or_default();
let def_id = trait_predicate.def_id();
if Some(def_id) != tcx.lang_items().sized_trait() {
@@ -313,7 +313,7 @@ fn bounds_from_generic_predicates<'tcx>(
entry.push(trait_predicate.def_id());
}
}
- ty::PredicateKind::Clause(ty::Clause::Projection(projection_pred)) => {
+ ty::ClauseKind::Projection(projection_pred) => {
projections.push(bound_predicate.rebind(projection_pred));
}
_ => {}
@@ -362,7 +362,7 @@ fn fn_sig_suggestion<'tcx>(
tcx: TyCtxt<'tcx>,
sig: ty::FnSig<'tcx>,
ident: Ident,
- predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
+ predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
assoc: ty::AssocItem,
) -> String {
let args = sig
@@ -403,7 +403,30 @@ fn fn_sig_suggestion<'tcx>(
.flatten()
.collect::<Vec<String>>()
.join(", ");
- let output = sig.output();
+ let mut output = sig.output();
+
+ let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
+ output = if let ty::Alias(_, alias_ty) = *output.kind() {
+ tcx.explicit_item_bounds(alias_ty.def_id)
+ .subst_iter_copied(tcx, alias_ty.substs)
+ .find_map(|(bound, _)| bound.as_projection_clause()?.no_bound_vars()?.term.ty())
+ .unwrap_or_else(|| {
+ span_bug!(
+ ident.span,
+ "expected async fn to have `impl Future` output, but it returns {output}"
+ )
+ })
+ } else {
+ span_bug!(
+ ident.span,
+ "expected async fn to have `impl Future` output, but it returns {output}"
+ )
+ };
+ "async "
+ } else {
+ ""
+ };
+
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
let unsafety = sig.unsafety.prefix_str();
@@ -414,7 +437,9 @@ fn fn_sig_suggestion<'tcx>(
// lifetimes between the `impl` and the `trait`, but this should be good enough to
// fill in a significant portion of the missing code, and other subsequent
// suggestions can help the user fix the code.
- format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
+ format!(
+ "{unsafety}{asyncness}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}"
+ )
}
pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
@@ -443,19 +468,16 @@ fn suggestion_signature<'tcx>(
);
match assoc.kind {
- ty::AssocKind::Fn => {
- // We skip the binder here because the binder would deanonymize all
- // late-bound regions, and we don't want method signatures to show up
- // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
- // regions just fine, showing `fn(&MyType)`.
- fn_sig_suggestion(
- tcx,
- tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
- assoc.ident(tcx),
- tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
- assoc,
- )
- }
+ ty::AssocKind::Fn => fn_sig_suggestion(
+ tcx,
+ tcx.liberate_late_bound_regions(
+ assoc.def_id,
+ tcx.fn_sig(assoc.def_id).subst(tcx, substs),
+ ),
+ assoc.ident(tcx),
+ tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
+ assoc,
+ ),
ty::AssocKind::Type => {
let (generics, where_clauses) = bounds_from_generic_predicates(
tcx,
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 6ab5556e9..5bd6fcb96 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -392,7 +392,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
// Manually recurse over closures and inline consts, because they are the only
// case of nested bodies that share the parent environment.
hir::ExprKind::Closure(&hir::Closure { body, .. })
- | hir::ExprKind::ConstBlock(hir::AnonConst { body, .. }) => {
+ | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
let body = visitor.tcx.hir().body(body);
visitor.visit_body(body);
}
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index b403ee96b..d4748b7ef 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -15,7 +15,7 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::query::Providers;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
- self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, TypeVisitor,
};
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
@@ -81,7 +81,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
self.tcx(),
cause,
param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg))),
));
}
}
@@ -105,7 +105,12 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
}
f(&mut wfcx);
- let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id);
+ let assumed_wf_types = match wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)
+ {
+ Ok(wf_types) => wf_types,
+ Err(_guar) => return,
+ };
+
let implied_bounds = infcx.implied_bounds_tys(param_env, body_def_id, assumed_wf_types);
let errors = wfcx.select_all_or_error();
@@ -217,10 +222,10 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl);
}
hir::ItemKind::Static(ty, ..) => {
- check_item_type(tcx, def_id, ty.span, false);
+ check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
}
hir::ItemKind::Const(ty, ..) => {
- check_item_type(tcx, def_id, ty.span, false);
+ check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
}
hir::ItemKind::Struct(_, ast_generics) => {
check_type_defn(tcx, item, false);
@@ -242,6 +247,12 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
}
// `ForeignItem`s are handled separately.
hir::ItemKind::ForeignMod { .. } => {}
+ hir::ItemKind::TyAlias(hir_ty, ..) => {
+ if tcx.type_of(item.owner_id.def_id).skip_binder().has_opaque_types() {
+ // Bounds are respected for `type X = impl Trait` and `type X = (impl Trait, Y);`
+ check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
+ }
+ }
_ => {}
}
}
@@ -258,7 +269,9 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
hir::ForeignItemKind::Fn(decl, ..) => {
check_item_fn(tcx, def_id, item.ident, item.span, decl)
}
- hir::ForeignItemKind::Static(ty, ..) => check_item_type(tcx, def_id, ty.span, true),
+ hir::ForeignItemKind::Static(ty, ..) => {
+ check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
+ }
hir::ForeignItemKind::Type => (),
}
}
@@ -314,7 +327,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
// Gather the bounds with which all other items inside of this trait constrain the GAT.
// This is calculated by taking the intersection of the bounds that each item
// constrains the GAT with individually.
- let mut new_required_bounds: Option<FxHashSet<ty::Predicate<'_>>> = None;
+ let mut new_required_bounds: Option<FxHashSet<ty::Clause<'_>>> = None;
for item in associated_items {
let item_def_id = item.id.owner_id;
// Skip our own GAT, since it does not constrain itself at all.
@@ -411,21 +424,17 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
let mut unsatisfied_bounds: Vec<_> = required_bounds
.into_iter()
.filter(|clause| match clause.kind().skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate(
- a,
- b,
- ))) => !region_known_to_outlive(
- tcx,
- gat_def_id.def_id,
- param_env,
- &FxIndexSet::default(),
- a,
- b,
- ),
- ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
- a,
- b,
- ))) => !ty_known_to_outlive(
+ ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
+ !region_known_to_outlive(
+ tcx,
+ gat_def_id.def_id,
+ param_env,
+ &FxIndexSet::default(),
+ a,
+ b,
+ )
+ }
+ ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => !ty_known_to_outlive(
tcx,
gat_def_id.def_id,
param_env,
@@ -433,7 +442,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
a,
b,
),
- _ => bug!("Unexpected PredicateKind"),
+ _ => bug!("Unexpected ClauseKind"),
})
.map(|clause| clause.to_string())
.collect();
@@ -481,7 +490,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
fn augment_param_env<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
- new_predicates: Option<&FxHashSet<ty::Predicate<'tcx>>>,
+ new_predicates: Option<&FxHashSet<ty::Clause<'tcx>>>,
) -> ty::ParamEnv<'tcx> {
let Some(new_predicates) = new_predicates else {
return param_env;
@@ -491,7 +500,7 @@ fn augment_param_env<'tcx>(
return param_env;
}
- let bounds = tcx.mk_predicates_from_iter(
+ let bounds = tcx.mk_clauses_from_iter(
param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()),
);
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
@@ -517,7 +526,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
wf_tys: &FxIndexSet<Ty<'tcx>>,
gat_def_id: LocalDefId,
gat_generics: &'tcx ty::Generics,
-) -> Option<FxHashSet<ty::Predicate<'tcx>>> {
+) -> Option<FxHashSet<ty::Clause<'tcx>>> {
// The bounds we that we would require from `to_check`
let mut bounds = FxHashSet::default();
@@ -552,22 +561,24 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
// our example, the type was `Self`, which will also be
// `Self` in the GAT.
let ty_param = gat_generics.param_at(*ty_idx, tcx);
- let ty_param = tcx.mk_ty_param(ty_param.index, ty_param.name);
+ let ty_param = Ty::new_param(tcx, ty_param.index, ty_param.name);
// Same for the region. In our example, 'a corresponds
// to the 'me parameter.
let region_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
- def_id: region_param.def_id,
- index: region_param.index,
- name: region_param.name,
- });
+ let region_param = ty::Region::new_early_bound(
+ tcx,
+ ty::EarlyBoundRegion {
+ def_id: region_param.def_id,
+ index: region_param.index,
+ name: region_param.name,
+ },
+ );
// The predicate we expect to see. (In our example,
// `Self: 'me`.)
- let clause = ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
- ty::OutlivesPredicate(ty_param, region_param),
- ));
- let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
- bounds.insert(clause);
+ bounds.insert(
+ ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_param, region_param))
+ .to_predicate(tcx),
+ );
}
}
@@ -593,24 +604,32 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
debug!("required clause: {region_a} must outlive {region_b}");
// Translate into the generic parameters of the GAT.
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
- let region_a_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
- def_id: region_a_param.def_id,
- index: region_a_param.index,
- name: region_a_param.name,
- });
+ let region_a_param = ty::Region::new_early_bound(
+ tcx,
+ ty::EarlyBoundRegion {
+ def_id: region_a_param.def_id,
+ index: region_a_param.index,
+ name: region_a_param.name,
+ },
+ );
// Same for the region.
let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
- let region_b_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
- def_id: region_b_param.def_id,
- index: region_b_param.index,
- name: region_b_param.name,
- });
+ let region_b_param = ty::Region::new_early_bound(
+ tcx,
+ ty::EarlyBoundRegion {
+ def_id: region_b_param.def_id,
+ index: region_b_param.index,
+ name: region_b_param.name,
+ },
+ );
// The predicate we expect to see.
- let clause = ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
- ty::OutlivesPredicate(region_a_param, region_b_param),
- ));
- let clause = tcx.mk_predicate(ty::Binder::dummy(clause));
- bounds.insert(clause);
+ bounds.insert(
+ ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
+ region_a_param,
+ region_b_param,
+ ))
+ .to_predicate(tcx),
+ );
}
}
}
@@ -820,83 +839,20 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
let ty = tcx.type_of(param.def_id).subst_identity();
if tcx.features().adt_const_params {
- if let Some(non_structural_match_ty) =
- traits::search_for_adt_const_param_violation(param.span, tcx, ty)
- {
- // We use the same error code in both branches, because this is really the same
- // issue: we just special-case the message for type parameters to make it
- // clearer.
- match non_structural_match_ty.kind() {
- ty::Param(_) => {
- // Const parameters may not have type parameters as their types,
- // because we cannot be sure that the type parameter derives `PartialEq`
- // and `Eq` (just implementing them is not enough for `structural_match`).
- struct_span_err!(
- tcx.sess,
- hir_ty.span,
- E0741,
- "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
- used as the type of a const parameter",
- )
- .span_label(
- hir_ty.span,
- format!("`{ty}` may not derive both `PartialEq` and `Eq`"),
- )
- .note(
- "it is not currently possible to use a type parameter as the type of a \
- const parameter",
- )
- .emit();
- }
- ty::Float(_) => {
- struct_span_err!(
- tcx.sess,
- hir_ty.span,
- E0741,
- "`{ty}` is forbidden as the type of a const generic parameter",
- )
- .note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
- .emit();
- }
- ty::FnPtr(_) => {
- struct_span_err!(
- tcx.sess,
- hir_ty.span,
- E0741,
- "using function pointers as const generic parameters is forbidden",
- )
- .emit();
- }
- ty::RawPtr(_) => {
- struct_span_err!(
- tcx.sess,
- hir_ty.span,
- E0741,
- "using raw pointers as const generic parameters is forbidden",
- )
- .emit();
- }
- _ => {
- let mut diag = struct_span_err!(
- tcx.sess,
- hir_ty.span,
- E0741,
- "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
- the type of a const parameter",
- non_structural_match_ty,
- );
-
- if ty == non_structural_match_ty {
- diag.span_label(
- hir_ty.span,
- format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
- );
- }
-
- diag.emit();
- }
- }
- }
+ enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
+ let trait_def_id =
+ tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span));
+ wfcx.register_bound(
+ ObligationCause::new(
+ hir_ty.span,
+ param.def_id,
+ ObligationCauseCode::ConstParam(ty),
+ ),
+ wfcx.param_env,
+ ty,
+ trait_def_id,
+ );
+ });
} else {
let err_ty_str;
let mut is_ptr = true;
@@ -1025,7 +981,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
// intermediate types must be sized.
let needs_drop_copy = || {
packed && {
- let ty = tcx.type_of(variant.fields.raw.last().unwrap().did).subst_identity();
+ let ty = tcx.type_of(variant.tail().did).subst_identity();
let ty = tcx.erase_regions(ty);
if ty.has_infer() {
tcx.sess
@@ -1078,9 +1034,9 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
tcx,
cause,
wfcx.param_env,
- ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
- )),
+ ))),
));
}
}
@@ -1133,7 +1089,7 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
wfcx.infcx,
wfcx.param_env,
wfcx.body_def_id,
- normalized_bound,
+ normalized_bound.as_predicate(),
bound_span,
)
});
@@ -1154,20 +1110,32 @@ fn check_item_fn(
})
}
-fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_foreign_ty: bool) {
+enum UnsizedHandling {
+ Forbid,
+ Allow,
+ AllowIfForeignTail,
+}
+
+fn check_item_type(
+ tcx: TyCtxt<'_>,
+ item_id: LocalDefId,
+ ty_span: Span,
+ unsized_handling: UnsizedHandling,
+) {
debug!("check_item_type: {:?}", item_id);
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
let ty = tcx.type_of(item_id).subst_identity();
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
- let mut forbid_unsized = true;
- if allow_foreign_ty {
- let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env);
- if let ty::Foreign(_) = tail.kind() {
- forbid_unsized = false;
+ let forbid_unsized = match unsized_handling {
+ UnsizedHandling::Forbid => true,
+ UnsizedHandling::Allow => false,
+ UnsizedHandling::AllowIfForeignTail => {
+ let tail = tcx.struct_tail_erasing_lifetimes(item_ty, wfcx.param_env);
+ !matches!(tail.kind(), ty::Foreign(_))
}
- }
+ };
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
if forbid_unsized {
@@ -1398,7 +1366,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
let mut param_count = CountParams::default();
let has_region = pred.visit_with(&mut param_count).is_break();
- let substituted_pred = ty::EarlyBinder(pred).subst(tcx, substs);
+ let substituted_pred = ty::EarlyBinder::bind(pred).subst(tcx, substs);
// Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params.
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
@@ -1441,7 +1409,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
infcx,
wfcx.param_env.without_const(),
wfcx.body_def_id,
- p,
+ p.as_predicate(),
sp,
)
});
@@ -1503,7 +1471,7 @@ fn check_fn_or_method<'tcx>(
let span = tcx.def_span(def_id);
let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None;
let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 });
- // Check that the argument is a tuple
+ // Check that the argument is a tuple and is sized
if let Some(ty) = inputs.next() {
wfcx.register_bound(
ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
@@ -1511,6 +1479,12 @@ fn check_fn_or_method<'tcx>(
*ty,
tcx.require_lang_item(hir::LangItem::Tuple, Some(span)),
);
+ wfcx.register_bound(
+ ObligationCause::new(span, wfcx.body_def_id, ObligationCauseCode::RustCall),
+ wfcx.param_env,
+ *ty,
+ tcx.require_lang_item(hir::LangItem::Sized, Some(span)),
+ );
} else {
tcx.sess.span_err(
hir_decl.inputs.last().map_or(span, |input| input.span),
@@ -1572,13 +1546,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
if let ty::Alias(ty::Opaque, unshifted_opaque_ty) = *ty.kind()
&& self.seen.insert(unshifted_opaque_ty.def_id)
&& let Some(opaque_def_id) = unshifted_opaque_ty.def_id.as_local()
- && let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty()
- && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin
+ && let origin = tcx.opaque_type_origin(opaque_def_id)
+ && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = origin
&& source == self.fn_def_id
{
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, _depth| {
match re.kind() {
- ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReError(_) => re,
+ ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReError(_) | ty::ReStatic => re,
r => bug!("unexpected region: {r:?}"),
}
});
@@ -1591,7 +1565,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
self.wfcx.infcx,
self.wfcx.param_env,
self.wfcx.body_def_id,
- bound,
+ bound.as_predicate(),
bound_span,
));
// Set the debruijn index back to innermost here, since we already eagerly
@@ -1799,9 +1773,11 @@ fn check_variances_for_type_defn<'tcx>(
item: &hir::Item<'tcx>,
hir_generics: &hir::Generics<'_>,
) {
- let ty = tcx.type_of(item.owner_id).subst_identity();
- if tcx.has_error_field(ty) {
- return;
+ let identity_substs = ty::InternalSubsts::identity_for_item(tcx, item.owner_id);
+ for field in tcx.adt_def(item.owner_id).all_fields() {
+ if field.ty(tcx, identity_substs).references_error() {
+ return;
+ }
}
let ty_predicates = tcx.predicates_of(item.owner_id);
@@ -1902,7 +1878,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
// We lower empty bounds like `Vec<dyn Copy>:` as
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
// regular WF checking
- if let ty::PredicateKind::WellFormed(..) = pred.kind().skip_binder() {
+ if let ty::ClauseKind::WellFormed(..) = pred.kind().skip_binder() {
continue;
}
// Match the existing behavior.