diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 12dcbd6d17fd7..fa378e19f71ab 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1390,7 +1390,7 @@ pub struct StructExpr {
// Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ExprKind {
- /// An array (`[a, b, c, d]`)
+ /// An array (e.g, `[a, b, c, d]`).
Array(ThinVec
>),
/// Allow anonymous constants from an inline `const` block
ConstBlock(AnonConst),
@@ -1401,7 +1401,7 @@ pub enum ExprKind {
/// This also represents calling the constructor of
/// tuple-like ADTs such as tuple structs and enum variants.
Call(P, ThinVec>),
- /// A method call (e.g. `x.foo::(a, b, c)`).
+ /// A method call (e.g., `x.foo::(a, b, c)`).
MethodCall(Box),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(ThinVec>),
@@ -1413,7 +1413,10 @@ pub enum ExprKind {
Lit(token::Lit),
/// A cast (e.g., `foo as f64`).
Cast(P, P),
- /// A type ascription (e.g., `42: usize`).
+ /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
+ ///
+ /// Usually not written directly in user code but
+ /// indirectly via the macro `type_ascribe!(...)`.
Type(P, P),
/// A `let pat = expr` expression that is only semantically allowed in the condition
/// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
@@ -1488,7 +1491,10 @@ pub enum ExprKind {
/// Output of the `asm!()` macro.
InlineAsm(P),
- /// Output of the `offset_of!()` macro.
+ /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
+ ///
+ /// Usually not written directly in user code but
+ /// indirectly via the macro `core::mem::offset_of!(...)`.
OffsetOf(P, P<[Ident]>),
/// A macro invocation; pre-expansion.
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index b5bb781acdfe0..93400c67949d9 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -422,7 +422,8 @@ impl<'a> State<'a> {
self.print_type(ty);
}
ast::ExprKind::Type(expr, ty) => {
- self.word("type_ascribe!(");
+ self.word("builtin # type_ascribe");
+ self.popen();
self.ibox(0);
self.print_expr(expr, FixupContext::default());
@@ -431,7 +432,7 @@ impl<'a> State<'a> {
self.print_type(ty);
self.end();
- self.word(")");
+ self.pclose();
}
ast::ExprKind::Let(pat, scrutinee, _, _) => {
self.print_let(pat, scrutinee, fixup);
@@ -657,15 +658,15 @@ impl<'a> State<'a> {
);
}
ast::ExprKind::InlineAsm(a) => {
- // FIXME: This should have its own syntax, distinct from a macro invocation.
+ // FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`.
self.word("asm!");
self.print_inline_asm(a);
}
ast::ExprKind::FormatArgs(fmt) => {
- // FIXME: This should have its own syntax, distinct from a macro invocation.
+ // FIXME: Print `builtin # format_args` once macro `format_args` uses `builtin_syntax`.
self.word("format_args!");
self.popen();
- self.rbox(0, Inconsistent);
+ self.ibox(0);
self.word(reconstruct_format_args_template_string(&fmt.template));
for arg in fmt.arguments.all_args() {
self.word_space(",");
@@ -677,7 +678,7 @@ impl<'a> State<'a> {
ast::ExprKind::OffsetOf(container, fields) => {
self.word("builtin # offset_of");
self.popen();
- self.rbox(0, Inconsistent);
+ self.ibox(0);
self.print_type(container);
self.word(",");
self.space();
@@ -690,8 +691,8 @@ impl<'a> State<'a> {
self.print_ident(field);
}
}
- self.pclose();
self.end();
+ self.pclose();
}
ast::ExprKind::MacCall(m) => self.print_mac(m),
ast::ExprKind::Paren(e) => {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index b90182c2b3e6b..61398f7d60579 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -238,6 +238,7 @@ impl<'a> State<'a> {
self.bclose(item.span, empty);
}
ast::ItemKind::GlobalAsm(asm) => {
+ // FIXME: Print `builtin # global_asm` once macro `global_asm` uses `builtin_syntax`.
self.head(visibility_qualified(&item.vis, "global_asm!"));
self.print_inline_asm(asm);
self.word(";");
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 6fe74edbd70a8..12868a666056d 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -21,7 +21,7 @@ use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
-use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
+use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{FileName, Span, DUMMY_SP};
@@ -32,8 +32,6 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use thin_vec::ThinVec;
-pub(crate) use rustc_span::hygiene::MacroKind;
-
// When adding new variants, make sure to
// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
// to use `assign_id!`
@@ -573,35 +571,6 @@ impl DummyResult {
tokens: None,
})
}
-
- /// A plain dummy pattern.
- pub fn raw_pat(sp: Span) -> ast::Pat {
- ast::Pat { id: ast::DUMMY_NODE_ID, kind: PatKind::Wild, span: sp, tokens: None }
- }
-
- /// A plain dummy type.
- pub fn raw_ty(sp: Span) -> P {
- // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
- // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
- // support, so we use an empty tuple instead.
- P(ast::Ty {
- id: ast::DUMMY_NODE_ID,
- kind: ast::TyKind::Tup(ThinVec::new()),
- span: sp,
- tokens: None,
- })
- }
-
- /// A plain dummy crate.
- pub fn raw_crate() -> ast::Crate {
- ast::Crate {
- attrs: Default::default(),
- items: Default::default(),
- spans: Default::default(),
- id: ast::DUMMY_NODE_ID,
- is_placeholder: Default::default(),
- }
- }
}
impl MacResult for DummyResult {
@@ -610,7 +579,12 @@ impl MacResult for DummyResult {
}
fn make_pat(self: Box) -> Option> {
- Some(P(DummyResult::raw_pat(self.span)))
+ Some(P(ast::Pat {
+ id: ast::DUMMY_NODE_ID,
+ kind: PatKind::Wild,
+ span: self.span,
+ tokens: None,
+ }))
}
fn make_items(self: Box) -> Option; 1]>> {
@@ -638,7 +612,15 @@ impl MacResult for DummyResult {
}
fn make_ty(self: Box) -> Option> {
- Some(DummyResult::raw_ty(self.span))
+ // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
+ // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
+ // support, so we use an empty tuple instead.
+ Some(P(ast::Ty {
+ id: ast::DUMMY_NODE_ID,
+ kind: ast::TyKind::Tup(ThinVec::new()),
+ span: self.span,
+ tokens: None,
+ }))
}
fn make_arms(self: Box) -> Option> {
@@ -670,7 +652,13 @@ impl MacResult for DummyResult {
}
fn make_crate(self: Box) -> Option {
- Some(DummyResult::raw_crate())
+ Some(ast::Crate {
+ attrs: Default::default(),
+ items: Default::default(),
+ spans: Default::default(),
+ id: ast::DUMMY_NODE_ID,
+ is_placeholder: Default::default(),
+ })
}
}
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 83f120525bc5f..1b6e191c2eb09 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -175,20 +175,6 @@ impl<'a> ExtCtxt<'a> {
ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
}
- pub fn stmt_let_pat(&self, sp: Span, pat: P, ex: P) -> ast::Stmt {
- let local = P(ast::Local {
- pat,
- ty: None,
- id: ast::DUMMY_NODE_ID,
- kind: LocalKind::Init(ex),
- span: sp,
- colon_sp: None,
- attrs: AttrVec::new(),
- tokens: None,
- });
- self.stmt_local(local, sp)
- }
-
pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P) -> ast::Stmt {
self.stmt_let_ty(sp, mutbl, ident, None, ex)
}
@@ -278,10 +264,6 @@ impl<'a> ExtCtxt<'a> {
self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
}
- pub fn expr_field(&self, span: Span, expr: P, field: Ident) -> P {
- self.expr(span, ast::ExprKind::Field(expr, field))
- }
-
pub fn expr_macro_call(&self, span: Span, call: P) -> P {
self.expr(span, ast::ExprKind::MacCall(call))
}
@@ -394,11 +376,6 @@ impl<'a> ExtCtxt<'a> {
self.expr(span, ast::ExprKind::Lit(lit))
}
- pub fn expr_char(&self, span: Span, ch: char) -> P {
- let lit = token::Lit::new(token::Char, literal::escape_char_symbol(ch), None);
- self.expr(span, ast::ExprKind::Lit(lit))
- }
-
pub fn expr_byte_str(&self, span: Span, bytes: Vec) -> P {
let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None);
self.expr(span, ast::ExprKind::Lit(lit))
@@ -414,10 +391,6 @@ impl<'a> ExtCtxt<'a> {
self.expr_addr_of(sp, self.expr_array(sp, exprs))
}
- pub fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P {
- self.expr(sp, ast::ExprKind::Cast(expr, ty))
- }
-
pub fn expr_some(&self, sp: Span, expr: P) -> P {
let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
self.expr_call_global(sp, some, thin_vec![expr])
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index b554a5ccd1961..897420a11cdfb 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -99,10 +99,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
// If the declared feature is unstable, record it.
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
(f.set_enabled)(&mut features);
- // When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance
- // that the person hitting the ICE may be using -Zbuild-std or similar with an untested target.
- // The bug is probably in the standard library and not the compiler in that case, but that doesn't
- // really matter - we want a bug report.
+ // When the ICE comes from core, alloc or std (approximation of the standard
+ // library), there's a chance that the person hitting the ICE may be using
+ // -Zbuild-std or similar with an untested target. The bug is probably in the
+ // standard library and not the compiler in that case, but that doesn't really
+ // matter - we want a bug report.
if features.internal(name)
&& ![sym::core, sym::alloc, sym::std].contains(&crate_name)
{
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 503c9170cab53..f61cebc02562a 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -4,7 +4,6 @@ use crate::errors::{
IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported,
UnsupportedKeyValue, WrongFragmentKind,
};
-use crate::hygiene::SyntaxContext;
use crate::mbe::diagnostics::annotate_err_with_kind;
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
use crate::placeholders::{placeholder, PlaceholderExpander};
@@ -32,6 +31,7 @@ use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::parse::feature_err;
use rustc_session::{Limit, Session};
+use rustc_span::hygiene::SyntaxContext;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span};
@@ -87,7 +87,7 @@ macro_rules! ast_fragments {
}
impl AstFragment {
- pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
+ fn add_placeholders(&mut self, placeholders: &[NodeId]) {
if placeholders.is_empty() {
return;
}
@@ -100,14 +100,14 @@ macro_rules! ast_fragments {
}
}
- pub fn make_opt_expr(self) -> Option> {
+ pub(crate) fn make_opt_expr(self) -> Option
> {
match self {
AstFragment::OptExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
}
}
- pub fn make_method_receiver_expr(self) -> P {
+ pub(crate) fn make_method_receiver_expr(self) -> P {
match self {
AstFragment::MethodReceiverExpr(expr) => expr,
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
@@ -125,7 +125,7 @@ macro_rules! ast_fragments {
T::fragment_to_output(self)
}
- pub fn mut_visit_with(&mut self, vis: &mut F) {
+ pub(crate) fn mut_visit_with(&mut self, vis: &mut F) {
match self {
AstFragment::OptExpr(opt_expr) => {
visit_clobber(opt_expr, |opt_expr| {
@@ -372,6 +372,14 @@ impl Invocation {
InvocationKind::Derive { path, .. } => path.span,
}
}
+
+ fn span_mut(&mut self) -> &mut Span {
+ match &mut self.kind {
+ InvocationKind::Bang { span, .. } => span,
+ InvocationKind::Attr { attr, .. } => &mut attr.span,
+ InvocationKind::Derive { path, .. } => &mut path.span,
+ }
+ }
}
pub struct MacroExpander<'a, 'b> {
@@ -432,7 +440,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
break;
}
invocations = mem::take(&mut undetermined_invocations);
- force = !mem::replace(&mut progress, false);
+ force = !progress;
+ progress = false;
if force && self.monotonic {
self.cx.dcx().span_delayed_bug(
invocations.last().unwrap().0.span(),
@@ -471,7 +480,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx.force_mode = force;
let fragment_kind = invoc.fragment_kind;
- let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
+ match self.expand_invoc(invoc, &ext.kind) {
ExpandResult::Ready(fragment) => {
let mut derive_invocations = Vec::new();
let derive_placeholders = self
@@ -503,12 +512,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
})
.unwrap_or_default();
- let (fragment, collected_invocations) =
+ let (expanded_fragment, collected_invocations) =
self.collect_invocations(fragment, &derive_placeholders);
- // We choose to expand any derive invocations associated with this macro invocation
- // *before* any macro invocations collected from the output fragment
+ // We choose to expand any derive invocations associated with this macro
+ // invocation *before* any macro invocations collected from the output
+ // fragment.
derive_invocations.extend(collected_invocations);
- (fragment, derive_invocations)
+
+ progress = true;
+ if expanded_fragments.len() < depth {
+ expanded_fragments.push(Vec::new());
+ }
+ expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
+ invocations.extend(derive_invocations.into_iter().rev());
}
ExpandResult::Retry(invoc) => {
if force {
@@ -519,17 +535,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
} else {
// Cannot expand, will retry this invocation later.
undetermined_invocations.push((invoc, Some(ext)));
- continue;
}
}
- };
-
- progress = true;
- if expanded_fragments.len() < depth {
- expanded_fragments.push(Vec::new());
}
- expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
- invocations.extend(new_invocations.into_iter().rev());
}
self.cx.current_expansion = orig_expansion_data;
@@ -590,11 +598,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
for (invoc, _) in invocations.iter_mut() {
let expn_id = invoc.expansion_data.id;
let parent_def = self.cx.resolver.invocation_parent(expn_id);
- let span = match &mut invoc.kind {
- InvocationKind::Bang { span, .. } => span,
- InvocationKind::Attr { attr, .. } => &mut attr.span,
- InvocationKind::Derive { path, .. } => &mut path.span,
- };
+ let span = invoc.span_mut();
*span = span.with_parent(Some(parent_def));
}
}
@@ -957,7 +961,7 @@ pub fn parse_ast_fragment<'a>(
})
}
-pub fn ensure_complete_parse<'a>(
+pub(crate) fn ensure_complete_parse<'a>(
parser: &Parser<'a>,
macro_path: &ast::Path,
kind_name: &str,
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 3c9d2e8706835..c2c3b777699ce 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,43 +1,39 @@
+// tidy-alphabetical-start
+#![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
#![doc(rust_logo)]
-#![feature(rustdoc_internals)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
#![feature(if_let_guard)]
#![feature(let_chains)]
-#![feature(lint_reasons)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
-#![feature(proc_macro_span)]
+#![feature(rustdoc_internals)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
-#![allow(rustc::diagnostic_outside_of_impl)]
-#![allow(internal_features)]
+// tidy-alphabetical-end
extern crate proc_macro as pm;
+mod build;
+mod errors;
+// FIXME(Nilstrieb) Translate macro_rules diagnostics
+#[allow(rustc::untranslatable_diagnostic)]
+mod mbe;
mod placeholders;
mod proc_macro_server;
pub use mbe::macro_rules::compile_declarative_macro;
-pub(crate) use rustc_span::hygiene;
pub mod base;
-pub mod build;
-#[macro_use]
pub mod config;
-pub mod errors;
pub mod expand;
pub mod module;
-
// FIXME(Nilstrieb) Translate proc_macro diagnostics
#[allow(rustc::untranslatable_diagnostic)]
pub mod proc_macro;
-// FIXME(Nilstrieb) Translate macro_rules diagnostics
-#[allow(rustc::untranslatable_diagnostic)]
-pub(crate) mod mbe;
-
// HACK(Centril, #64197): These shouldn't really be here.
// Rather, they should be with their respective modules which are defined in other crates.
// However, since for now constructing a `ParseSess` sorta requires `config` from this crate,
diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs
index bd6a9b7cb07da..a805c4fcf7b97 100644
--- a/compiler/rustc_expand/src/mbe.rs
+++ b/compiler/rustc_expand/src/mbe.rs
@@ -4,12 +4,13 @@
//! official terminology: "declarative macros".
pub(crate) mod diagnostics;
-pub(crate) mod macro_check;
-pub(crate) mod macro_parser;
pub(crate) mod macro_rules;
-pub(crate) mod metavar_expr;
-pub(crate) mod quoted;
-pub(crate) mod transcribe;
+
+mod macro_check;
+mod macro_parser;
+mod metavar_expr;
+mod quoted;
+mod transcribe;
use metavar_expr::MetaVarExpr;
use rustc_ast::token::{Delimiter, NonterminalKind, Token, TokenKind};
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 5d6c3e8aa3a4a..464361cb4020b 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -28,7 +28,8 @@ pub(super) fn failed_to_match_macro<'cx>(
) -> Box {
let psess = &cx.sess.psess;
- // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics.
+ // An error occurred, try the expansion again, tracking the expansion closely for better
+ // diagnostics.
let mut tracker = CollectTrackerAndEmitter::new(cx, sp);
let try_success_result = try_match_macro(psess, name, &arg, lhses, &mut tracker);
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index df2643ad1ddea..470bde232d723 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -157,8 +157,8 @@ pub(super) trait Tracker<'matcher> {
/// This is called before trying to match next MatcherLoc on the current token.
fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {}
- /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called,
- /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
+ /// This is called after an arm has been parsed, either successfully or unsuccessfully. When
+ /// this is called, `before_match_loc` was called at least once (with a `MatcherLoc::Eof`).
fn after_arm(&mut self, _result: &NamedParseResult) {}
/// For tracing.
@@ -169,7 +169,8 @@ pub(super) trait Tracker<'matcher> {
}
}
-/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization.
+/// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to
+/// monomorphization.
pub(super) struct NoopTracker;
impl<'matcher> Tracker<'matcher> for NoopTracker {
@@ -492,7 +493,7 @@ pub fn compile_declarative_macro(
.pop()
.unwrap();
// We don't handle errors here, the driver will abort
- // after parsing/expansion. we can report every error in every macro this way.
+ // after parsing/expansion. We can report every error in every macro this way.
check_emission(check_lhs_nt_follows(sess, def, &tt));
return tt;
}
@@ -528,7 +529,7 @@ pub fn compile_declarative_macro(
check_emission(check_rhs(sess, rhs));
}
- // don't abort iteration early, so that errors for multiple lhses can be reported
+ // Don't abort iteration early, so that errors for multiple lhses can be reported.
for lhs in &lhses {
check_emission(check_lhs_no_empty_seq(sess, slice::from_ref(lhs)));
}
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index dad83984c8b15..011aa95c8a116 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -39,26 +39,32 @@ impl MutVisitor for Marker {
}
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
-enum Frame<'a> {
- Delimited {
- tts: &'a [mbe::TokenTree],
- idx: usize,
- delim: Delimiter,
- span: DelimSpan,
- spacing: DelimSpacing,
- },
- Sequence {
- tts: &'a [mbe::TokenTree],
- idx: usize,
- sep: Option,
- kleene_op: KleeneOp,
- },
+struct Frame<'a> {
+ tts: &'a [mbe::TokenTree],
+ idx: usize,
+ kind: FrameKind,
+}
+
+enum FrameKind {
+ Delimited { delim: Delimiter, span: DelimSpan, spacing: DelimSpacing },
+ Sequence { sep: Option, kleene_op: KleeneOp },
}
impl<'a> Frame<'a> {
- /// Construct a new frame around the delimited set of tokens.
- fn new(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
- Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span, spacing }
+ fn new_delimited(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
+ Frame {
+ tts: &src.tts,
+ idx: 0,
+ kind: FrameKind::Delimited { delim: src.delim, span, spacing },
+ }
+ }
+
+ fn new_sequence(
+ src: &'a mbe::SequenceRepetition,
+ sep: Option,
+ kleene_op: KleeneOp,
+ ) -> Frame<'a> {
+ Frame { tts: &src.tts, idx: 0, kind: FrameKind::Sequence { sep, kleene_op } }
}
}
@@ -66,13 +72,9 @@ impl<'a> Iterator for Frame<'a> {
type Item = &'a mbe::TokenTree;
fn next(&mut self) -> Option<&'a mbe::TokenTree> {
- match self {
- Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => {
- let res = tts.get(*idx);
- *idx += 1;
- res
- }
- }
+ let res = self.tts.get(self.idx);
+ self.idx += 1;
+ res
}
}
@@ -111,13 +113,16 @@ pub(super) fn transcribe<'a>(
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
// choice of spacing values doesn't matter.
- let mut stack: SmallVec<[Frame<'_>; 1]> =
- smallvec![Frame::new(src, src_span, DelimSpacing::new(Spacing::Alone, Spacing::Alone))];
+ let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new_delimited(
+ src,
+ src_span,
+ DelimSpacing::new(Spacing::Alone, Spacing::Alone)
+ )];
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
// `repeats` keeps track of where we are in matching at each level, with the last element being
// the most deeply nested sequence. This is used as a stack.
- let mut repeats = Vec::new();
+ let mut repeats: Vec<(usize, usize)> = Vec::new();
// `result` contains resulting token stream from the TokenTree we just finished processing. At
// the end, this will contain the full result of transcription, but at arbitrary points during
@@ -142,11 +147,12 @@ pub(super) fn transcribe<'a>(
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
// go back to the beginning of the sequence.
- if let Frame::Sequence { idx, sep, .. } = stack.last_mut().unwrap() {
+ let frame = stack.last_mut().unwrap();
+ if let FrameKind::Sequence { sep, .. } = &frame.kind {
let (repeat_idx, repeat_len) = repeats.last_mut().unwrap();
*repeat_idx += 1;
if repeat_idx < repeat_len {
- *idx = 0;
+ frame.idx = 0;
if let Some(sep) = sep {
result.push(TokenTree::Token(sep.clone(), Spacing::Alone));
}
@@ -157,16 +163,16 @@ pub(super) fn transcribe<'a>(
// We are done with the top of the stack. Pop it. Depending on what it was, we do
// different things. Note that the outermost item must be the delimited, wrapped RHS
// that was passed in originally to `transcribe`.
- match stack.pop().unwrap() {
+ match stack.pop().unwrap().kind {
// Done with a sequence. Pop from repeats.
- Frame::Sequence { .. } => {
+ FrameKind::Sequence { .. } => {
repeats.pop();
}
// We are done processing a Delimited. If this is the top-level delimited, we are
// done. Otherwise, we unwind the result_stack to append what we have produced to
// any previous results.
- Frame::Delimited { delim, span, mut spacing, .. } => {
+ FrameKind::Delimited { delim, span, mut spacing, .. } => {
// Hack to force-insert a space after `]` in certain case.
// See discussion of the `hex-literal` crate in #114571.
if delim == Delimiter::Bracket {
@@ -192,7 +198,7 @@ pub(super) fn transcribe<'a>(
// We are descending into a sequence. We first make sure that the matchers in the RHS
// and the matches in `interp` have the same shape. Otherwise, either the caller or the
// macro writer has made a mistake.
- seq @ mbe::TokenTree::Sequence(_, delimited) => {
+ seq @ mbe::TokenTree::Sequence(_, seq_rep) => {
match lockstep_iter_size(seq, interp, &repeats) {
LockstepIterSize::Unconstrained => {
return Err(cx
@@ -233,12 +239,11 @@ pub(super) fn transcribe<'a>(
// The first time we encounter the sequence we push it to the stack. It
// then gets reused (see the beginning of the loop) until we are done
// repeating.
- stack.push(Frame::Sequence {
- idx: 0,
- sep: seq.separator.clone(),
- tts: &delimited.tts,
- kleene_op: seq.kleene.op,
- });
+ stack.push(Frame::new_sequence(
+ seq_rep,
+ seq.separator.clone(),
+ seq.kleene.op,
+ ));
}
}
}
@@ -294,13 +299,7 @@ pub(super) fn transcribe<'a>(
// the previous results (from outside the Delimited).
mbe::TokenTree::Delimited(mut span, spacing, delimited) => {
mut_visit::visit_delim_span(&mut span, &mut marker);
- stack.push(Frame::Delimited {
- tts: &delimited.tts,
- delim: delimited.delim,
- idx: 0,
- span,
- spacing: *spacing,
- });
+ stack.push(Frame::new_delimited(delimited, span, *spacing));
result_stack.push(mem::take(&mut result));
}
@@ -358,10 +357,13 @@ fn maybe_use_metavar_location(
) -> TokenTree {
let undelimited_seq = matches!(
stack.last(),
- Some(Frame::Sequence {
+ Some(Frame {
tts: [_],
- sep: None,
- kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
+ kind: FrameKind::Sequence {
+ sep: None,
+ kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
+ ..
+ },
..
})
);
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 581d71875bd07..7026425e167c8 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -9,7 +9,7 @@ use rustc_span::DUMMY_SP;
use smallvec::{smallvec, SmallVec};
use thin_vec::ThinVec;
-pub fn placeholder(
+pub(crate) fn placeholder(
kind: AstFragmentKind,
id: ast::NodeId,
vis: Option,
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 15f048ab598c9..8d7489f5f7e60 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -330,20 +330,19 @@ impl DeepRejectCtxt {
}
pub fn consts_may_unify(self, obligation_ct: ty::Const<'_>, impl_ct: ty::Const<'_>) -> bool {
- match impl_ct.kind() {
+ let impl_val = match impl_ct.kind() {
ty::ConstKind::Expr(_)
| ty::ConstKind::Param(_)
| ty::ConstKind::Unevaluated(_)
| ty::ConstKind::Error(_) => {
return true;
}
- ty::ConstKind::Value(_) => {}
+ ty::ConstKind::Value(impl_val) => impl_val,
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
bug!("unexpected impl arg: {:?}", impl_ct)
}
- }
+ };
- let k = impl_ct.kind();
match obligation_ct.kind() {
ty::ConstKind::Param(_) => match self.treat_obligation_params {
TreatParams::ForLookup => false,
@@ -358,10 +357,7 @@ impl DeepRejectCtxt {
ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
true
}
- ty::ConstKind::Value(obl) => match k {
- ty::ConstKind::Value(imp) => obl == imp,
- _ => true,
- },
+ ty::ConstKind::Value(obl_val) => obl_val == impl_val,
ty::ConstKind::Infer(_) => true,
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index b6b6246baa670..42f8a08a9e4ee 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -4,9 +4,9 @@
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
-use core::ops::Deref;
#[cfg(not(no_global_oom_handling))]
use core::ops::{Add, AddAssign};
+use core::ops::{Deref, DerefPure};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::borrow::{Borrow, BorrowMut};
@@ -343,6 +343,9 @@ where
}
}
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for Cow<'_, B> where B::Owned: Borrow {}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for Cow<'_, B> where B: Eq + ToOwned {}
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 7c9f13e30ffb1..2a859ad55eed2 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1382,7 +1382,7 @@ impl String {
/// Shortens this `String` to the specified length.
///
- /// If `new_len` is greater than the string's current length, this has no
+ /// If `new_len` is greater than or equal to the string's current length, this has no
/// effect.
///
/// Note that this method has no effect on the allocated capacity
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index ae0436bc5209e..4b491ffdafa70 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -239,7 +239,7 @@ use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::{PhantomData, Unsize};
use crate::mem::{self, size_of};
-use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn};
+use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
use crate::ptr::{self, NonNull};
mod lazy;
@@ -1452,6 +1452,9 @@ impl Deref for Ref<'_, T> {
}
}
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for Ref<'_, T> {}
+
impl<'b, T: ?Sized> Ref<'b, T> {
/// Copies a `Ref`.
///
@@ -1844,6 +1847,9 @@ impl DerefMut for RefMut<'_, T> {
}
}
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for RefMut<'_, T> {}
+
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'b, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for RefMut<'b, T> {}
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 3318a8ffa5548..d23764abe7a70 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2578,8 +2578,7 @@ extern "rust-intrinsic" {
///
/// Currently such an assertion would always succeed; until Rust decides
/// otherwise, that principle should not be violated.
-#[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
-#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_const_unstable(feature = "const_eval_select", issue = "124625")]
#[rustc_intrinsic]
#[rustc_intrinsic_must_be_overridden]
pub const fn const_eval_select(
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 98cff3493a7ea..955efb9b0f98d 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -1,4 +1,4 @@
-use crate::ops::{Deref, DerefMut};
+use crate::ops::{Deref, DerefMut, DerefPure};
use crate::ptr;
/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
@@ -161,3 +161,6 @@ impl DerefMut for ManuallyDrop {
&mut self.value
}
}
+
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for ManuallyDrop {}
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index f7463d170fd8e..d8fc3b7177f38 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -923,7 +923,7 @@
use crate::cmp;
use crate::fmt;
use crate::hash::{Hash, Hasher};
-use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
+use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver};
#[allow(unused_imports)]
use crate::{
@@ -1684,6 +1684,9 @@ impl> DerefMut for Pin {
}
}
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for Pin {}
+
#[unstable(feature = "receiver_trait", issue = "none")]
impl Receiver for Pin {}
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index cba9ff4485d05..52729ba1f8456 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -64,12 +64,10 @@ r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }
[features]
backtrace = [
- "gimli-symbolize",
'addr2line/rustc-dep-of-std',
'object/rustc-dep-of-std',
'miniz_oxide/rustc-dep-of-std',
]
-gimli-symbolize = []
panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index de9bde51f2a30..4fc82fec0adbc 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -371,9 +371,10 @@ impl f32 {
/// It might have a different sequence of rounding operations than `powf`,
/// so the results are not guaranteed to agree.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -393,9 +394,10 @@ impl f32 {
/// Raises a number to a floating point power.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -444,9 +446,10 @@ impl f32 {
/// Returns `e^(self)`, (the exponential function).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -470,9 +473,10 @@ impl f32 {
/// Returns `2^(self)`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -494,9 +498,10 @@ impl f32 {
/// Returns the natural logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -524,9 +529,10 @@ impl f32 {
/// `self.log2()` can produce more accurate results for base 2, and
/// `self.log10()` can produce more accurate results for base 10.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -548,9 +554,10 @@ impl f32 {
/// Returns the base 2 logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -572,9 +579,10 @@ impl f32 {
/// Returns the base 10 logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -599,9 +607,10 @@ impl f32 {
/// * If `self <= other`: `0.0`
/// * Else: `self - other`
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `fdimf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -637,9 +646,10 @@ impl f32 {
/// Returns the cube root of a number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `cbrtf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -666,9 +676,10 @@ impl f32 {
/// right-angle triangle with other sides having length `x.abs()` and
/// `y.abs()`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `hypotf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -693,9 +704,10 @@ impl f32 {
/// Computes the sine of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -716,9 +728,10 @@ impl f32 {
/// Computes the cosine of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -739,9 +752,10 @@ impl f32 {
/// Computes the tangent of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tanf` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -765,9 +779,10 @@ impl f32 {
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
/// [-1, 1].
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `asinf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -794,9 +809,10 @@ impl f32 {
/// the range [0, pi] or NaN if the number is outside the range
/// [-1, 1].
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `acosf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -822,9 +838,10 @@ impl f32 {
/// Computes the arctangent of a number. Return value is in radians in the
/// range [-pi/2, pi/2];
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `atanf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -854,9 +871,10 @@ impl f32 {
/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `atan2f` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -890,9 +908,10 @@ impl f32 {
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
/// `(sin(x), cos(x))`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `(f32::sin(x),
/// f32::cos(x))`. Note that this might change in the future.
///
@@ -919,9 +938,10 @@ impl f32 {
/// Returns `e^(self) - 1` in a way that is accurate even if the
/// number is close to zero.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `expm1f` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -947,9 +967,10 @@ impl f32 {
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
/// the operations were performed separately.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `log1pf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -975,9 +996,10 @@ impl f32 {
/// Hyperbolic sine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `sinhf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1004,9 +1026,10 @@ impl f32 {
/// Hyperbolic cosine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `coshf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1033,9 +1056,10 @@ impl f32 {
/// Hyperbolic tangent function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tanhf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1062,9 +1086,10 @@ impl f32 {
/// Inverse hyperbolic sine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1089,9 +1114,10 @@ impl f32 {
/// Inverse hyperbolic cosine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1118,9 +1144,10 @@ impl f32 {
/// Inverse hyperbolic tangent function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1143,9 +1170,10 @@ impl f32 {
/// Gamma function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tgammaf` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1171,9 +1199,10 @@ impl f32 {
///
/// The integer part of the tuple indicates the sign of the gamma function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `lgamma_r` from libc on Unix
/// and Windows. Note that this might change in the future.
///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 944186d602c8f..f8c66a3e71752 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -371,9 +371,10 @@ impl f64 {
/// It might have a different sequence of rounding operations than `powf`,
/// so the results are not guaranteed to agree.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -393,9 +394,10 @@ impl f64 {
/// Raises a number to a floating point power.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -444,9 +446,10 @@ impl f64 {
/// Returns `e^(self)`, (the exponential function).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -470,9 +473,10 @@ impl f64 {
/// Returns `2^(self)`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -494,9 +498,10 @@ impl f64 {
/// Returns the natural logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -524,9 +529,10 @@ impl f64 {
/// `self.log2()` can produce more accurate results for base 2, and
/// `self.log10()` can produce more accurate results for base 10.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -548,9 +554,10 @@ impl f64 {
/// Returns the base 2 logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -572,9 +579,10 @@ impl f64 {
/// Returns the base 10 logarithm of the number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -599,9 +607,10 @@ impl f64 {
/// * If `self <= other`: `0.0`
/// * Else: `self - other`
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `fdim` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -637,9 +646,10 @@ impl f64 {
/// Returns the cube root of a number.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `cbrt` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -666,9 +676,10 @@ impl f64 {
/// right-angle triangle with other sides having length `x.abs()` and
/// `y.abs()`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `hypot` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -693,9 +704,10 @@ impl f64 {
/// Computes the sine of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -716,9 +728,10 @@ impl f64 {
/// Computes the cosine of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -739,9 +752,10 @@ impl f64 {
/// Computes the tangent of a number (in radians).
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tan` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -765,9 +779,10 @@ impl f64 {
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
/// [-1, 1].
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `asin` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -794,9 +809,10 @@ impl f64 {
/// the range [0, pi] or NaN if the number is outside the range
/// [-1, 1].
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `acos` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -822,9 +838,10 @@ impl f64 {
/// Computes the arctangent of a number. Return value is in radians in the
/// range [-pi/2, pi/2];
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `atan` from libc on Unix and
/// Windows. Note that this might change in the future.
///
@@ -854,9 +871,10 @@ impl f64 {
/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `atan2` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -890,9 +908,10 @@ impl f64 {
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
/// `(sin(x), cos(x))`.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `(f64::sin(x),
/// f64::cos(x))`. Note that this might change in the future.
///
@@ -919,9 +938,10 @@ impl f64 {
/// Returns `e^(self) - 1` in a way that is accurate even if the
/// number is close to zero.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `expm1` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -947,9 +967,10 @@ impl f64 {
/// Returns `ln(1+n)` (natural logarithm) more accurately than if
/// the operations were performed separately.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `log1p` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -975,9 +996,10 @@ impl f64 {
/// Hyperbolic sine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `sinh` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1004,9 +1026,10 @@ impl f64 {
/// Hyperbolic cosine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `cosh` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1033,9 +1056,10 @@ impl f64 {
/// Hyperbolic tangent function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tanh` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1062,9 +1086,10 @@ impl f64 {
/// Inverse hyperbolic sine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1089,9 +1114,10 @@ impl f64 {
/// Inverse hyperbolic cosine function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1118,9 +1144,10 @@ impl f64 {
/// Inverse hyperbolic tangent function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
///
/// # Examples
///
@@ -1143,9 +1170,10 @@ impl f64 {
/// Gamma function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `tgamma` from libc on Unix
/// and Windows. Note that this might change in the future.
///
@@ -1171,9 +1199,10 @@ impl f64 {
///
/// The integer part of the tuple indicates the sign of the gamma function.
///
- /// # Platform-specific precision
+ /// # Unspecified precision
///
- /// The precision of this function varies by platform and Rust version.
+ /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
+ /// can even differ within the same execution from one invocation to the next.
/// This function currently corresponds to the `lgamma_r` from libc on Unix
/// and Windows. Note that this might change in the future.
///
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 98973a43e1ded..a3fdcdc2d07ba 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -266,7 +266,7 @@
//! its file descriptors with no operations being performed by any other part of the program.
//!
//! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the
-//! underlying kernel object that the file descriptor references (also called "file description" on
+//! underlying kernel object that the file descriptor references (also called "open file description" on
//! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned
//! file descriptor, you cannot know whether there are any other file descriptors that reference the
//! same kernel object. However, when you create a new kernel object, you know that you are holding
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index 827278f8b2605..6d4090ee31cfc 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -12,8 +12,8 @@
//! | Type | Analogous to |
//! | ------------------ | ------------ |
//! | [`RawFd`] | `*const _` |
-//! | [`BorrowedFd<'a>`] | `&'a _` |
-//! | [`OwnedFd`] | `Box<_>` |
+//! | [`BorrowedFd<'a>`] | `&'a Arc<_>` |
+//! | [`OwnedFd`] | `Arc<_>` |
//!
//! Like raw pointers, `RawFd` values are primitive values. And in new code,
//! they should be considered unsafe to do I/O on (analogous to dereferencing
@@ -23,22 +23,31 @@
//! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
//! using to `BorrowedFd` or `OwnedFd` instead.
//!
+//! The use of `Arc` for borrowed/owned file descriptors may be surprising. Unix file descriptors
+//! are mere references to internal kernel objects called "open file descriptions", and the same
+//! open file description can be referenced by multiple file descriptors (e.g. if `dup` is used).
+//! State such as the offset within the file is shared among all file descriptors that refer to the
+//! same open file description, and the kernel internally does reference-counting to only close the
+//! underlying resource once all file descriptors referencing it are closed. That's why `Arc` (and
+//! not `Box`) is the closest Rust analogy to an "owned" file descriptor.
+//!
//! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
//! that they don't outlive the resource they point to. These are safe to
//! use. `BorrowedFd` values may be used in APIs which provide safe access to
//! any system call except for:
//!
//! - `close`, because that would end the dynamic lifetime of the resource
-//! without ending the lifetime of the file descriptor.
+//! without ending the lifetime of the file descriptor. (Equivalently:
+//! an `&Arc<_>` cannot be `drop`ed.)
//!
//! - `dup2`/`dup3`, in the second argument, because this argument is
-//! closed and assigned a new resource, which may break the assumptions
+//! closed and assigned a new resource, which may break the assumptions of
//! other code using that file descriptor.
//!
-//! `BorrowedFd` values may be used in APIs which provide safe access to `dup`
-//! system calls, so types implementing `AsFd` or `From` should not
-//! assume they always have exclusive access to the underlying file
-//! description.
+//! `BorrowedFd` values may be used in APIs which provide safe access to `dup` system calls, so code
+//! working with `OwnedFd` cannot assume to have exclusive access to the underlying open file
+//! description. (Equivalently: `&Arc` may be used in APIs that provide safe access to `clone`, so
+//! code working with an `Arc` cannot assume that the reference count is 1.)
//!
//! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the
//! provided file descriptor in a manner similar to `dup` and does not require
@@ -52,8 +61,10 @@
//! take full responsibility for ensuring that safe Rust code cannot evoke
//! undefined behavior through it.
//!
-//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
-//! and free (close) it when they are dropped.
+//! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to,
+//! and decrement the reference count when they are dropped (by calling `close`).
+//! When the reference count reaches 0, the underlying open file description will be freed
+//! by the kernel.
//!
//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
//!
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
index a2d51902652bc..146123793be40 100644
--- a/src/tools/run-make-support/src/cc.rs
+++ b/src/tools/run-make-support/src/cc.rs
@@ -161,8 +161,9 @@ pub fn extra_cxx_flags() -> Vec<&'static str> {
if is_windows() {
if is_msvc() { vec![] } else { vec!["-lstdc++"] }
} else {
- match uname() {
- n if n.contains("Darwin") => vec!["-lc++"],
+ match &uname()[..] {
+ "Darwin" => vec!["-lc++"],
+ "FreeBSD" | "SunOS" | "OpenBSD" => vec![],
_ => vec!["-lstdc++"],
}
}