Skip to content

Commit a31431f

Browse files
committed
Auto merge of rust-lang#87029 - JohnTitor:rollup-0yapv7z, r=JohnTitor
Rollup of 5 pull requests Successful merges: - rust-lang#87006 (Revert the revert of renaming traits::VTable to ImplSource) - rust-lang#87011 (avoid reentrant lock acquire when ThreadIds run out) - rust-lang#87013 (Fix several ICEs related to malformed `#[repr(...)]` attributes) - rust-lang#87020 (remove const_raw_ptr_to_usize_cast feature) - rust-lang#87028 (Fix type: `'satic` -> `'static`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3982eb3 + 36b142f commit a31431f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+305
-346
lines changed

compiler/rustc_attr/src/builtin.rs

+96-8
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,23 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
870870
sym::simd => Some(ReprSimd),
871871
sym::transparent => Some(ReprTransparent),
872872
sym::no_niche => Some(ReprNoNiche),
873+
sym::align => {
874+
let mut err = struct_span_err!(
875+
diagnostic,
876+
item.span(),
877+
E0589,
878+
"invalid `repr(align)` attribute: `align` needs an argument"
879+
);
880+
err.span_suggestion(
881+
item.span(),
882+
"supply an argument here",
883+
"align(...)".to_string(),
884+
Applicability::HasPlaceholders,
885+
);
886+
err.emit();
887+
recognised = true;
888+
None
889+
}
873890
name => int_type_of_word(name).map(ReprInt),
874891
};
875892

@@ -891,53 +908,124 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
891908
Ok(literal) => acc.push(ReprPacked(literal)),
892909
Err(message) => literal_error = Some(message),
893910
};
911+
} else if matches!(name, sym::C | sym::simd | sym::transparent | sym::no_niche)
912+
|| int_type_of_word(name).is_some()
913+
{
914+
recognised = true;
915+
struct_span_err!(
916+
diagnostic,
917+
item.span(),
918+
E0552,
919+
"invalid representation hint: `{}` does not take a parenthesized argument list",
920+
name.to_ident_string(),
921+
).emit();
894922
}
895923
if let Some(literal_error) = literal_error {
896924
struct_span_err!(
897925
diagnostic,
898926
item.span(),
899927
E0589,
900-
"invalid `repr(align)` attribute: {}",
928+
"invalid `repr({})` attribute: {}",
929+
name.to_ident_string(),
901930
literal_error
902931
)
903932
.emit();
904933
}
905934
} else if let Some(meta_item) = item.meta_item() {
906-
if meta_item.has_name(sym::align) {
907-
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
935+
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
936+
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
937+
let name = meta_item.name_or_empty().to_ident_string();
908938
recognised = true;
909939
let mut err = struct_span_err!(
910940
diagnostic,
911941
item.span(),
912942
E0693,
913-
"incorrect `repr(align)` attribute format"
943+
"incorrect `repr({})` attribute format",
944+
name,
914945
);
915946
match value.kind {
916947
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
917948
err.span_suggestion(
918949
item.span(),
919950
"use parentheses instead",
920-
format!("align({})", int),
951+
format!("{}({})", name, int),
921952
Applicability::MachineApplicable,
922953
);
923954
}
924955
ast::LitKind::Str(s, _) => {
925956
err.span_suggestion(
926957
item.span(),
927958
"use parentheses instead",
928-
format!("align({})", s),
959+
format!("{}({})", name, s),
929960
Applicability::MachineApplicable,
930961
);
931962
}
932963
_ => {}
933964
}
934965
err.emit();
966+
} else {
967+
if matches!(
968+
meta_item.name_or_empty(),
969+
sym::C | sym::simd | sym::transparent | sym::no_niche
970+
) || int_type_of_word(meta_item.name_or_empty()).is_some()
971+
{
972+
recognised = true;
973+
struct_span_err!(
974+
diagnostic,
975+
meta_item.span,
976+
E0552,
977+
"invalid representation hint: `{}` does not take a value",
978+
meta_item.name_or_empty().to_ident_string(),
979+
)
980+
.emit();
981+
}
982+
}
983+
} else if let MetaItemKind::List(_) = meta_item.kind {
984+
if meta_item.has_name(sym::align) {
985+
recognised = true;
986+
struct_span_err!(
987+
diagnostic,
988+
meta_item.span,
989+
E0693,
990+
"incorrect `repr(align)` attribute format: \
991+
`align` takes exactly one argument in parentheses"
992+
)
993+
.emit();
994+
} else if meta_item.has_name(sym::packed) {
995+
recognised = true;
996+
struct_span_err!(
997+
diagnostic,
998+
meta_item.span,
999+
E0552,
1000+
"incorrect `repr(packed)` attribute format: \
1001+
`packed` takes exactly one parenthesized argument, \
1002+
or no parentheses at all"
1003+
)
1004+
.emit();
1005+
} else if matches!(
1006+
meta_item.name_or_empty(),
1007+
sym::C | sym::simd | sym::transparent | sym::no_niche
1008+
) || int_type_of_word(meta_item.name_or_empty()).is_some()
1009+
{
1010+
recognised = true;
1011+
struct_span_err!(
1012+
diagnostic,
1013+
meta_item.span,
1014+
E0552,
1015+
"invalid representation hint: `{}` does not take a parenthesized argument list",
1016+
meta_item.name_or_empty().to_ident_string(),
1017+
).emit();
9351018
}
9361019
}
9371020
}
9381021
if !recognised {
939-
// Not a word we recognize
940-
diagnostic.delay_span_bug(item.span(), "unrecognized representation hint");
1022+
// Not a word we recognize. This will be caught and reported by
1023+
// the `check_mod_attrs` pass, but this pass doesn't always run
1024+
// (e.g. if we only pretty-print the source), so we have to gate
1025+
// the `delay_span_bug` call as follows:
1026+
if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
1027+
diagnostic.delay_span_bug(item.span(), "unrecognized representation hint");
1028+
}
9411029
}
9421030
}
9431031
}

