Auto merge of #136965 - jhpratt:rollup-bsnqvmf, r=jhpratt
Rollup of 8 pull requests Successful merges: - #134999 (Add cygwin target.) - #136559 (Resolve named regions when reporting type test failures in NLL) - #136660 (Use a trait to enforce field validity for union fields + `unsafe` fields + `unsafe<>` binder types) - #136858 (Parallel-compiler-related cleanup) - #136881 (cg_llvm: Reduce visibility of all functions in the llvm module) - #136888 (Always perform discr read for never pattern in EUV) - #136948 (Split out the `extern_system_varargs` feature) - #136949 (Fix import in bench for wasm) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
54cdc751df
71 changed files with 1231 additions and 790 deletions
|
@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
|
|||
use rustc_errors::MultiSpan;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::{Node, intravisit};
|
||||
use rustc_hir::{LangItem, Node, intravisit};
|
||||
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
|
||||
use rustc_infer::traits::{Obligation, ObligationCauseCode};
|
||||
use rustc_lint_defs::builtin::{
|
||||
|
@ -27,6 +27,7 @@ use rustc_session::lint::builtin::UNINHABITED_STATIC;
|
|||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use tracing::{debug, instrument};
|
||||
use ty::TypingMode;
|
||||
|
@ -87,89 +88,76 @@ fn allowed_union_or_unsafe_field<'tcx>(
|
|||
typing_env: ty::TypingEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
// We don't just accept all !needs_drop fields, due to semver concerns.
|
||||
let allowed = match ty.kind() {
|
||||
ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
|
||||
ty::Tuple(tys) => {
|
||||
// allow tuples of allowed types
|
||||
tys.iter().all(|ty| allowed_union_or_unsafe_field(tcx, ty, typing_env, span))
|
||||
}
|
||||
ty::Array(elem, _len) => {
|
||||
// Like `Copy`, we do *not* special-case length 0.
|
||||
allowed_union_or_unsafe_field(tcx, *elem, typing_env, span)
|
||||
}
|
||||
_ => {
|
||||
// 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())
|
||||
|| tcx.type_is_copy_modulo_regions(typing_env, ty)
|
||||
|| ty.references_error()
|
||||
}
|
||||
};
|
||||
if allowed && ty.needs_drop(tcx, typing_env) {
|
||||
// This should never happen. But we can get here e.g. in case of name resolution errors.
|
||||
tcx.dcx()
|
||||
.span_delayed_bug(span, "we should never accept maybe-dropping union or unsafe fields");
|
||||
// HACK (not that bad of a hack don't worry): Some codegen tests don't even define proper
|
||||
// impls for `Copy`. Let's short-circuit here for this validity check, since a lot of them
|
||||
// use unions. We should eventually fix all the tests to define that lang item or use
|
||||
// minicore stubs.
|
||||
if ty.is_trivially_pure_clone_copy() {
|
||||
return true;
|
||||
}
|
||||
allowed
|
||||
// If `BikeshedGuaranteedNoDrop` is not defined in a `#[no_core]` test, fall back to `Copy`.
|
||||
// This is an underapproximation of `BikeshedGuaranteedNoDrop`,
|
||||
let def_id = tcx
|
||||
.lang_items()
|
||||
.get(LangItem::BikeshedGuaranteedNoDrop)
|
||||
.unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, Some(span)));
|
||||
let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else {
|
||||
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
|
||||
return true;
|
||||
};
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
infcx.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(span),
|
||||
param_env,
|
||||
ty::TraitRef::new(tcx, def_id, [ty]),
|
||||
))
|
||||
}
|
||||
|
||||
/// Check that the fields of the `union` do not need dropping.
|
||||
fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
|
||||
let item_type = tcx.type_of(item_def_id).instantiate_identity();
|
||||
if let ty::Adt(def, args) = item_type.kind() {
|
||||
assert!(def.is_union());
|
||||
let def = tcx.adt_def(item_def_id);
|
||||
assert!(def.is_union());
|
||||
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
|
||||
for field in &def.non_enum_variant().fields {
|
||||
let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
|
||||
else {
|
||||
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
|
||||
continue;
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
|
||||
|
||||
for field in &def.non_enum_variant().fields {
|
||||
if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
|
||||
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
||||
// We are currently checking the type this field came from, so it must be local.
|
||||
Some(Node::Field(field)) => (field.span, field.ty.span),
|
||||
_ => unreachable!("mir field has to correspond to hir field"),
|
||||
};
|
||||
|
||||
if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) {
|
||||
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
|
||||
// We are currently checking the type this field came from, so it must be local.
|
||||
Some(Node::Field(field)) => (field.span, field.ty.span),
|
||||
_ => unreachable!("mir field has to correspond to hir field"),
|
||||
};
|
||||
tcx.dcx().emit_err(errors::InvalidUnionField {
|
||||
field_span,
|
||||
sugg: errors::InvalidUnionFieldSuggestion {
|
||||
lo: ty_span.shrink_to_lo(),
|
||||
hi: ty_span.shrink_to_hi(),
|
||||
},
|
||||
note: (),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
tcx.dcx().emit_err(errors::InvalidUnionField {
|
||||
field_span,
|
||||
sugg: errors::InvalidUnionFieldSuggestion {
|
||||
lo: ty_span.shrink_to_lo(),
|
||||
hi: ty_span.shrink_to_hi(),
|
||||
},
|
||||
note: (),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind());
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Check that the unsafe fields do not need dropping.
|
||||
fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
|
||||
let span = tcx.def_span(item_def_id);
|
||||
let item_type = tcx.type_of(item_def_id).instantiate_identity();
|
||||
let ty::Adt(def, args) = item_type.kind() else {
|
||||
span_bug!(span, "structs/enums must be ty::Adt, but got {:?}", item_type.kind());
|
||||
};
|
||||
let def = tcx.adt_def(item_def_id);
|
||||
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
|
||||
|
||||
for field in def.all_fields() {
|
||||
if !field.safety.is_unsafe() {
|
||||
continue;
|
||||
}
|
||||
let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
|
||||
else {
|
||||
tcx.dcx().span_delayed_bug(span, "could not normalize field type");
|
||||
continue;
|
||||
};
|
||||
|
||||
if !allowed_union_or_unsafe_field(tcx, field_ty, typing_env, span) {
|
||||
if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
|
||||
let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
|
||||
unreachable!("field has to correspond to hir field")
|
||||
};
|
||||
|
|
|
@ -122,28 +122,42 @@ fn require_c_abi_if_c_variadic(
|
|||
const UNSTABLE_EXPLAIN: &str =
|
||||
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
|
||||
|
||||
// ABIs which can stably use varargs
|
||||
if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ABIs with feature-gated stability
|
||||
let extended_abi_support = tcx.features().extended_varargs_abi_support();
|
||||
let conventions = match (extended_abi_support, abi.supports_varargs()) {
|
||||
// User enabled additional ABI support for varargs and function ABI matches those ones.
|
||||
(true, true) => return,
|
||||
let extern_system_varargs = tcx.features().extern_system_varargs();
|
||||
|
||||
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
|
||||
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
|
||||
(false, true) => {
|
||||
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
|
||||
.emit();
|
||||
CONVENTIONS_STABLE
|
||||
}
|
||||
|
||||
(false, false) => CONVENTIONS_STABLE,
|
||||
(true, false) => CONVENTIONS_UNSTABLE,
|
||||
// If the feature gate has been enabled, we can stop here
|
||||
if extern_system_varargs && let ExternAbi::System { .. } = abi {
|
||||
return;
|
||||
};
|
||||
if extended_abi_support && abi.supports_varargs() {
|
||||
return;
|
||||
};
|
||||
|
||||
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
|
||||
// Looks like we need to pick an error to emit.
|
||||
// Is there any feature which we could have enabled to make this work?
|
||||
match abi {
|
||||
ExternAbi::System { .. } => {
|
||||
feature_err(&tcx.sess, sym::extern_system_varargs, span, UNSTABLE_EXPLAIN)
|
||||
}
|
||||
abi if abi.supports_varargs() => {
|
||||
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
|
||||
}
|
||||
_ => tcx.dcx().create_err(errors::VariadicFunctionCompatibleConvention {
|
||||
span,
|
||||
conventions: if tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||
CONVENTIONS_UNSTABLE
|
||||
} else {
|
||||
CONVENTIONS_STABLE
|
||||
},
|
||||
}),
|
||||
}
|
||||
.emit();
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue