Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
.collect()
}
}

pub(crate) struct RustcNonConstTraitMethodParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
Expand Down Expand Up @@ -722,6 +723,19 @@ impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
}
}

pub(crate) struct RustcInsignificantDtorParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcInsignificantDtorParser {
const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Enum),
Allow(Target::Struct),
Allow(Target::ForeignTy),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcInsignificantDtor;
}

pub(crate) struct RustcEffectiveVisibilityParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
Expand Down Expand Up @@ -810,3 +824,29 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDefPath {
Some(AttributeKind::RustcDefPath(cx.attr_span))
}
}

pub(crate) struct RustcReservationImplParser;

impl<S: Stage> SingleAttributeParser<S> for RustcReservationImplParser {
const PATH: &[Symbol] = &[sym::rustc_reservation_impl];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]);

const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(nv) = args.name_value() else {
cx.expected_name_value(args.span().unwrap_or(cx.attr_span), None);
return None;
};

let Some(value_str) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};

Some(AttributeKind::RustcReservationImpl(cx.attr_span, value_str))
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ attribute_parsers!(
Single<RustcLintOptDenyFieldAccessParser>,
Single<RustcMustImplementOneOfParser>,
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcReservationImplParser>,
Single<RustcScalableVectorParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<RustcSymbolName>,
Expand Down Expand Up @@ -264,6 +265,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcEffectiveVisibilityParser>>,
Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,
Single<WithoutArgs<RustcHiddenTypeOfOpaquesParser>>,
Single<WithoutArgs<RustcInsignificantDtorParser>>,
Single<WithoutArgs<RustcLintOptTyParser>>,
Single<WithoutArgs<RustcLintQueryInstabilityParser>>,
Single<WithoutArgs<RustcLintUntrackedQueryInformationParser>>,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_if_this_changed]`
RustcIfThisChanged(Span, Option<Symbol>),

/// Represents `#[rustc_insignificant_dtor]`
RustcInsignificantDtor,

/// Represents `#[rustc_layout]`
RustcLayout(ThinVec<RustcLayoutType>),

Expand Down Expand Up @@ -1198,6 +1201,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_reallocator]`
RustcReallocator,

/// Represents `#[rustc_reservation_impl]`
RustcReservationImpl(Span, Symbol),

