Skip to content

Commit 8e5a277

Browse files
committed
Auto merge of rust-lang#75510 - tmandry:rollup-tb9mllu, r=tmandry
Rollup of 12 pull requests Successful merges: - rust-lang#74650 (Correctly parse `{} && false` in tail expression) - rust-lang#75319 (Fix ICE rust-lang#75307 in `format`) - rust-lang#75417 (Don't spill operands onto the stack in naked functions) - rust-lang#75452 (self-profile: Cache more query key strings when doing self-profiling.) - rust-lang#75459 (fix LocalInfo doc comment) - rust-lang#75462 (Remove unused tcx parameter) - rust-lang#75467 (Fix E0741 error code explanation) - rust-lang#75471 (Change registered "program name" for -Cllvm-args usage messages) - rust-lang#75477 (Expand function pointer docs) - rust-lang#75479 (make rustc-docs component available to rustup) - rust-lang#75496 (Prioritization WG: Open Zulip topics only for `I-prioritize` issues) - rust-lang#75500 (Disable zlib in LLVM on aarch64-apple-darwin) Failed merges: r? @ghost
2 parents 81dc88f + e8acafd commit 8e5a277

File tree

28 files changed

+235
-219
lines changed

28 files changed

+235
-219
lines changed

library/std/src/primitive_docs.rs

+48-9
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,8 @@ mod prim_ref {}
10581058
/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null
10591059
/// pointers, make your type `Option<fn()>` with your required signature.
10601060
///
1061+
/// ### Safety
1062+
///
10611063
/// Plain function pointers are obtained by casting either plain functions, or closures that don't
10621064
/// capture an environment:
10631065
///
@@ -1095,23 +1097,60 @@ mod prim_ref {}
10951097
/// let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
10961098
/// ```
10971099
///
1098-
/// On top of that, function pointers can vary based on what ABI they use. This is achieved by
1099-
/// adding the `extern` keyword to the type name, followed by the ABI in question. For example,
1100-
/// `fn()` is different from `extern "C" fn()`, which itself is different from `extern "stdcall"
1101-
/// fn()`, and so on for the various ABIs that Rust supports. Non-`extern` functions have an ABI
1102-
/// of `"Rust"`, and `extern` functions without an explicit ABI have an ABI of `"C"`. For more
1103-
/// information, see [the nomicon's section on foreign calling conventions][nomicon-abi].
1100+
/// ### ABI
1101+
///
1102+
/// On top of that, function pointers can vary based on what ABI they use. This
1103+
/// is achieved by adding the `extern` keyword before the type, followed by the
1104+
/// ABI in question. The default ABI is "Rust", i.e., `fn()` is the exact same
1105+
/// type as `extern "Rust" fn()`. A pointer to a function with C ABI would have
1106+
/// type `extern "C" fn()`.
1107+
///
1108+
/// `extern "ABI" { ... }` blocks declare functions with ABI "ABI". The default
1109+
/// here is "C", i.e., functions declared in an `extern {...}` block have "C"
1110+
/// ABI.
1111+
///
1112+
/// For more information and a list of supported ABIs, see [the nomicon's
1113+
/// section on foreign calling conventions][nomicon-abi].
11041114
///
1105-
/// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions
1115+
/// ### Variadic functions
11061116
///
11071117
/// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them
1108-
/// to be called with a variable number of arguments. Normal rust functions, even those with an
1118+
/// to be called with a variable number of arguments. Normal Rust functions, even those with an
11091119
/// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on
11101120
/// variadic functions][nomicon-variadic].
11111121
///
11121122
/// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions
11131123
///
1114-
/// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type.
1124+
/// ### Creating function pointers
1125+
///
1126+
/// When `bar` is the name of a function, then the expression `bar` is *not* a
1127+
/// function pointer. Rather, it denotes a value of an unnameable type that
1128+
/// uniquely identifies the function `bar`. The value is zero-sized because the
1129+
/// type already identifies the function. This has the advantage that "calling"
1130+
/// the value (it implements the `Fn*` traits) does not require dynamic
1131+
/// dispatch.
1132+
///
1133+
/// This zero-sized type *coerces* to a regular function pointer. For example:
1134+
///
1135+
/// ```rust
1136+
/// use std::mem;
1137+
///
1138+
/// fn bar(x: i32) {}
1139+
///
1140+
/// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar`
1141+
/// assert_eq!(mem::size_of_val(&not_bar_ptr), 0);
1142+
///
1143+
/// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer
1144+
/// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());
1145+
///
1146+
/// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar`
1147+
/// ```
1148+
///
1149+
/// The last line shows that `&bar` is not a function pointer either. Rather, it
1150+
/// is a reference to the function-specific ZST. `&bar` is basically never what you
1151+
/// want when `bar` is a function.
1152+
///
1153+
/// ### Traits
11151154
///
11161155
/// Function pointers implement the following traits:
11171156
///

