diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
16 files changed, 204 insertions, 229 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 40049f96de4..6c534d58a7d 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -778,13 +778,13 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { match tcx.def_kind(def_id) { DefKind::Static { .. } => { - tcx.ensure().typeck(def_id); + tcx.ensure_ok().typeck(def_id); maybe_check_static_with_link_section(tcx, def_id); check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); } DefKind::Const => { - tcx.ensure().typeck(def_id); + tcx.ensure_ok().typeck(def_id); } DefKind::Enum => { check_enum(tcx, def_id); @@ -804,7 +804,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { DefKind::Impl { of_trait } => { if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { if tcx - .ensure() + .ensure_ok() .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id) .is_ok() { @@ -1042,7 +1042,7 @@ fn check_impl_items_against_trait<'tcx>( continue; }; - let res = tcx.ensure().compare_impl_item(impl_item.expect_local()); + let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local()); if res.is_ok() { match ty_impl_item.kind { @@ -1488,7 +1488,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) { for v in def.variants() { if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr { - tcx.ensure().typeck(discr_def_id.expect_local()); + tcx.ensure_ok().typeck(discr_def_id.expect_local()); } } 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 3bff5fe02c0..a91d72e9225 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2034,7 +2034,7 @@ pub(super) fn check_type_bounds<'tcx>( ) -> Result<(), ErrorGuaranteed> { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure().coherent_trait(impl_trait_ref.def_id)?; + tcx.ensure_ok().coherent_trait(impl_trait_ref.def_id)?; let param_env = tcx.param_env(impl_ty.def_id); debug!(?param_env); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index cf3d4897304..c3404fa1624 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -472,7 +472,7 @@ pub fn check_intrinsic_type( 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 => { + sym::unchecked_div | sym::unchecked_rem | sym::exact_div | sym::disjoint_bitor => { (1, 0, vec![param(0), param(0)], param(0)) } sym::unchecked_shl | sym::unchecked_shr => (2, 0, vec![param(0), param(1)], param(0)), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c9837ca3716..20eb96f3ab1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -328,16 +328,20 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), // `ForeignItem`s are handled separately. hir::ItemKind::ForeignMod { .. } => Ok(()), - hir::ItemKind::TyAlias(hir_ty, hir_generics) => { - if tcx.type_alias_is_lazy(item.owner_id) { - // Bounds of lazy type aliases and of eager ones that contain opaque types are respected. - // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`. - let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); - check_variances_for_type_defn(tcx, item, hir_generics); - res - } else { + hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => { + let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { + let ty = tcx.type_of(def_id).instantiate_identity(); + let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); + wfcx.register_wf_obligation( + hir_ty.span, + Some(WellFormedLoc::Ty(def_id)), + item_ty.into(), + ); + check_where_clauses(wfcx, item.span, def_id); Ok(()) - } + }); + check_variances_for_type_defn(tcx, item, hir_generics); + res } _ => Ok(()), }; @@ -1046,7 +1050,7 @@ fn check_associated_item( // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure() + tcx.ensure_ok() .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?; let self_ty = match item.container { @@ -1061,6 +1065,7 @@ fn check_associated_item( let ty = tcx.type_of(item.def_id).instantiate_identity(); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); + check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span)); Ok(()) } ty::AssocKind::Fn => { @@ -1185,7 +1190,7 @@ fn check_type_defn<'tcx>( ), wfcx.param_env, ty, - tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)), ); } @@ -1276,7 +1281,6 @@ fn check_item_fn( enum UnsizedHandling { Forbid, - Allow, AllowIfForeignTail, } @@ -1294,7 +1298,6 @@ fn check_item_type( let forbid_unsized = match unsized_handling { UnsizedHandling::Forbid => true, - UnsizedHandling::Allow => false, UnsizedHandling::AllowIfForeignTail => { let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); @@ -1312,7 +1315,7 @@ fn check_item_type( ), wfcx.param_env, item_ty, - tcx.require_lang_item(LangItem::Sized, None), + tcx.require_lang_item(LangItem::Sized, Some(ty_span)), ); } @@ -1354,7 +1357,7 @@ fn check_impl<'tcx>( let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity(); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. - tcx.ensure().coherent_trait(trait_ref.def_id)?; + tcx.ensure_ok().coherent_trait(trait_ref.def_id)?; let trait_span = hir_trait_ref.path.span; let trait_ref = wfcx.normalize( trait_span, @@ -1642,6 +1645,31 @@ fn check_fn_or_method<'tcx>( ); } } + + // If the function has a body, additionally require that the return type is sized. + check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output { + hir::FnRetTy::Return(ty) => Some(ty.span), + hir::FnRetTy::DefaultReturn(_) => None, + }); +} + +fn check_sized_if_body<'tcx>( + wfcx: &WfCheckingCtxt<'_, 'tcx>, + def_id: LocalDefId, + ty: Ty<'tcx>, + maybe_span: Option<Span>, +) { + let tcx = wfcx.tcx(); + if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) { + let span = maybe_span.unwrap_or(body.value.span); + + wfcx.register_bound( + ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType), + wfcx.param_env, + ty, + tcx.require_lang_item(LangItem::Sized, Some(span)), + ); + } } /// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`. @@ -2268,11 +2296,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_module_items(module); let res = items - .par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)) - .and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))) - .and(items.par_opaques(|item| tcx.ensure().check_well_formed(item))); + .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)) + .and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) + .and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) + .and( + items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)), + ) + .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item))); if module == LocalModDefId::CRATE_DEF_ID { super::entry::check_for_entry_fn(tcx); } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 30f51fe1724..3511dbc6252 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -192,7 +192,7 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E // errors; other parts of the code may demand it for the info of // course. let span = tcx.def_span(impl_did); - tcx.at(span).ensure().coerce_unsized_info(impl_did) + tcx.at(span).ensure_ok().coerce_unsized_info(impl_did) } fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index b1f73a903d8..1bc60087ab5 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -151,7 +151,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> let Some(impls) = tcx.all_local_trait_impls(()).get(&def_id) else { return Ok(()) }; // Trigger building the specialization graph for the trait. This will detect and report any // overlap errors. - let mut res = tcx.ensure().specialization_graph_of(def_id); + let mut res = tcx.ensure_ok().specialization_graph_of(def_id); for &impl_def_id in impls { let trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); @@ -162,7 +162,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> .and(check_impl(tcx, impl_def_id, trait_ref, trait_def)) .and(check_object_overlap(tcx, impl_def_id, trait_ref)) .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def)) - .and(tcx.ensure().orphan_check_impl(impl_def_id)) + .and(tcx.ensure_ok().orphan_check_impl(impl_def_id)) .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header)); } @@ -199,10 +199,9 @@ fn check_object_overlap<'tcx>( for component_def_id in component_def_ids { if !tcx.is_dyn_compatible(component_def_id) { - // FIXME(dyn_compat_renaming): Rename test and update comment. // Without the 'dyn_compatible_for_dispatch' feature this is an error // which will be reported by wfcheck. Ignore it here. - // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. + // This is tested by `coherence-impl-trait-for-trait-dyn-compatible.rs`. // With the feature enabled, the trait is not implemented automatically, // so this is valid. } else { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 226370fccad..ce7319f6561 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -292,16 +292,16 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} hir::GenericParamKind::Type { default: Some(_), .. } => { - self.tcx.ensure().type_of(param.def_id); + self.tcx.ensure_ok().type_of(param.def_id); } hir::GenericParamKind::Type { .. } => {} hir::GenericParamKind::Const { default, .. } => { - self.tcx.ensure().type_of(param.def_id); + self.tcx.ensure_ok().type_of(param.def_id); if let Some(default) = default { // need to store default and type of default - self.tcx.ensure().const_param_default(param.def_id); + self.tcx.ensure_ok().const_param_default(param.def_id); if let hir::ConstArgKind::Anon(ac) = default.kind { - self.tcx.ensure().type_of(ac.def_id); + self.tcx.ensure_ok().type_of(ac.def_id); } } } @@ -312,8 +312,8 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { if let hir::ExprKind::Closure(closure) = expr.kind { - self.tcx.ensure().generics_of(closure.def_id); - self.tcx.ensure().codegen_fn_attrs(closure.def_id); + self.tcx.ensure_ok().generics_of(closure.def_id); + self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id); // We do not call `type_of` for closures here as that // depends on typecheck and would therefore hide // any further errors in case one typeck fails. @@ -325,15 +325,15 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { /// `check_item_type` ensures that it's called instead. fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { let def_id = opaque.def_id; - self.tcx.ensure().generics_of(def_id); - self.tcx.ensure().predicates_of(def_id); - self.tcx.ensure().explicit_item_bounds(def_id); - self.tcx.ensure().explicit_item_self_bounds(def_id); - self.tcx.ensure().item_bounds(def_id); - self.tcx.ensure().item_self_bounds(def_id); + self.tcx.ensure_ok().generics_of(def_id); + self.tcx.ensure_ok().predicates_of(def_id); + self.tcx.ensure_ok().explicit_item_bounds(def_id); + self.tcx.ensure_ok().explicit_item_self_bounds(def_id); + self.tcx.ensure_ok().item_bounds(def_id); + self.tcx.ensure_ok().item_self_bounds(def_id); if self.tcx.is_conditionally_const(def_id) { - self.tcx.ensure().explicit_implied_const_bounds(def_id); - self.tcx.ensure().const_conditions(def_id); + self.tcx.ensure_ok().explicit_implied_const_bounds(def_id); + self.tcx.ensure_ok().const_conditions(def_id); } intravisit::walk_opaque_ty(self, opaque); } @@ -683,20 +683,20 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::ForeignMod { items, .. } => { for item in *items { let item = tcx.hir().foreign_item(item.id); - tcx.ensure().generics_of(item.owner_id); - tcx.ensure().type_of(item.owner_id); - tcx.ensure().predicates_of(item.owner_id); + tcx.ensure_ok().generics_of(item.owner_id); + tcx.ensure_ok().type_of(item.owner_id); + tcx.ensure_ok().predicates_of(item.owner_id); if tcx.is_conditionally_const(def_id) { - tcx.ensure().explicit_implied_const_bounds(def_id); - tcx.ensure().const_conditions(def_id); + tcx.ensure_ok().explicit_implied_const_bounds(def_id); + tcx.ensure_ok().const_conditions(def_id); } match item.kind { hir::ForeignItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(item.owner_id); - tcx.ensure().fn_sig(item.owner_id) + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); + tcx.ensure_ok().fn_sig(item.owner_id) } hir::ForeignItemKind::Static(..) => { - tcx.ensure().codegen_fn_attrs(item.owner_id); + tcx.ensure_ok().codegen_fn_attrs(item.owner_id); let mut visitor = HirPlaceholderCollector::default(); visitor.visit_foreign_item(item); placeholder_type_error( @@ -713,40 +713,40 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } } hir::ItemKind::Enum(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); lower_enum_variant_types(tcx, def_id.to_def_id()); } hir::ItemKind::Impl { .. } => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().impl_trait_header(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().associated_items(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().impl_trait_header(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); } hir::ItemKind::Trait(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().trait_def(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().trait_def(def_id); tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().associated_items(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().associated_items(def_id); } hir::ItemKind::TraitAlias(..) => { - tcx.ensure().generics_of(def_id); + tcx.ensure_ok().generics_of(def_id); tcx.at(it.span).explicit_implied_predicates_of(def_id); tcx.at(it.span).explicit_super_predicates_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); for f in struct_def.fields() { - tcx.ensure().generics_of(f.def_id); - tcx.ensure().type_of(f.def_id); - tcx.ensure().predicates_of(f.def_id); + tcx.ensure_ok().generics_of(f.def_id); + tcx.ensure_ok().type_of(f.def_id); + tcx.ensure_ok().predicates_of(f.def_id); } if let Some(ctor_def_id) = struct_def.ctor_def_id() { @@ -755,15 +755,15 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } hir::ItemKind::TyAlias(..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_item(it); @@ -779,11 +779,11 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } hir::ItemKind::Fn { .. } => { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); - tcx.ensure().fn_sig(def_id); - tcx.ensure().codegen_fn_attrs(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); + tcx.ensure_ok().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); } } } @@ -791,18 +791,18 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let trait_item = tcx.hir().trait_item(trait_item_id); let def_id = trait_item_id.owner_id; - tcx.ensure().generics_of(def_id); + tcx.ensure_ok().generics_of(def_id); let icx = ItemCtxt::new(tcx, def_id.def_id); match trait_item.kind { hir::TraitItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().fn_sig(def_id); } hir::TraitItemKind::Const(ty, body_id) => { - tcx.ensure().type_of(def_id); + tcx.ensure_ok().type_of(def_id); if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType) && !(ty.is_suggestable_infer_ty() && body_id.is_some()) { @@ -821,9 +821,9 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } hir::TraitItemKind::Type(_, Some(_)) => { - tcx.ensure().item_bounds(def_id); - tcx.ensure().item_self_bounds(def_id); - tcx.ensure().type_of(def_id); + tcx.ensure_ok().item_bounds(def_id); + tcx.ensure_ok().item_self_bounds(def_id); + tcx.ensure_ok().type_of(def_id); // Account for `type T = _;`. let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); @@ -838,8 +838,8 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } hir::TraitItemKind::Type(_, None) => { - tcx.ensure().item_bounds(def_id); - tcx.ensure().item_self_bounds(def_id); + tcx.ensure_ok().item_bounds(def_id); + tcx.ensure_ok().item_self_bounds(def_id); // #74612: Visit and try to find bad placeholders // even if there is no concrete type. let mut visitor = HirPlaceholderCollector::default(); @@ -856,20 +856,20 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { } }; - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { let def_id = impl_item_id.owner_id; - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); let impl_item = tcx.hir().impl_item(impl_item_id); let icx = ItemCtxt::new(tcx, def_id.def_id); match impl_item.kind { hir::ImplItemKind::Fn(..) => { - tcx.ensure().codegen_fn_attrs(def_id); - tcx.ensure().fn_sig(def_id); + tcx.ensure_ok().codegen_fn_attrs(def_id); + tcx.ensure_ok().fn_sig(def_id); } hir::ImplItemKind::Type(_) => { // Account for `type T = _;` @@ -904,9 +904,9 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { } fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) { - tcx.ensure().generics_of(def_id); - tcx.ensure().type_of(def_id); - tcx.ensure().predicates_of(def_id); + tcx.ensure_ok().generics_of(def_id); + tcx.ensure_ok().type_of(def_id); + tcx.ensure_ok().predicates_of(def_id); } fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { @@ -937,9 +937,9 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { ); for f in &variant.fields { - tcx.ensure().generics_of(f.did); - tcx.ensure().type_of(f.did); - tcx.ensure().predicates_of(f.did); + tcx.ensure_ok().generics_of(f.did); + tcx.ensure_ok().type_of(f.did); + tcx.ensure_ok().predicates_of(f.did); } // Lower the ctor, if any. This also registers the variant as an item. diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 2ac8acbd3a4..c0902398a54 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { { Some(parent_did) } + Node::TyPat(_) => Some(parent_did), _ => None, } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index d67b9d33596..76006354717 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } #[instrument(level = "debug", skip(self))] - fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) { - intravisit::walk_pat(self, p) + fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) { + intravisit::walk_ty_pat(self, p) } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 348d4d708b5..4e12db190fd 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer; mod opaque; -fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { +fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use hir::*; use rustc_middle::ty::Ty; + let tcx = icx.tcx; let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); @@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { hir_id: arg_hir_id, kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }), .. - }) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span), + }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span), // Anon consts outside the type system. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) @@ -138,10 +139,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { } } -fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> { +fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> { use hir::*; use rustc_middle::ty::Ty; + let tcx = icx.tcx; + match tcx.parent_hir_node(arg_hir_id) { // Array length const arguments do not have `type_of` fed as there is never a corresponding // generic parameter definition. @@ -149,7 +152,15 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) if constant.hir_id == arg_hir_id => { - return tcx.types.usize; + tcx.types.usize + } + + Node::TyPat(pat) => { + let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else { + bug!() + }; + assert_eq!(p.hir_id, pat.hir_id); + icx.lower_ty(ty) } // This is not a `bug!` as const arguments in path segments that did not resolve to anything @@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ tcx.typeck(def_id).node_type(hir_id) } - Node::AnonConst(_) => anon_const_type_of(tcx, def_id), + Node::AnonConst(_) => anon_const_type_of(&icx, def_id), Node::ConstBlock(_) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id()); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1dcea5d0335..9769be30226 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1605,13 +1605,6 @@ pub(crate) struct OpaqueCapturesHigherRankedLifetime { pub bad_place: &'static str, } -#[derive(Diagnostic)] -#[diag(hir_analysis_pattern_type_non_const_range)] -pub(crate) struct NonConstRange { - #[primary_span] - pub span: Span, -} - #[derive(Subdiagnostic)] pub(crate) enum InvalidReceiverTyHint { #[note(hir_analysis_invalid_receiver_ty_help_weak_note)] diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs index bb771d6ea17..ec7b3aaa1c1 100644 --- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs +++ b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs @@ -1,9 +1,14 @@ use rustc_macros::Diagnostic; +use rustc_middle::ty::Ty; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(hir_analysis_pattern_type_wild_pat)] -pub(crate) struct WildPatTy { +#[diag(hir_analysis_invalid_base_type)] +pub(crate) struct InvalidBaseType<'tcx> { + pub ty: Ty<'tcx>, #[primary_span] - pub span: Span, + pub ty_span: Span, + pub pat: &'static str, + #[note] + pub pat_span: Span, } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 36b214b6ae7..79aa2f4b8cc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -3,7 +3,7 @@ use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::unord::UnordMap; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err, + Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err, }; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -808,14 +808,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|(trait_, mut assocs)| { assocs.sort(); let trait_ = trait_.print_trait_sugared(); - format!("{} in `{trait_}`", match &assocs[..] { - [] => String::new(), - [only] => format!("`{only}`"), - [assocs @ .., last] => format!( - "{} and `{last}`", - assocs.iter().map(|a| format!("`{a}`")).collect::<Vec<_>>().join(", ") - ), - }) + format!( + "{} in `{trait_}`", + listify(&assocs[..], |a| format!("`{a}`")).unwrap_or_default() + ) }) .collect::<Vec<String>>(); names.sort(); @@ -1075,18 +1071,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } }) .collect(); - let this_type = match &types_and_spans[..] { - [.., _, (last, _)] => format!( - "{} and {last}", - types_and_spans[..types_and_spans.len() - 1] - .iter() - .map(|(x, _)| x.as_str()) - .intersperse(", ") - .collect::<String>() - ), - [(only, _)] => only.to_string(), - [] => bug!("expected one segment to deny"), - }; + let this_type = listify(&types_and_spans, |(t, _)| t.to_string()) + .expect("expected one segment to deny"); let arg_spans: Vec<Span> = segments .clone() @@ -1102,21 +1088,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ProhibitGenericsArg::Infer => kinds.push("generic"), }); - let (kind, s) = match kinds[..] { - [.., _, last] => ( - format!( - "{} and {last}", - kinds[..kinds.len() - 1] - .iter() - .map(|&x| x) - .intersperse(", ") - .collect::<String>() - ), - "s", - ), - [only] => (only.to_string(), ""), - [] => bug!("expected at least one generic to prohibit"), - }; + let s = pluralize!(kinds.len()); + let kind = + listify(&kinds, |k| k.to_string()).expect("expected at least one generic to prohibit"); let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); let mut err = struct_span_code_err!( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b4cab3330af..079e8921627 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -53,7 +53,7 @@ use tracing::{debug, instrument}; use crate::bounds::Bounds; use crate::check::check_abi_fn_ptr; -use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy}; +use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; @@ -2432,61 +2432,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.ty_infer(None, hir_ty.span) } hir::TyKind::Pat(ty, pat) => { + let ty_span = ty.span; let ty = self.lower_ty(ty); let pat_ty = match pat.kind { - hir::PatKind::Wild => { - let err = self.dcx().emit_err(WildPatTy { span: pat.span }); - Ty::new_error(tcx, err) - } - hir::PatKind::Range(start, end, include_end) => { - let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> { - let (c, c_ty) = match expr.kind { - hir::PatExprKind::Lit { lit, negated } => { - let lit_input = - LitToConstInput { lit: &lit.node, ty, neg: negated }; - let ct = tcx.lit_to_const(lit_input); - (ct, ty) - } - - hir::PatExprKind::Path(hir::QPath::Resolved( - _, - path @ &hir::Path { - res: Res::Def(DefKind::ConstParam, def_id), - .. - }, - )) => { - match self.prohibit_generic_args( - path.segments.iter(), - GenericsArgsErrExtend::Param(def_id), - ) { - Ok(()) => { - let ty = tcx - .type_of(def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); - let ct = self.lower_const_param(def_id, expr.hir_id); - (ct, ty) - } - Err(guar) => ( - ty::Const::new_error(tcx, guar), - Ty::new_error(tcx, guar), - ), - } - } - - _ => { - let err = tcx - .dcx() - .emit_err(crate::errors::NonConstRange { span: expr.span }); - (ty::Const::new_error(tcx, err), Ty::new_error(tcx, err)) - } - }; - self.record_ty(expr.hir_id, c_ty, expr.span); - c + hir::TyPatKind::Range(start, end, include_end) => { + let ty = match ty.kind() { + ty::Int(_) | ty::Uint(_) | ty::Char => ty, + _ => Ty::new_error( + tcx, + self.dcx().emit_err(InvalidBaseType { + ty, + pat: "range", + ty_span, + pat_span: pat.span, + }), + ), }; - - let start = start.map(expr_to_const); - let end = end.map(expr_to_const); + let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); + let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)); let include_end = match include_end { hir::RangeEnd::Included => true, @@ -2496,12 +2459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end }); Ty::new_pat(tcx, ty, pat) } - hir::PatKind::Err(e) => Ty::new_error(tcx, e), - _ => Ty::new_error_with_message( - tcx, - pat.span, - format!("unsupported pattern for pattern type: {pat:#?}"), - ), + hir::TyPatKind::Err(e) => Ty::new_error(tcx, e), }; self.record_ty(pat.hir_id, ty, pat.span); pat_ty diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index fd5a7089b4c..c30b39dfe76 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -62,7 +62,7 @@ pub(crate) fn check_impl_wf( // Check that the args are constrained. We queryfied the check for ty/const params // since unconstrained type/const params cause ICEs in projection, so we want to // detect those specifically and project those to `TyKind::Error`. - let mut res = tcx.ensure().enforce_impl_non_lifetime_params_are_constrained(impl_def_id); + let mut res = tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id); res = res.and(enforce_impl_lifetime_params_are_constrained(tcx, impl_def_id)); if tcx.features().min_specialization() { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index ae054a9eaeb..3af4318544e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -100,7 +100,7 @@ use rustc_middle::middle; use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits; pub use crate::collect::suggest_impl_trait; @@ -139,16 +139,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); tcx.sess.time("coherence_checking", || { + // When discarding query call results, use an explicit type to indicate + // what we are intending to discard, to help future type-based refactoring. + type R = Result<(), ErrorGuaranteed>; + tcx.hir().par_for_each_module(|module| { - let _ = tcx.ensure().check_mod_type_wf(module); + let _: R = tcx.ensure_ok().check_mod_type_wf(module); }); for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - let _ = tcx.ensure().coherent_trait(trait_def_id); + let _: R = tcx.ensure_ok().coherent_trait(trait_def_id); } // these queries are executed for side-effects (error reporting): - let _ = tcx.ensure().crate_inherent_impls_validity_check(()); - let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); + let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(()); + let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(()); }); if tcx.features().rustc_attrs() { @@ -167,12 +171,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { - DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id), + DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); - tcx.ensure().eval_to_const_value_raw(typing_env.as_query_input(cid)); + tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); } _ => (), } @@ -185,11 +189,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); if !matches!(def_kind, DefKind::AnonConst) { - tcx.ensure().typeck(item_def_id); + tcx.ensure_ok().typeck(item_def_id); } }); - tcx.ensure().check_unused_traits(()); + tcx.ensure_ok().check_unused_traits(()); } /// Lower a [`hir::Ty`] to a [`Ty`]. |