compiler/rustc_feature/src/active.rs

-3
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,6 @@ declare_features! (
416416
/// Allows accessing fields of unions inside `const` functions.
417417
(active, const_fn_union, "1.27.0", Some(51909), None),
418418

419-
/// Allows casting raw pointers to `usize` during const eval.
420-
(active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
421-
422419
/// Allows dereferencing raw pointers during const eval.
423420
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
424421

compiler/rustc_feature/src/removed.rs

+4
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ declare_features! (
144144
(removed, external_doc, "1.54.0", Some(44732), None,
145145
Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
146146

147+
/// Allows casting raw pointers to `usize` during const eval.
148+
(removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
149+
Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
150+
147151
// -------------------------------------------------------------------------
148152
// feature-group-end: removed features
149153
// -------------------------------------------------------------------------

compiler/rustc_middle/src/traits/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,10 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
426426
/// impl Clone for i32 { ... } // Impl_3
427427
///
428428
/// fn foo<T: Clone>(concrete: Option<Box<i32>>, param: T, mixed: Option<T>) {
429-
/// // Case A: Vtable points at a specific impl. Only possible when
429+
/// // Case A: ImplSource points at a specific impl. Only possible when
430430
/// // type is concretely known. If the impl itself has bounded
431-
/// // type parameters, Vtable will carry resolutions for those as well:
432-
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
431+
/// // type parameters, ImplSource will carry resolutions for those as well:
432+
/// concrete.clone(); // ImpleSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
433433
///
434434
/// // Case A: ImplSource points at a specific impl. Only possible when
435435
/// // type is concretely known. If the impl itself has bounded

compiler/rustc_mir/src/transform/check_consts/ops.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ impl NonConstOp for PanicNonStr {
397397
}
398398
}
399399

400+
/// Comparing raw pointers for equality.
401+
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
402+
/// allocation base addresses that are not known at compile-time.
400403
#[derive(Debug)]
401404
pub struct RawPtrComparison;
402405
impl NonConstOp for RawPtrComparison {
@@ -430,20 +433,22 @@ impl NonConstOp for RawPtrDeref {
430433
}
431434
}
432435

436+
/// Casting raw pointer or function pointer to an integer.
437+
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
438+
/// allocation base addresses that are not known at compile-time.
433439
#[derive(Debug)]
434440
pub struct RawPtrToIntCast;
435441
impl NonConstOp for RawPtrToIntCast {
436-
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
437-
Status::Unstable(sym::const_raw_ptr_to_usize_cast)
438-
}
439-
440442
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
441-
feature_err(
442-
&ccx.tcx.sess.parse_sess,
443-
sym::const_raw_ptr_to_usize_cast,
444-
span,
445-
&format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
446-
)
443+
let mut err = ccx
444+
.tcx
445+
.sess
446+
.struct_span_err(span, "pointers cannot be cast to integers during const eval.");
447+
err.note("at compile-time, pointers do not have an integer value");
448+
err.note(
449+
"avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior",
450+
);
451+
err
447452
}
448453
}
449454

compiler/rustc_mir/src/transform/check_unsafety.rs

+1-30
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_hir::intravisit;
77
use rustc_hir::Node;
88
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
99
use rustc_middle::mir::*;
10-
use rustc_middle::ty::cast::CastTy;
1110
use rustc_middle::ty::query::Providers;
1211
use rustc_middle::ty::{self, TyCtxt};
1312
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
@@ -18,7 +17,6 @@ use std::ops::Bound;
1817
pub struct UnsafetyChecker<'a, 'tcx> {
1918
body: &'a Body<'tcx>,
2019
body_did: LocalDefId,
21-
const_context: bool,
2220
violations: Vec<UnsafetyViolation>,
2321
source_info: SourceInfo,
2422
tcx: TyCtxt<'tcx>,
@@ -30,7 +28,6 @@ pub struct UnsafetyChecker<'a, 'tcx> {
3028

3129
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
3230
fn new(
33-
const_context: bool,
3431
body: &'a Body<'tcx>,
3532
body_did: LocalDefId,
3633
tcx: TyCtxt<'tcx>,
@@ -39,7 +36,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
3936
Self {
4037
body,
4138
body_did,
42-
const_context,
4339
violations: vec![],
4440
source_info: SourceInfo::outermost(body.span),
4541
tcx,
@@ -136,25 +132,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
136132
self.register_violations(&violations, &unsafe_blocks);
137133
}
138134
},
139-
// casting pointers to ints is unsafe in const fn because the const evaluator cannot
140-
// possibly know what the result of various operations like `address / 2` would be
141-
// pointers during const evaluation have no integral address, only an abstract one
142-
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty)
143-
if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast =>
144-
{
145-
let operand_ty = operand.ty(self.body, self.tcx);
146-
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
147-
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
148-
match (cast_in, cast_out) {
149-
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
150-
self.require_unsafe(
151-
UnsafetyViolationKind::General,
152-
UnsafetyViolationDetails::CastOfPointerToInt,
153-
);
154-
}
155-
_ => {}
156-
}
157-
}
158135
_ => {}
159136
}
160137
self.super_rvalue(rvalue, location);
@@ -469,13 +446,7 @@ fn unsafety_check_result<'tcx>(
469446

470447
let param_env = tcx.param_env(def.did);
471448

472-
let id = tcx.hir().local_def_id_to_hir_id(def.did);
473-
let const_context = match tcx.hir().body_owner_kind(id) {
474-
hir::BodyOwnerKind::Closure => false,
475-
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
476-
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
477-
};
478-
let mut checker = UnsafetyChecker::new(const_context, body, def.did, tcx, param_env);
449+
let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env);
479450
checker.visit_body(&body);
480451

