summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check/check.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check/check.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs81
1 files changed, 42 insertions, 39 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 848828175..0bb98fdf2 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1,5 +1,5 @@
use crate::check::intrinsicck::InlineAsmCtxt;
-use crate::errors::LinkageType;
+use crate::errors::{self, LinkageType};
use super::compare_impl_item::check_type_bounds;
use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
@@ -22,12 +22,12 @@ use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{
- self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
- TypeVisitableExt,
+ self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym;
use rustc_span::{self, Span};
+use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@@ -115,9 +115,11 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
allowed_union_field(*elem, tcx, param_env)
}
_ => {
- // Fallback case: allow `ManuallyDrop` and things that are `Copy`.
+ // Fallback case: allow `ManuallyDrop` and things that are `Copy`,
+ // also no need to report an error if the type is unresolved.
ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
|| ty.is_copy_modulo_regions(tcx, param_env)
+ || ty.references_error()
}
}
}
@@ -132,26 +134,14 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
Some(Node::Field(field)) => (field.span, field.ty.span),
_ => unreachable!("mir field has to correspond to hir field"),
};
- struct_span_err!(
- tcx.sess,
+ tcx.sess.emit_err(errors::InvalidUnionField {
field_span,
- E0740,
- "unions cannot contain fields that may need dropping"
- )
- .note(
- "a type is guaranteed not to need dropping \
- when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type",
- )
- .multipart_suggestion_verbose(
- "when the type does not implement `Copy`, \
- wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped",
- vec![
- (ty_span.shrink_to_lo(), "std::mem::ManuallyDrop<".into()),
- (ty_span.shrink_to_hi(), ">".into()),
- ],
- Applicability::MaybeIncorrect,
- )
- .emit();
+ sugg: errors::InvalidUnionFieldSuggestion {
+ lo: ty_span.shrink_to_lo(),
+ hi: ty_span.shrink_to_hi(),
+ },
+ note: (),
+ });
return false;
} else if field_ty.needs_drop(tcx, param_env) {
// This should never happen. But we can get here e.g. in case of name resolution errors.
@@ -222,7 +212,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
return;
}
- let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id());
+ let substs = InternalSubsts::identity_for_item(tcx, item.owner_id);
let span = tcx.def_span(item.owner_id.def_id);
if !tcx.features().impl_trait_projections {
@@ -315,8 +305,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
..
}) = item.kind
{
- let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
- let opaque_identity_ty = if in_trait {
+ 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)
} else {
tcx.mk_opaque(def_id.to_def_id(), substs)
@@ -455,18 +445,15 @@ fn check_opaque_meets_bounds<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
- infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+ infcx.err_ctxt().report_fulfillment_errors(&errors);
}
match origin {
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
// Can have different predicates to their defining use
hir::OpaqueTyOrigin::TyAlias => {
- let outlives_environment = OutlivesEnvironment::new(param_env);
- let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(
- defining_use_anchor,
- &outlives_environment,
- );
+ let outlives_env = OutlivesEnvironment::new(param_env);
+ let _ = ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env);
}
}
// Clean up after ourselves
@@ -485,7 +472,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>(
let [var_one, var_two] = &adt_def.variants().raw[..] else {
return false;
};
- let (([], [field]) | ([field], [])) = (&var_one.fields[..], &var_two.fields[..]) else {
+ let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
return false;
};
matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..))
@@ -546,7 +533,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_substs =
- InternalSubsts::identity_for_item(tcx, id.owner_id.to_def_id());
+ InternalSubsts::identity_for_item(tcx, id.owner_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx,
assoc_item,
@@ -565,10 +552,18 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
check_union(tcx, id.owner_id.def_id);
}
DefKind::OpaqueTy => {
- check_opaque(tcx, id);
+ 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 hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
+ && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
+ {
+ // Skip opaques from RPIT in traits with no default body.
+ } else {
+ check_opaque(tcx, id);
+ }
}
DefKind::ImplTraitPlaceholder => {
- let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id());
+ let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
// Only check the validity of this opaque type if the function has a default body
if let hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
@@ -896,7 +891,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
return;
}
- let e = fields[0].ty(tcx, substs);
+ let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs);
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
.span_label(sp, "SIMD elements must have the same type")
@@ -1172,7 +1167,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
def.destructor(tcx); // force the destructor to be evaluated
if def.variants().is_empty() {
- if let Some(attr) = tcx.get_attrs(def_id.to_def_id(), sym::repr).next() {
+ if let Some(attr) = tcx.get_attrs(def_id, sym::repr).next() {
struct_span_err!(
tcx.sess,
attr.span,
@@ -1511,6 +1506,14 @@ fn opaque_type_cycle_error(
{
label_match(interior_ty.ty, interior_ty.span);
}
+ if tcx.sess.opts.unstable_opts.drop_tracking_mir
+ && let DefKind::Generator = tcx.def_kind(closure_def_id)
+ {
+ let generator_layout = tcx.mir_generator_witnesses(closure_def_id);
+ for interior_ty in &generator_layout.field_tys {
+ label_match(interior_ty.ty, interior_ty.source_info.span);
+ }
+ }
}
}
}
@@ -1548,6 +1551,6 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let errors = fulfillment_cx.select_all_or_error(&infcx);
debug!(?errors);
if !errors.is_empty() {
- infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+ infcx.err_ctxt().report_fulfillment_errors(&errors);
}
}