/// Represents `#[rustc_scalable_vector(N)]`
RustcScalableVector {
/// The base multiple of lanes that are in a scalable vector, if provided. `element_count`
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl AttributeKind {
RustcHasIncoherentInherentImpls => Yes,
RustcHiddenTypeOfOpaques => No,
RustcIfThisChanged(..) => No,
RustcInsignificantDtor => Yes,
RustcLayout(..) => No,
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
Expand All @@ -144,6 +145,7 @@ impl AttributeKind {
RustcPreserveUbChecks => No,
RustcPubTransparent(..) => Yes,
RustcReallocator => No,
RustcReservationImpl(..) => Yes,
RustcScalableVector { .. } => Yes,
RustcShouldNotBeCalledOnConstItems(..) => Yes,
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,8 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
.of_trait
.unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}"));
let selfty = tcx.type_of(def_id).instantiate_identity();
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
let is_rustc_reservation =
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(..));

check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcHasIncoherentInherentImpls
| AttributeKind::RustcHiddenTypeOfOpaques
| AttributeKind::RustcIfThisChanged(..)
| AttributeKind::RustcInsignificantDtor
| AttributeKind::RustcLayout(..)
| AttributeKind::RustcLayoutScalarValidRangeEnd(..)
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
Expand All @@ -335,6 +336,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
| AttributeKind::RustcPreserveUbChecks
| AttributeKind::RustcReallocator
| AttributeKind::RustcReservationImpl(..)
| AttributeKind::RustcScalableVector { .. }
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
Expand Down Expand Up @@ -383,15 +385,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::default_lib_allocator
| sym::rustc_diagnostic_item
| sym::rustc_no_mir_inline
| sym::rustc_insignificant_dtor
| sym::rustc_nonnull_optimization_guaranteed
| sym::rustc_intrinsic
| sym::rustc_inherit_overflow_checks
| sym::rustc_intrinsic_const_stable_indirect
| sym::rustc_trivial_field_reads
| sym::rustc_on_unimplemented
| sym::rustc_do_not_const_check
| sym::rustc_reservation_impl
| sym::rustc_doc_primitive
| sym::rustc_conversion_suggestion
| sym::rustc_deprecated_safe_2024
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use std::fmt::Debug;

use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::find_attr;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::PredicateObligations;
use rustc_macros::{TypeFoldable, TypeVisitable};
Expand All @@ -23,7 +25,7 @@ use rustc_middle::ty::{
};
pub use rustc_next_trait_solver::coherence::*;
use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
use rustc_span::{DUMMY_SP, Span, sym};
use rustc_span::{DUMMY_SP, Span};
use tracing::{debug, instrument, warn};

use super::ObligationCtxt;
Expand Down Expand Up @@ -758,10 +760,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
} = cand.kind()
&& let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
{
let message = infcx
.tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
let message = find_attr!(infcx.tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
if let Some(message) = message {
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
}
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use rustc_data_structures::assert_matches;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::LangItem;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem, find_attr};
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::at::ToTrace;
Expand All @@ -33,7 +33,7 @@ use rustc_middle::ty::{
may_use_unstable_feature,
};
use rustc_next_trait_solver::solve::AliasBoundKind;
use rustc_span::{Symbol, sym};
use rustc_span::Symbol;
use tracing::{debug, instrument, trace};

use self::EvaluationResult::*;
Expand Down Expand Up @@ -1445,8 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&& let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
{
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
let message =
tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
let message = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
if let Some(message) = message {
debug!(
"filter_reservation_impls: \
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ty_utils/src/needs_drop.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! Check whether a type has (potentially) non-trivial drop glue.

use rustc_data_structures::fx::FxHashSet;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::DefId;
use rustc_hir::find_attr;
use rustc_hir::limit::Limit;
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components};
use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt};
use rustc_span::sym;
use tracing::{debug, instrument};

use crate::errors::NeedsDropOverflow;
Expand Down Expand Up @@ -396,8 +397,7 @@ fn adt_consider_insignificant_dtor<'tcx>(
tcx: TyCtxt<'tcx>,
) -> impl Fn(ty::AdtDef<'tcx>) -> Option<DtorType> {
move |adt_def: ty::AdtDef<'tcx>| {
let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor);
if is_marked_insig {
if find_attr!(tcx.get_all_attrs(adt_def.did()), AttributeKind::RustcInsignificantDtor) {
// In some cases like `std::collections::HashMap` where the struct is a wrapper around
// a type that is a Drop type, and the wrapped type (eg: `hashbrown::HashMap`) lies
// outside stdlib, we might choose to still annotate the wrapper (std HashMap) with
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ use crate::vec::Vec;
/// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[rustc_diagnostic_item = "cstring_type"]
#[rustc_insignificant_dtor]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct CString {
// Invariant 1: the slice ends with a zero byte and has a length of at least one.
Expand Down Expand Up @@ -694,7 +695,6 @@ impl CString {
// memory-unsafe code from working by accident. Inline
// to prevent LLVM from optimizing it away in debug builds.
#[stable(feature = "cstring_drop", since = "1.13.0")]
#[rustc_insignificant_dtor]
impl Drop for CString {
#[inline]
fn drop(&mut self) {
Expand Down
48 changes: 31 additions & 17 deletions library/std/src/sync/poison/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,36 @@ use crate::sys::sync as sys;
/// # Examples
///
/// ```
/// use std::sync::RwLock;
/// use std::sync::{Arc, RwLock};
/// use std::thread;
/// use std::time::Duration;
///
/// let lock = RwLock::new(5);
/// let data = Arc::new(RwLock::new(5));
///
/// // many reader locks can be held at once
/// {
/// let r1 = lock.read().unwrap();
/// let r2 = lock.read().unwrap();
/// assert_eq!(*r1, 5);
/// assert_eq!(*r2, 5);
/// } // read locks are dropped at this point
/// // Multiple readers can access in parallel.
/// for i in 0..3 {
/// let lock_clone = Arc::clone(&data);
///
/// // only one write lock may be held, however
/// {
/// let mut w = lock.write().unwrap();
/// *w += 1;
/// assert_eq!(*w, 6);
/// } // write lock is dropped here
/// thread::spawn(move || {
/// let value = lock_clone.read().unwrap();
///
/// println!("Reader {}: Read value {}, now holding lock...", i, *value);
///
/// // Simulating a long read operation
/// thread::sleep(Duration::from_secs(1));
///
/// println!("Reader {}: Dropping lock.", i);
/// // Read lock unlocked when going out of scope.
/// });
/// }
///
/// thread::sleep(Duration::from_millis(100)); // Wait for readers to start
///
/// // While all readers can proceed, a call to .write() has to wait for
// // current active reader locks.
/// let mut writable_data = data.write().unwrap();
/// println!("Writer proceeds...");
/// *writable_data += 1;
/// ```
///
/// [`Mutex`]: super::Mutex
Expand Down Expand Up @@ -370,7 +382,8 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Panics
///
/// This function might panic when called if the lock is already held by the current thread.
/// This function might panic when called if the lock is already held by the current thread
/// in read or write mode.
///
/// # Examples
///
Expand Down Expand Up @@ -467,7 +480,8 @@ impl<T: ?Sized> RwLock<T> {
///
/// # Panics
///
/// This function might panic when called if the lock is already held by the current thread.
/// This function might panic when called if the lock is already held by the current thread
/// in read or write mode.
///
/// # Examples
///
Expand Down
Loading