Skip to content

Commit

Permalink
Auto merge of #87029 - JohnTitor:rollup-0yapv7z, r=JohnTitor
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #87006 (Revert the revert of renaming traits::VTable to ImplSource)
 - #87011 (avoid reentrant lock acquire when ThreadIds run out)
 - #87013 (Fix several ICEs related to malformed `#[repr(...)]` attributes)
 - #87020 (remove const_raw_ptr_to_usize_cast feature)
 - #87028 (Fix type: `'satic` -> `'static`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 10, 2021
2 parents 3982eb3 + 36b142f commit a31431f
Show file tree
Hide file tree
Showing 44 changed files with 305 additions and 346 deletions.
104 changes: 96 additions & 8 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,23 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
sym::simd => Some(ReprSimd),
sym::transparent => Some(ReprTransparent),
sym::no_niche => Some(ReprNoNiche),
sym::align => {
let mut err = struct_span_err!(
diagnostic,
item.span(),
E0589,
"invalid `repr(align)` attribute: `align` needs an argument"
);
err.span_suggestion(
item.span(),
"supply an argument here",
"align(...)".to_string(),
Applicability::HasPlaceholders,
);
err.emit();
recognised = true;
None
}
name => int_type_of_word(name).map(ReprInt),
};

Expand All @@ -891,53 +908,124 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
Ok(literal) => acc.push(ReprPacked(literal)),
Err(message) => literal_error = Some(message),
};
} else if matches!(name, sym::C | sym::simd | sym::transparent | sym::no_niche)
|| int_type_of_word(name).is_some()
{
recognised = true;
struct_span_err!(
diagnostic,
item.span(),
E0552,
"invalid representation hint: `{}` does not take a parenthesized argument list",
name.to_ident_string(),
).emit();
}
if let Some(literal_error) = literal_error {
struct_span_err!(
diagnostic,
item.span(),
E0589,
"invalid `repr(align)` attribute: {}",
"invalid `repr({})` attribute: {}",
name.to_ident_string(),
literal_error
)
.emit();
}
} else if let Some(meta_item) = item.meta_item() {
if meta_item.has_name(sym::align) {
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
let name = meta_item.name_or_empty().to_ident_string();
recognised = true;
let mut err = struct_span_err!(
diagnostic,
item.span(),
E0693,
"incorrect `repr(align)` attribute format"
"incorrect `repr({})` attribute format",
name,
);
match value.kind {
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
err.span_suggestion(
item.span(),
"use parentheses instead",
format!("align({})", int),
format!("{}({})", name, int),
Applicability::MachineApplicable,
);
}
ast::LitKind::Str(s, _) => {
err.span_suggestion(
item.span(),
"use parentheses instead",
format!("align({})", s),
format!("{}({})", name, s),
Applicability::MachineApplicable,
);
}
_ => {}
}
err.emit();
} else {
if matches!(
meta_item.name_or_empty(),
sym::C | sym::simd | sym::transparent | sym::no_niche
) || int_type_of_word(meta_item.name_or_empty()).is_some()
{
recognised = true;
struct_span_err!(
diagnostic,
meta_item.span,
E0552,
"invalid representation hint: `{}` does not take a value",
meta_item.name_or_empty().to_ident_string(),
)
.emit();
}
}
} else if let MetaItemKind::List(_) = meta_item.kind {
if meta_item.has_name(sym::align) {
recognised = true;
struct_span_err!(
diagnostic,
meta_item.span,
E0693,
"incorrect `repr(align)` attribute format: \
`align` takes exactly one argument in parentheses"
)
.emit();
} else if meta_item.has_name(sym::packed) {
recognised = true;
struct_span_err!(
diagnostic,
meta_item.span,
E0552,
"incorrect `repr(packed)` attribute format: \
`packed` takes exactly one parenthesized argument, \
or no parentheses at all"
)
.emit();
} else if matches!(
meta_item.name_or_empty(),
sym::C | sym::simd | sym::transparent | sym::no_niche
) || int_type_of_word(meta_item.name_or_empty()).is_some()
{
recognised = true;
struct_span_err!(
diagnostic,
meta_item.span,
E0552,
"invalid representation hint: `{}` does not take a parenthesized argument list",
meta_item.name_or_empty().to_ident_string(),
).emit();
}
}
}
if !recognised {
// Not a word we recognize
diagnostic.delay_span_bug(item.span(), "unrecognized representation hint");
// Not a word we recognize. This will be caught and reported by
// the `check_mod_attrs` pass, but this pass doesn't always run
// (e.g. if we only pretty-print the source), so we have to gate
// the `delay_span_bug` call as follows:
if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
diagnostic.delay_span_bug(item.span(), "unrecognized representation hint");
}
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,9 +416,6 @@ declare_features! (
/// Allows accessing fields of unions inside `const` functions.
(active, const_fn_union, "1.27.0", Some(51909), None),

/// Allows casting raw pointers to `usize` during const eval.
(active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),

/// Allows dereferencing raw pointers during const eval.
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ declare_features! (
(removed, external_doc, "1.54.0", Some(44732), None,
Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),

/// Allows casting raw pointers to `usize` during const eval.
(removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),

// -------------------------------------------------------------------------
// feature-group-end: removed features
// -------------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,10 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
/// impl Clone for i32 { ... } // Impl_3
///
/// fn foo<T: Clone>(concrete: Option<Box<i32>>, param: T, mixed: Option<T>) {
/// // Case A: Vtable points at a specific impl. Only possible when
/// // Case A: ImplSource points at a specific impl. Only possible when
/// // type is concretely known. If the impl itself has bounded
/// // type parameters, Vtable will carry resolutions for those as well:
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
/// // type parameters, ImplSource will carry resolutions for those as well:
/// concrete.clone(); // ImpleSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])])
///
/// // Case A: ImplSource points at a specific impl. Only possible when
/// // type is concretely known. If the impl itself has bounded
Expand Down
25 changes: 15 additions & 10 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ impl NonConstOp for PanicNonStr {
}
}

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

/// Casting raw pointer or function pointer to an integer.
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
/// allocation base addresses that are not known at compile-time.
#[derive(Debug)]
pub struct RawPtrToIntCast;
impl NonConstOp for RawPtrToIntCast {
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_raw_ptr_to_usize_cast)
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_raw_ptr_to_usize_cast,
span,
&format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
)
let mut err = ccx
.tcx
.sess
.struct_span_err(span, "pointers cannot be cast to integers during const eval.");
err.note("at compile-time, pointers do not have an integer value");
err.note(
"avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior",
);
err
}
}

