Auto merge of #131111 - matthiaskrgr:rollup-n6do187, r=matthiaskrgr

Rollup of 4 pull requests

Successful merges:

 - #130005 (Replace -Z default-hidden-visibility with -Z default-visibility)
 - #130229 (ptr::add/sub: do not claim equivalence with `offset(c as isize)`)
 - #130773 (Update Unicode escapes in `/library/core/src/char/methods.rs`)
 - #130933 (rustdoc: lists items that contain multiple paragraphs are more clear)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-10-01 19:29:26 +00:00
commit 06bb8364aa
19 changed files with 270 additions and 127 deletions

View File

@ -104,10 +104,17 @@ fn create_wrapper_function(
false,
);
if tcx.sess.default_hidden_visibility() {
#[cfg(feature = "master")]
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
#[cfg(feature = "master")]
match tcx.sess.default_visibility() {
rustc_target::spec::SymbolVisibility::Hidden => {
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden))
}
rustc_target::spec::SymbolVisibility::Protected => {
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected))
}
rustc_target::spec::SymbolVisibility::Interposable => {}
}
if tcx.sess.must_emit_unwind_tables() {
// TODO(antoyo): emit unwind tables.
}

View File

@ -77,18 +77,20 @@ pub(crate) unsafe fn codegen(
// __rust_alloc_error_handler_should_panic
let name = OomStrategy::SYMBOL;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
if tcx.sess.default_hidden_visibility() {
llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
}
llvm::LLVMRustSetVisibility(
ll_g,
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
let llval = llvm::LLVMConstInt(i8, val as u64, False);
llvm::LLVMSetInitializer(ll_g, llval);
let name = NO_ALLOC_SHIM_IS_UNSTABLE;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
if tcx.sess.default_hidden_visibility() {
llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
}
llvm::LLVMRustSetVisibility(
ll_g,
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
let llval = llvm::LLVMConstInt(i8, 0, False);
llvm::LLVMSetInitializer(ll_g, llval);
}
@ -132,9 +134,11 @@ fn create_wrapper_function(
None
};
if tcx.sess.default_hidden_visibility() {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
llvm::LLVMRustSetVisibility(
llfn,
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
);
if tcx.sess.must_emit_unwind_tables() {
let uwtable =
attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind);

View File

@ -22,6 +22,7 @@ use tracing::debug;
use crate::abi::{FnAbi, FnAbiLlvmExt};
use crate::context::CodegenCx;
use crate::llvm::AttributePlace::Function;
use crate::llvm::Visibility;
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, llvm};
@ -84,11 +85,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
fn_type: &'ll Type,
) -> &'ll Value {
// Declare C ABI functions with the visibility used by C by default.
let visibility = if self.tcx.sess.default_hidden_visibility() {
llvm::Visibility::Hidden
} else {
llvm::Visibility::Default
};
let visibility = Visibility::from_generic(self.tcx.sess.default_visibility());
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
}
@ -107,11 +104,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
unnamed: llvm::UnnamedAddr,
fn_type: &'ll Type,
) -> &'ll Value {
let visibility = if self.tcx.sess.default_hidden_visibility() {
llvm::Visibility::Hidden
} else {
llvm::Visibility::Default
};
let visibility = Visibility::from_generic(self.tcx.sess.default_visibility());
declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
}

View File