481452
check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks);

compiler/rustc_mir/src/transform/inline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ impl Inliner<'tcx> {
284284
&self,
285285
callsite: &CallSite<'tcx>,
286286
callee_attrs: &CodegenFnAttrs,
287-
) -> Result<(), &'satic str> {
287+
) -> Result<(), &'static str> {
288288
if let InlineAttr::Never = callee_attrs.inline {
289289
return Err("never inline hint");
290290
}

compiler/rustc_mir_build/src/check_unsafety.rs

-21
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ struct UnsafetyVisitor<'a, 'tcx> {
2525
/// The `#[target_feature]` attributes of the body. Used for checking
2626
/// calls to functions with `#[target_feature]` (RFC 2396).
2727
body_target_features: &'tcx Vec<Symbol>,
28-
is_const: bool,
2928
in_possible_lhs_union_assign: bool,
3029
in_union_destructure: bool,
3130
}
@@ -315,16 +314,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
315314
(Bound::Unbounded, Bound::Unbounded) => {}
316315
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
317316
},
318-
ExprKind::Cast { source } => {
319-
let source = &self.thir[source];
320-
if self.tcx.features().const_raw_ptr_to_usize_cast
321-
&& self.is_const
322-
&& (source.ty.is_unsafe_ptr() || source.ty.is_fn_ptr())
323-
&& expr.ty.is_integral()
324-
{
325-
self.requires_unsafe(expr.span, CastOfPointerToInt);
326-
}
327-
}
328317
ExprKind::Closure {
329318
closure_id,
330319
substs: _,
@@ -413,7 +402,6 @@ enum UnsafeOpKind {
413402
CallToUnsafeFunction,
414403
UseOfInlineAssembly,
415404
InitializingTypeWith,
416-
CastOfPointerToInt,
417405
UseOfMutableStatic,
418406
UseOfExternStatic,
419407
DerefOfRawPointer,
@@ -446,9 +434,6 @@ impl UnsafeOpKind {
446434
"initializing a layout restricted type's field with a value outside the valid \
447435
range is undefined behavior",
448436
),
449-
CastOfPointerToInt => {
450-
("cast of pointer to int", "casting pointers to integers in constants")
451-
}
452437
UseOfMutableStatic => (
453438
"use of mutable static",
454439
"mutable statics can be mutated by multiple threads: aliasing violations or data \
@@ -526,19 +511,13 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
526511
let body_target_features = &tcx.codegen_fn_attrs(def.did).target_features;
527512
let safety_context =
528513
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
529-
let is_const = match tcx.hir().body_owner_kind(hir_id) {
530-
hir::BodyOwnerKind::Closure => false,
531-
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
532-
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
533-
};
534514
let mut visitor = UnsafetyVisitor {
535515
tcx,
536516
thir,
537517
safety_context,
538518
hir_context: hir_id,
539519
body_unsafety,
540520
body_target_features,
541-
is_const,
542521
in_possible_lhs_union_assign: false,
543522
in_union_destructure: false,
544523
};

library/std/src/thread/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -999,11 +999,12 @@ impl ThreadId {
999999
static mut COUNTER: u64 = 1;
10001000

10011001
unsafe {
1002-
let _guard = GUARD.lock();
1002+
let guard = GUARD.lock();
10031003

10041004
// If we somehow use up all our bits, panic so that we're not
10051005
// covering up subtle bugs of IDs being reused.
10061006
if COUNTER == u64::MAX {
1007+
drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
10071008
panic!("failed to generate unique thread ID: bitspace exhausted");
10081009
}
10091010

0 commit comments

Comments
 (0)