Expand Down
31 changes: 1 addition & 30 deletions compiler/rustc_mir/src/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_hir::intravisit;
use rustc_hir::Node;
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
Expand All @@ -18,7 +17,6 @@ use std::ops::Bound;
pub struct UnsafetyChecker<'a, 'tcx> {
body: &'a Body<'tcx>,
body_did: LocalDefId,
const_context: bool,
violations: Vec<UnsafetyViolation>,
source_info: SourceInfo,
tcx: TyCtxt<'tcx>,
Expand All @@ -30,7 +28,6 @@ pub struct UnsafetyChecker<'a, 'tcx> {

impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
fn new(
const_context: bool,
body: &'a Body<'tcx>,
body_did: LocalDefId,
tcx: TyCtxt<'tcx>,
Expand All @@ -39,7 +36,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
Self {
body,
body_did,
const_context,
violations: vec![],
source_info: SourceInfo::outermost(body.span),
tcx,
Expand Down Expand Up @@ -136,25 +132,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
self.register_violations(&violations, &unsafe_blocks);
}
},
// casting pointers to ints is unsafe in const fn because the const evaluator cannot
// possibly know what the result of various operations like `address / 2` would be
// pointers during const evaluation have no integral address, only an abstract one
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty)
if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast =>
{
let operand_ty = operand.ty(self.body, self.tcx);
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
match (cast_in, cast_out) {
(CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
self.require_unsafe(
UnsafetyViolationKind::General,
UnsafetyViolationDetails::CastOfPointerToInt,
);
}
_ => {}
}
}
_ => {}
}
self.super_rvalue(rvalue, location);
Expand Down Expand Up @@ -469,13 +446,7 @@ fn unsafety_check_result<'tcx>(

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

let id = tcx.hir().local_def_id_to_hir_id(def.did);
let const_context = match tcx.hir().body_owner_kind(id) {
hir::BodyOwnerKind::Closure => false,
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
};
let mut checker = UnsafetyChecker::new(const_context, body, def.did, tcx, param_env);
let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env);
checker.visit_body(&body);

check_unused_unsafe(tcx, def.did, &checker.used_unsafe, &mut checker.inherited_blocks);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl Inliner<'tcx> {
&self,
callsite: &CallSite<'tcx>,
callee_attrs: &CodegenFnAttrs,
) -> Result<(), &'satic str> {
) -> Result<(), &'static str> {
if let InlineAttr::Never = callee_attrs.inline {
return Err("never inline hint");
}
Expand Down
21 changes: 0 additions & 21 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ struct UnsafetyVisitor<'a, 'tcx> {
/// The `#[target_feature]` attributes of the body. Used for checking
/// calls to functions with `#[target_feature]` (RFC 2396).
body_target_features: &'tcx Vec<Symbol>,
is_const: bool,
in_possible_lhs_union_assign: bool,
in_union_destructure: bool,
}
Expand Down Expand Up @@ -315,16 +314,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
(Bound::Unbounded, Bound::Unbounded) => {}
_ => self.requires_unsafe(expr.span, InitializingTypeWith),
},
ExprKind::Cast { source } => {
let source = &self.thir[source];
if self.tcx.features().const_raw_ptr_to_usize_cast
&& self.is_const
&& (source.ty.is_unsafe_ptr() || source.ty.is_fn_ptr())
&& expr.ty.is_integral()
{
self.requires_unsafe(expr.span, CastOfPointerToInt);
}
}
ExprKind::Closure {
closure_id,
substs: _,
Expand Down Expand Up @@ -413,7 +402,6 @@ enum UnsafeOpKind {
CallToUnsafeFunction,
UseOfInlineAssembly,
InitializingTypeWith,
CastOfPointerToInt,
UseOfMutableStatic,
UseOfExternStatic,
DerefOfRawPointer,
Expand Down Expand Up @@ -446,9 +434,6 @@ impl UnsafeOpKind {
"initializing a layout restricted type's field with a value outside the valid \
range is undefined behavior",
),
CastOfPointerToInt => {
("cast of pointer to int", "casting pointers to integers in constants")
}
UseOfMutableStatic => (
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing violations or data \
Expand Down Expand Up @@ -526,19 +511,13 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
let body_target_features = &tcx.codegen_fn_attrs(def.did).target_features;
let safety_context =
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
let is_const = match tcx.hir().body_owner_kind(hir_id) {
hir::BodyOwnerKind::Closure => false,
hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
};
let mut visitor = UnsafetyVisitor {
tcx,
thir,
safety_context,
hir_context: hir_id,
body_unsafety,
body_target_features,
is_const,
in_possible_lhs_union_assign: false,
in_union_destructure: false,
};
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,11 +999,12 @@ impl ThreadId {
static mut COUNTER: u64 = 1;

unsafe {
let _guard = GUARD.lock();
let guard = GUARD.lock();

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

Expand Down
Loading

0 comments on commit a31431f

Please sign in to comment.