src/bootstrap/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl Step for Llvm {
178178
.define("LLVM_TARGET_ARCH", target_native.split('-').next().unwrap())
179179
.define("LLVM_DEFAULT_TARGET_TRIPLE", target_native);
180180

181-
if !target.contains("netbsd") {
181+
if !target.contains("netbsd") && target != "aarch64-apple-darwin" {
182182
cfg.define("LLVM_ENABLE_ZLIB", "ON");
183183
} else {
184184
// FIXME: Enable zlib on NetBSD too

src/librustc_ast/util/parser.rs

-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ impl AssocOp {
222222
Greater | // `{ 42 } > 3`
223223
GreaterEqual | // `{ 42 } >= 3`
224224
AssignOp(_) | // `{ 42 } +=`
225-
LAnd | // `{ 42 } &&foo`
226225
As | // `{ 42 } as usize`
227226
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
228227
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.

src/librustc_builtin_macros/format.rs

+13-20
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn parse_args<'a>(
149149
return Err(err);
150150
} else {
151151
// ...after that delegate to `expect` to also include the other expected tokens.
152-
return Err(p.expect(&token::Comma).err().unwrap());
152+
let _ = p.expect(&token::Comma)?;
153153
}
154154
}
155155
first = false;
@@ -359,24 +359,18 @@ impl<'a, 'b> Context<'a, 'b> {
359359
// for `println!("{7:7$}", 1);`
360360
refs.sort();
361361
refs.dedup();
362-
let (arg_list, mut sp) = if refs.len() == 1 {
363-
let spans: Vec<_> = spans.into_iter().filter_map(|sp| sp.copied()).collect();
364-
(
365-
format!("argument {}", refs[0]),
366-
if spans.is_empty() {
367-
MultiSpan::from_span(self.fmtsp)
368-
} else {
369-
MultiSpan::from_spans(spans)
370-
},
371-
)
362+
let spans: Vec<_> = spans.into_iter().filter_map(|sp| sp.copied()).collect();
363+
let sp = if self.arg_spans.is_empty() || spans.is_empty() {
364+
MultiSpan::from_span(self.fmtsp)
365+
} else {
366+
MultiSpan::from_spans(spans)
367+
};
368+
let arg_list = if refs.len() == 1 {
369+
format!("argument {}", refs[0])
372370
} else {
373-
let pos = MultiSpan::from_spans(spans.into_iter().map(|s| *s.unwrap()).collect());
374371
let reg = refs.pop().unwrap();
375-
(format!("arguments {head} and {tail}", head = refs.join(", "), tail = reg,), pos)
372+
format!("arguments {head} and {tail}", head = refs.join(", "), tail = reg)
376373
};
377-
if self.arg_spans.is_empty() {
378-
sp = MultiSpan::from_span(self.fmtsp);
379-
}
380374

381375
e = self.ecx.struct_span_err(
382376
sp,
@@ -1067,10 +1061,9 @@ pub fn expand_preparsed_format_args(
10671061
let args_unused = errs_len;
10681062

10691063
let mut diag = {
1070-
if errs_len == 1 {
1071-
let (sp, msg) = errs.into_iter().next().unwrap();
1072-
let mut diag = cx.ecx.struct_span_err(sp, msg);
1073-
diag.span_label(sp, msg);
1064+
if let [(sp, msg)] = &errs[..] {
1065+
let mut diag = cx.ecx.struct_span_err(*sp, *msg);
1066+
diag.span_label(*sp, *msg);
10741067
diag
10751068
} else {
10761069
let mut diag = cx.ecx.struct_span_err(

src/librustc_codegen_llvm/llvm_util.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ unsafe fn configure_llvm(sess: &Session) {
7373
llvm_c_strs.push(s);
7474
}
7575
};
76-
add("rustc", true); // fake program name
76+
// Set the llvm "program name" to make usage and invalid argument messages more clear.
77+
add("rustc -Cllvm-args=\"...\" with", true);
7778
if sess.time_llvm_passes() {
7879
add("-time-passes", false);
7980
}

src/librustc_codegen_ssa/mir/debuginfo.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::traits::*;
22
use rustc_hir::def_id::CrateNum;
33
use rustc_index::vec::IndexVec;
4+
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
45
use rustc_middle::mir;
56
use rustc_middle::ty;
67
use rustc_session::config::DebugInfo;
@@ -216,6 +217,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
216217
LocalRef::Operand(None) => return,
217218

218219
LocalRef::Operand(Some(operand)) => {
220+
// Don't spill operands onto the stack in naked functions.
221+
// See: https://github.com/rust-lang/rust/issues/42779
222+
let attrs = bx.tcx().codegen_fn_attrs(self.instance.def_id());
223+
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
224+
return;
225+
}
226+
219227
// "Spill" the value onto the stack, for debuginfo,
220228
// without forcing non-debuginfo uses of the local
221229
// to also load from the stack every single time.

src/librustc_error_codes/error_codes/E0477.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ fn i_want_static_closure<F>(a: F)
3737
3838
fn print_string(s: Mutex<MyString<'static>>) {
3939
40-
i_want_static_closure(move || { // error: this closure has lifetime 'a
41-
// rather than 'static
40+
i_want_static_closure(move || { // ok!
4241
println!("{}", s.lock().unwrap().data);
4342
});
4443
}

src/librustc_middle/mir/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -857,9 +857,12 @@ pub struct LocalDecl<'tcx> {
857857
#[cfg(target_arch = "x86_64")]
858858
static_assert_size!(LocalDecl<'_>, 56);
859859

860-
/// Extra information about a some locals that's used for diagnostics. (Not
861-
/// used for non-StaticRef temporaries, the return place, or anonymous function
862-
/// parameters.)
860+
/// Extra information about a some locals that's used for diagnostics and for
861+
/// classifying variables into local variables, statics, etc, which is needed e.g.
862+
/// for unsafety checking.
863+
///
864+
/// Not used for non-StaticRef temporaries, the return place, or anonymous
865+
/// function parameters.
863866
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
864867
pub enum LocalInfo<'tcx> {
865868
/// A user-defined local variable or function parameter

src/librustc_middle/ty/query/profiling_support.rs

+45-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::ty::context::TyCtxt;
2+
use crate::ty::WithOptConstParam;
23
use measureme::{StringComponent, StringId};
34
use rustc_data_structures::fx::FxHashMap;
45
use rustc_data_structures::profiling::SelfProfiler;
5-
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
6+
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
67
use rustc_hir::definitions::DefPathData;
78
use rustc_query_system::query::QueryCache;
89
use rustc_query_system::query::QueryState;
@@ -154,6 +155,49 @@ impl SpecIntoSelfProfilingString for DefIndex {
154155
}
155156
}
156157

158+
impl SpecIntoSelfProfilingString for LocalDefId {
159+
fn spec_to_self_profile_string(
160+
&self,
161+
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
162+
) -> StringId {
163+
builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: self.local_def_index })
164+
}
165+
}
166+
167+
impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> {
168+
fn spec_to_self_profile_string(
169+
&self,
170+
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
171+
) -> StringId {
172+
// We print `WithOptConstParam` values as tuples to make them shorter
173+
// and more readable, without losing information:
174+
//
175+
// "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }"
176+
// becomes "(foo::bar, foo::baz)" and
177+
// "WithOptConstParam { did: foo::bar, const_param_did: None }"
178+
// becomes "(foo::bar, _)".
179+
180+
let did = StringComponent::Ref(self.did.to_self_profile_string(builder));
181+
182+
let const_param_did = if let Some(const_param_did) = self.const_param_did {
183+
let const_param_did = builder.def_id_to_string_id(const_param_did);
184+
StringComponent::Ref(const_param_did)
185+
} else {
186+
StringComponent::Value("_")
187+
};
188+
189+
let components = [
190+
StringComponent::Value("("),
191+
did,
192+
StringComponent::Value(", "),
193+
const_param_did,
194+
StringComponent::Value(")"),
195+
];
196+
197+
builder.profiler.alloc_string(&components[..])
198+
}
199+
}
200+
157201
impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1)
158202
where
159203
T0: SpecIntoSelfProfilingString,

src/librustc_mir_build/build/mod.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_hir::lang_items;
1010
use rustc_hir::{GeneratorKind, HirIdMap, Node};
1111
use rustc_index::vec::{Idx, IndexVec};
1212
use rustc_infer::infer::TyCtxtInferExt;
13-
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1413
use rustc_middle::middle::region;
1514
use rustc_middle::mir::*;
1615
use rustc_middle::ty::subst::Subst;
@@ -798,22 +797,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
798797
argument_scope: region::Scope,
799798
ast_body: &'tcx hir::Expr<'tcx>,
800799
) -> BlockAnd<()> {
801-
let tcx = self.hir.tcx();
802-
let attrs = tcx.codegen_fn_attrs(fn_def_id);
803-
let naked = attrs.flags.contains(CodegenFnAttrFlags::NAKED);
804-
805800
// Allocate locals for the function arguments
806801
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
807802
let source_info =
808803
SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span));
809804
let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));
810805

811-
// Emit function argument debuginfo only for non-naked functions.
812-
// See: https://github.com/rust-lang/rust/issues/42779
813-
if naked {
814-
continue;
815-
}
816-
817806
// If this is a simple binding pattern, give debuginfo a nice name.
818807
if let Some(arg) = arg_opt {
819808
if let Some(ident) = arg.pat.simple_ident() {
@@ -826,6 +815,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
826815
}
827816
}
828817

818+
let tcx = self.hir.tcx();
829819
let tcx_hir = tcx.hir();
830820
let hir_typeck_results = self.hir.typeck_results();
831821

src/librustc_parse/parser/expr.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,18 @@ impl<'a> Parser<'a> {
318318
// want to keep their span info to improve diagnostics in these cases in a later stage.
319319
(true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
320320
(true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
321-
(true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475)
322321
(true, Some(AssocOp::Add)) // `{ 42 } + 42
323322
// If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
324323
// `if x { a } else { b } && if y { c } else { d }`
325-
if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
324+
if !self.look_ahead(1, |t| t.is_used_keyword()) => {
325+
// These cases are ambiguous and can't be identified in the parser alone.
326+
let sp = self.sess.source_map().start_point(self.token.span);
327+
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
328+
false
329+
}
330+
(true, Some(AssocOp::LAnd)) => {
331+
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
332+
// above due to #74233.
326333
// These cases are ambiguous and can't be identified in the parser alone.
327334
let sp = self.sess.source_map().start_point(self.token.span);
328335
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);

src/librustc_query_system/query/caches.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ pub trait QueryCache: QueryStorage {
4343
OnHit: FnOnce(&Self::Stored, DepNodeIndex) -> R,
4444
OnMiss: FnOnce(Self::Key, QueryLookup<'_, CTX, Self::Key, Self::Sharded>) -> R;
4545

46-
fn complete<CTX: QueryContext>(
46+
fn complete(
4747
&self,
48-
tcx: CTX,
4948
lock_sharded_storage: &mut Self::Sharded,
5049
key: Self::Key,
5150
value: Self::Value,
@@ -112,9 +111,8 @@ impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
112111
}
113112

114113
#[inline]
115-
fn complete<CTX: QueryContext>(
114+
fn complete(
116115
&self,
117-
_: CTX,
118116
lock_sharded_storage: &mut Self::Sharded,
119117
key: K,
120118
value: V,
@@ -195,9 +193,8 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> QueryCache for ArenaCache<'tcx, K, V> {
195193
}
196194

197195
#[inline]
198-
fn complete<CTX: QueryContext>(
196+
fn complete(
199197
&self,
200-
_: CTX,
201198
lock_sharded_storage: &mut Self::Sharded,
202199
key: K,
203200
value: V,

0 commit comments

Comments
 (0)