@ -4,6 +4,7 @@
use std::marker::PhantomData;
use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
use rustc_target::spec::SymbolVisibility;
use super::RustString;
use super::debuginfo::{
@ -133,6 +134,16 @@ pub enum Visibility {
Protected = 2,
}
impl Visibility {
pub fn from_generic(visibility: SymbolVisibility) -> Self {
match visibility {
SymbolVisibility::Hidden => Visibility::Hidden,
SymbolVisibility::Protected => Visibility::Protected,
SymbolVisibility::Interposable => Visibility::Default,
}
}
}
/// LLVMUnnamedAddr
#[repr(C)]
pub enum UnnamedAddr {

View File

@ -770,7 +770,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(crate_attr, vec!["abc".to_string()]);
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
tracked!(debug_info_for_profiling, true);
tracked!(default_hidden_visibility, Some(true));
tracked!(default_visibility, Some(rustc_target::spec::SymbolVisibility::Hidden));
tracked!(dep_info_omit_d_target, true);
tracked!(direct_access_external_data, Some(true));
tracked!(dual_proc_macros, true);

View File

@ -15,6 +15,7 @@ use rustc_query_system::ich::StableHashingContext;
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_span::symbol::Symbol;
use rustc_target::spec::SymbolVisibility;
use tracing::debug;
use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
@ -305,6 +306,16 @@ pub enum Visibility {
Protected,
}
impl From<SymbolVisibility> for Visibility {
fn from(value: SymbolVisibility) -> Self {
match value {
SymbolVisibility::Hidden => Visibility::Hidden,
SymbolVisibility::Protected => Visibility::Protected,
SymbolVisibility::Interposable => Visibility::Default,
}
}
}
impl<'tcx> CodegenUnit<'tcx> {
#[inline]
pub fn new(name: Symbol) -> CodegenUnit<'tcx> {

View File

@ -904,26 +904,22 @@ fn mono_item_visibility<'tcx>(
}
fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
if !tcx.sess.default_hidden_visibility() {
return Visibility::Default;
}
let export_level = if is_generic {
// Generic functions never have export-level C.
SymbolExportLevel::Rust
} else {
match tcx.reachable_non_generics(id.krate).get(&id) {
Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => SymbolExportLevel::C,
_ => SymbolExportLevel::Rust,
}
};
match export_level {
// C-export level items remain at `Default` to allow C code to
// access and interpose them.
SymbolExportLevel::C => Visibility::Default,
// Generic functions never have export-level C.
if is_generic {
return Visibility::Hidden;
}
// Things with export level C don't get instantiated in
// downstream crates.
if !id.is_local() {
return Visibility::Hidden;
}
// C-export level items remain at `Default`, all other internal
// items become `Hidden`.
match tcx.reachable_non_generics(id.krate).get(&id) {
Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => Visibility::Default,
_ => Visibility::Hidden,
// For all other symbols, `default_visibility` determines which visibility to use.
SymbolExportLevel::Rust => tcx.sess.default_visibility().into(),
}
}

View File

@ -3008,7 +3008,8 @@ pub(crate) mod dep_tracking {
use rustc_span::edition::Edition;
use rustc_target::spec::{
CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel, WasmCAbi,
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTriple,
TlsModel, WasmCAbi,
};
use super::{
@ -3101,6 +3102,7 @@ pub(crate) mod dep_tracking {
StackProtector,
SwitchWithOptPath,
SymbolManglingVersion,
SymbolVisibility,
RemapPathScopeComponents,
SourceFileHashAlgorithm,
OutFileName,

View File

@ -13,8 +13,8 @@ use rustc_span::edition::Edition;
use rustc_span::{RealFileName, SourceFileHashAlgorithm};
use rustc_target::spec::{
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
WasmCAbi,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility,
TargetTriple, TlsModel, WasmCAbi,
};
use crate::config::*;
@ -416,6 +416,8 @@ mod desc {
"one of: `disabled`, `trampolines`, or `aliases`";
pub(crate) const parse_symbol_mangling_version: &str =
"one of: `legacy`, `v0` (RFC 2603), or `hashed`";
pub(crate) const parse_opt_symbol_visibility: &str =
"one of: `hidden`, `protected`, or `interposable`";
pub(crate) const parse_src_file_hash: &str = "either `md5` or `sha1`";
pub(crate) const parse_relocation_model: &str =
"one of supported relocation models (`rustc --print relocation-models`)";
@ -922,6 +924,20 @@ mod parse {
true
}
pub(crate) fn parse_opt_symbol_visibility(
slot: &mut Option<SymbolVisibility>,
v: Option<&str>,
) -> bool {
if let Some(v) = v {
if let Ok(vis) = SymbolVisibility::from_str(v) {
*slot = Some(vis);
} else {
return false;
}
}
true
}
pub(crate) fn parse_optimization_fuel(
slot: &mut Option<(String, u64)>,
v: Option<&str>,
@ -1688,8 +1704,8 @@ options! {
"compress debug info sections (none, zlib, zstd, default: none)"),
deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
"deduplicate identical diagnostics (default: yes)"),
default_hidden_visibility: Option<bool> = (None, parse_opt_bool, [TRACKED],
"overrides the `default_hidden_visibility` setting of the target"),
default_visibility: Option<SymbolVisibility> = (None, parse_opt_symbol_visibility, [TRACKED],
"overrides the `default_visibility` setting of the target"),
dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
"in dep-info output, omit targets for tracking dependencies of the dep-info files \
themselves (default: no)"),

View File

@ -31,7 +31,8 @@ use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{
CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
SmallDataThresholdSupport, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
SmallDataThresholdSupport, SplitDebuginfo, StackProtector, SymbolVisibility, Target,
TargetTriple, TlsModel,
};
use crate::code_stats::CodeStats;
@ -617,12 +618,13 @@ impl Session {
}
}
/// Whether the default visibility of symbols should be "hidden" rather than "default".
pub fn default_hidden_visibility(&self) -> bool {
/// Returns the default symbol visibility.
pub fn default_visibility(&self) -> SymbolVisibility {
self.opts
.unstable_opts
.default_hidden_visibility
.unwrap_or(self.target.options.default_hidden_visibility)
.default_visibility
.or(self.target.options.default_visibility)
.unwrap_or(SymbolVisibility::Interposable)
}
}

View File

@ -830,6 +830,46 @@ impl RelroLevel {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum SymbolVisibility {
Hidden,
Protected,
Interposable,
}
impl SymbolVisibility {
pub fn desc(&self) -> &str {
match *self {
SymbolVisibility::Hidden => "hidden",
SymbolVisibility::Protected => "protected",
SymbolVisibility::Interposable => "interposable",
}
}
}
impl FromStr for SymbolVisibility {
type Err = ();
fn from_str(s: &str) -> Result<SymbolVisibility, ()> {
match s {
"hidden" => Ok(SymbolVisibility::Hidden),
"protected" => Ok(SymbolVisibility::Protected),
"interposable" => Ok(SymbolVisibility::Interposable),
_ => Err(()),
}
}
}
impl ToJson for SymbolVisibility {
fn to_json(&self) -> Json {
match *self {
SymbolVisibility::Hidden => "hidden".to_json(),
SymbolVisibility::Protected => "protected".to_json(),
SymbolVisibility::Interposable => "interposable".to_json(),
}
}
}
impl FromStr for RelroLevel {
type Err = ();
@ -2326,13 +2366,12 @@ pub struct TargetOptions {
/// for this target unconditionally.
pub no_builtins: bool,
/// The default visibility for symbols in this target should be "hidden"
/// rather than "default".
/// The default visibility for symbols in this target.
///
/// This value typically shouldn't be accessed directly, but through
/// the `rustc_session::Session::default_hidden_visibility` method, which
/// allows `rustc` users to override this setting using cmdline flags.
pub default_hidden_visibility: bool,
/// This value typically shouldn't be accessed directly, but through the
/// `rustc_session::Session::default_visibility` method, which allows `rustc` users to override
/// this setting using cmdline flags.
pub default_visibility: Option<SymbolVisibility>,
/// Whether a .debug_gdb_scripts section will be added to the output object file
pub emit_debug_gdb_scripts: bool,
@ -2623,7 +2662,7 @@ impl Default for TargetOptions {
requires_lto: false,
singlethread: false,
no_builtins: false,
default_hidden_visibility: false,
default_visibility: None,
emit_debug_gdb_scripts: true,
requires_uwtable: false,
default_uwtable: false,
@ -2963,6 +3002,18 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, Option<SymbolVisibility>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<SymbolVisibility>() {
Ok(level) => base.$key_name = Some(level),
_ => return Some(Err(format!("'{}' is not a valid value for \
symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, DebuginfoKind) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@ -3353,7 +3404,7 @@ impl Target {
key!(requires_lto, bool);
key!(singlethread, bool);
key!(no_builtins, bool);
key!(default_hidden_visibility, bool);
key!(default_visibility, Option<SymbolVisibility>)?;
key!(emit_debug_gdb_scripts, bool);
key!(requires_uwtable, bool);
key!(default_uwtable, bool);
@ -3633,7 +3684,7 @@ impl ToJson for Target {
target_option_val!(requires_lto);
target_option_val!(singlethread);
target_option_val!(no_builtins);
target_option_val!(default_hidden_visibility);
target_option_val!(default_visibility);
target_option_val!(emit_debug_gdb_scripts);
target_option_val!(requires_uwtable);
target_option_val!(default_uwtable);

View File

@ -69,7 +69,7 @@ impl char {
/// assert_eq!(char::from_u32(value_at_max + 1), None);
/// ```
#[stable(feature = "assoc_char_consts", since = "1.52.0")]
pub const MAX: char = '\u{10ffff}';
pub const MAX: char = '\u{10FFFF}';
/// `U+FFFD REPLACEMENT CHARACTER` (<28>) is used in Unicode to represent a
/// decoding error.
@ -1841,7 +1841,6 @@ pub const fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] {
}
(2, [a, b, ..]) => {
code -= 0x1_0000;
*a = (code >> 10) as u16 | 0xD800;
*b = (code & 0x3FF) as u16 | 0xDC00;
}

View File

@ -1425,8 +1425,7 @@ extern "rust-intrinsic" {
///
/// If the computed offset is non-zero, then both the starting and resulting pointer must be
/// either in bounds or at the end of an allocated object. If either pointer is out
/// of bounds or arithmetic overflow occurs then any further use of the returned value will
/// result in undefined behavior.
/// of bounds or arithmetic overflow occurs then this operation is undefined behavior.
///
/// The stabilized version of this intrinsic is [`pointer::offset`].
#[must_use = "returns a new pointer rather than modifying its argument"]

View File

@ -346,7 +346,7 @@ impl<T: ?Sized> *const T {
if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
}
/// Adds an offset to a pointer.
/// Adds a signed offset to a pointer.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -355,7 +355,8 @@ impl<T: ?Sized> *const T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -398,7 +399,7 @@ impl<T: ?Sized> *const T {
unsafe { intrinsics::offset(self, count) }
}
/// Calculates the offset from a pointer in bytes.
/// Adds a signed offset in bytes to a pointer.
///
/// `count` is in units of **bytes**.
///
@ -418,7 +419,7 @@ impl<T: ?Sized> *const T {
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// Adds a signed offset to a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -480,7 +481,7 @@ impl<T: ?Sized> *const T {
unsafe { intrinsics::arith_offset(self, count) }
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// Adds a signed offset in bytes to a pointer using wrapping arithmetic.
///
/// `count` is in units of **bytes**.
///
@ -804,7 +805,11 @@ impl<T: ?Sized> *const T {
}
}
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
/// Adds an unsigned offset to a pointer.
///
/// This can only move the pointer forward (or not move it). If you need to move forward or
/// backward depending on the value, then you might want [`offset`](#method.offset) instead
/// which takes a signed offset.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -813,7 +818,8 @@ impl<T: ?Sized> *const T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -856,7 +862,7 @@ impl<T: ?Sized> *const T {
unsafe { intrinsics::offset(self, count) }
}
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
/// Adds an unsigned offset in bytes to a pointer.
///
/// `count` is in units of bytes.
///
@ -876,8 +882,11 @@ impl<T: ?Sized> *const T {
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
}
/// Subtracts an offset from a pointer (convenience for
/// `.offset((count as isize).wrapping_neg())`).
/// Subtracts an unsigned offset from a pointer.
///
/// This can only move the pointer backward (or not move it). If you need to move forward or
/// backward depending on the value, then you might want [`offset`](#method.offset) instead
/// which takes a signed offset.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -886,7 +895,8 @@ impl<T: ?Sized> *const T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -937,8 +947,7 @@ impl<T: ?Sized> *const T {
}
}
/// Calculates the offset from a pointer in bytes (convenience for
/// `.byte_offset((count as isize).wrapping_neg())`).
/// Subtracts an unsigned offset in bytes from a pointer.
///
/// `count` is in units of bytes.
///
@ -958,8 +967,7 @@ impl<T: ?Sized> *const T {
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset(count as isize)`)
/// Adds an unsigned offset to a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -1020,8 +1028,7 @@ impl<T: ?Sized> *const T {
self.wrapping_offset(count as isize)
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// (convenience for `.wrapping_byte_offset(count as isize)`)
/// Adds an unsigned offset in bytes to a pointer using wrapping arithmetic.
///
/// `count` is in units of bytes.
///
@ -1038,8 +1045,7 @@ impl<T: ?Sized> *const T {
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
/// Subtracts an unsigned offset from a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -1100,8 +1106,7 @@ impl<T: ?Sized> *const T {
self.wrapping_offset((count as isize).wrapping_neg())
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
/// Subtracts an unsigned offset in bytes from a pointer using wrapping arithmetic.
///
/// `count` is in units of bytes.
///

View File

@ -344,7 +344,7 @@ impl<T: ?Sized> *mut T {
if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
}
/// Adds an offset to a pointer.
/// Adds a signed offset to a pointer.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -353,7 +353,8 @@ impl<T: ?Sized> *mut T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -398,7 +399,7 @@ impl<T: ?Sized> *mut T {
unsafe { intrinsics::offset(self, count) }
}
/// Calculates the offset from a pointer in bytes.
/// Adds a signed offset in bytes to a pointer.
///
/// `count` is in units of **bytes**.
///
@ -418,7 +419,8 @@ impl<T: ?Sized> *mut T {
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// Adds a signed offset to a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
///
@ -477,7 +479,7 @@ impl<T: ?Sized> *mut T {
unsafe { intrinsics::arith_offset(self, count) as *mut T }
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// Adds a signed offset in bytes to a pointer using wrapping arithmetic.
///
/// `count` is in units of **bytes**.
///
@ -885,7 +887,11 @@ impl<T: ?Sized> *mut T {
unsafe { (self as *const T).sub_ptr(origin) }
}
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
/// Adds an unsigned offset to a pointer.
///
/// This can only move the pointer forward (or not move it). If you need to move forward or
/// backward depending on the value, then you might want [`offset`](#method.offset) instead
/// which takes a signed offset.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -894,7 +900,8 @@ impl<T: ?Sized> *mut T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -937,7 +944,7 @@ impl<T: ?Sized> *mut T {
unsafe { intrinsics::offset(self, count) }
}
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
/// Adds an unsigned offset in bytes to a pointer.
///
/// `count` is in units of bytes.
///
@ -957,8 +964,11 @@ impl<T: ?Sized> *mut T {
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
}
/// Subtracts an offset from a pointer (convenience for
/// `.offset((count as isize).wrapping_neg())`).
/// Subtracts an unsigned offset from a pointer.
///
/// This can only move the pointer backward (or not move it). If you need to move forward or
/// backward depending on the value, then you might want [`offset`](#method.offset) instead
/// which takes a signed offset.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -967,7 +977,8 @@ impl<T: ?Sized> *mut T {
///
/// If any of the following conditions are violated, the result is Undefined Behavior:
///
/// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
/// "wrapping around"), must fit in an `isize`.
///
/// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
/// [allocated object], and the entire memory range between `self` and the result must be in
@ -1018,8 +1029,7 @@ impl<T: ?Sized> *mut T {
}
}
/// Calculates the offset from a pointer in bytes (convenience for
/// `.byte_offset((count as isize).wrapping_neg())`).
/// Subtracts an unsigned offset in bytes from a pointer.
///
/// `count` is in units of bytes.
///
@ -1039,8 +1049,7 @@ impl<T: ?Sized> *mut T {
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset(count as isize)`)
/// Adds an unsigned offset to a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -1099,8 +1108,7 @@ impl<T: ?Sized> *mut T {
self.wrapping_offset(count as isize)
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// (convenience for `.wrapping_byte_offset(count as isize)`)
/// Adds an unsigned offset in bytes to a pointer using wrapping arithmetic.
///
/// `count` is in units of bytes.
///
@ -1117,8 +1125,7 @@ impl<T: ?Sized> *mut T {
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
}
/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
/// Subtracts an unsigned offset from a pointer using wrapping arithmetic.
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
@ -1177,8 +1184,7 @@ impl<T: ?Sized> *mut T {
self.wrapping_offset((count as isize).wrapping_neg())
}
/// Calculates the offset from a pointer in bytes using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
/// Subtracts an unsigned offset in bytes from a pointer using wrapping arithmetic.
///
/// `count` is in units of bytes.
///

View File

@ -1,12 +0,0 @@
# `default-hidden-visibility`
The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/656
------------------------
This flag can be used to override the target's
[`default_hidden_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_hidden_visibility)
setting.
Using `-Zdefault_hidden_visibility=yes` is roughly equivalent to Clang's
[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility)
cmdline flag.

View File

@ -0,0 +1,44 @@
# `default-visibility`
The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131090
------------------------
This flag can be used to override the target's
[`default_visibility`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_target/spec/struct.TargetOptions.html#structfield.default_visibility)
setting.
This option only affects building of shared objects and should have no effect on executables.
Visibility an be set to one of three options:
* protected
* hidden
* interposable
## Hidden visibility
Using `-Zdefault-visibility=hidden` is roughly equivalent to Clang's
[`-fvisibility=hidden`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fvisibility)
cmdline flag. Hidden symbols will not be exported from the created shared object, so cannot be
referenced from other shared objects or from executables.
## Protected visibility
Using `-Zdefault-visibility=protected` will cause rust-mangled symbols to be emitted with
"protected" visibility. This signals the compiler, the linker and the runtime linker that these
symbols cannot be overridden by the executable or by other shared objects earlier in the load order.
This will allow the compiler to emit direct references to symbols, which may improve performance. It
also removes the need for these symbols to be resolved when a shared object built with this option
is loaded.
Using protected visibility when linking with GNU ld prior to 2.40 will result in linker errors when
building for Linux. Other linkers such as LLD are not affected.
## Interposable
Using `-Zdefault-visibility=interposable` will cause symbols to be emitted with "default"
visibility. On platforms that support it, this makes it so that symbols can be interposed, which
means that they can be overridden by symbols with the same name from the executable or by other
shared objects earier in the load order.

View File

@ -960,6 +960,13 @@ pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers {
display: inline-block;
}
.docblock li {
margin-bottom: .8em;
}
.docblock li p {
margin-bottom: .1em;
}
/* "where ..." clauses with block display are also smaller */
div.where {
white-space: pre-wrap;

View File

@ -1,11 +1,12 @@
// Verifies that `Session::default_hidden_visibility` is affected when using the related cmdline
// flag. This is a regression test for https://github.com/rust-lang/compiler-team/issues/656. See
// Verifies that `Session::default_visibility` is affected when using the related cmdline
// flag. This is a regression test for https://github.com/rust-lang/compiler-team/issues/782. See
// also https://github.com/rust-lang/rust/issues/73295 and
// https://github.com/rust-lang/rust/issues/37530.
//@ revisions:DEFAULT YES NO
//@[YES] compile-flags: -Zdefault-hidden-visibility=yes
//@[NO] compile-flags: -Zdefault-hidden-visibility=no
//@ revisions:DEFAULT HIDDEN PROTECTED INTERPOSABLE
//@[HIDDEN] compile-flags: -Zdefault-visibility=hidden
//@[PROTECTED] compile-flags: -Zdefault-visibility=protected
//@[INTERPOSABLE] compile-flags: -Zdefault-visibility=interposable
// The test scenario is specifically about visibility of symbols exported out of dynamically linked
// libraries.
@ -26,6 +27,7 @@ pub static tested_symbol: [u8; 6] = *b"foobar";
//
//@ only-x86_64-unknown-linux-gnu
// DEFAULT: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant
// YES: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = hidden constant
// NO: @{{.*}}default_hidden_visibility{{.*}}tested_symbol{{.*}} = constant
// HIDDEN: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = hidden constant
// PROTECTED: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = protected constant
// INTERPOSABLE: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant
// DEFAULT: @{{.*}}default_visibility{{.*}}tested_symbol{{.*}} = constant