Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 12 pull requests #75510

Merged
merged 25 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9b5a974
Correctly parse `{} && false` in tail expression
estebank Jul 22, 2020
0a4f4e8
Fix ICE #75307 in `format`
estebank Aug 9, 2020
0356bb9
Revert "Suppress debuginfo on naked function arguments"
npmccallum Aug 11, 2020
050fb38
Don't spill operands onto the stack in naked functions
npmccallum Aug 11, 2020
0e26f9b
fix LocalInfo doc comment
RalfJung Aug 12, 2020
bff104d
Remove unused tcx parameter
Mark-Simulacrum Aug 12, 2020
b38e571
Fix E0741 error code explanation
rubenrua Aug 12, 2020
d4593af
Change registered "program name" for -Cllvm-args usage messages
richkadel Aug 12, 2020
2100e67
make rustc-docs component available to rustup
matthiaskrgr Aug 13, 2020
08d9517
self-profile: Cache more query key strings when doing self-profiling.
michaelwoerister Aug 11, 2020
2338903
fn type: structure, and talk a bit more about ABIs and how to create …
RalfJung Aug 13, 2020
264434f
Prioritization WG: Open Zulip topics only for `I-prioritize` issues
spastorino Aug 13, 2020
9302c17
Disable zlib in LLVM on aarch64-apple-darwin
glandium Aug 13, 2020
5b5eec7
Rollup merge of #74650 - estebank:ambiguous-expr-binop, r=eddyb
tmandry Aug 14, 2020
8c361aa
Rollup merge of #75319 - estebank:format-ice, r=eddyb
tmandry Aug 14, 2020
1f73e89
Rollup merge of #75417 - npmccallum:naked, r=matthewjasper
tmandry Aug 14, 2020
6f964f0
Rollup merge of #75452 - michaelwoerister:sp-cache-more-query-keys, r…
tmandry Aug 14, 2020
c76259a
Rollup merge of #75459 - RalfJung:local-info, r=oli-obk
tmandry Aug 14, 2020
84f7991
Rollup merge of #75462 - Mark-Simulacrum:clean-queries, r=petrochenkov
tmandry Aug 14, 2020
b4966a8
Rollup merge of #75467 - rubenrua:rubenrua-patch-E0477, r=oli-obk
tmandry Aug 14, 2020
d000fb1
Rollup merge of #75471 - richkadel:llvm-program-name, r=wesleywiser
tmandry Aug 14, 2020
33fca5a
Rollup merge of #75477 - RalfJung:fn-ptrs, r=Mark-Simulacrum
tmandry Aug 14, 2020
9cbc031
Rollup merge of #75479 - matthiaskrgr:package_docs, r=Mark-Simulacrum
tmandry Aug 14, 2020
912b5b3
Rollup merge of #75496 - spastorino:prioritization-zulip-topics, r=Ma…
tmandry Aug 14, 2020
e8acafd
Rollup merge of #75500 - glandium:arm64-mac-zlib, r=Mark-Simulacrum
tmandry Aug 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions library/std/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,8 @@ mod prim_ref {}
/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null
/// pointers, make your type `Option<fn()>` with your required signature.
///
/// ### Safety
///
/// Plain function pointers are obtained by casting either plain functions, or closures that don't
/// capture an environment:
///
Expand Down Expand Up @@ -1095,23 +1097,60 @@ mod prim_ref {}
/// let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
/// ```
///
/// On top of that, function pointers can vary based on what ABI they use. This is achieved by
/// adding the `extern` keyword to the type name, followed by the ABI in question. For example,
/// `fn()` is different from `extern "C" fn()`, which itself is different from `extern "stdcall"
/// fn()`, and so on for the various ABIs that Rust supports. Non-`extern` functions have an ABI
/// of `"Rust"`, and `extern` functions without an explicit ABI have an ABI of `"C"`. For more
/// information, see [the nomicon's section on foreign calling conventions][nomicon-abi].
/// ### ABI
///
/// On top of that, function pointers can vary based on what ABI they use. This
/// is achieved by adding the `extern` keyword before the type, followed by the
/// ABI in question. The default ABI is "Rust", i.e., `fn()` is the exact same
/// type as `extern "Rust" fn()`. A pointer to a function with C ABI would have
/// type `extern "C" fn()`.
///
/// `extern "ABI" { ... }` blocks declare functions with ABI "ABI". The default
/// here is "C", i.e., functions declared in an `extern {...}` block have "C"
/// ABI.
///
/// For more information and a list of supported ABIs, see [the nomicon's
/// section on foreign calling conventions][nomicon-abi].
///
/// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions
/// ### Variadic functions
///
/// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them
/// to be called with a variable number of arguments. Normal rust functions, even those with an
/// to be called with a variable number of arguments. Normal Rust functions, even those with an
/// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on
/// variadic functions][nomicon-variadic].
///
/// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions
///
/// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type.
/// ### Creating function pointers
///
/// When `bar` is the name of a function, then the expression `bar` is *not* a
/// function pointer. Rather, it denotes a value of an unnameable type that
/// uniquely identifies the function `bar`. The value is zero-sized because the
/// type already identifies the function. This has the advantage that "calling"
/// the value (it implements the `Fn*` traits) does not require dynamic
/// dispatch.
///
/// This zero-sized type *coerces* to a regular function pointer. For example:
///
/// ```rust
/// use std::mem;
///
/// fn bar(x: i32) {}
///
/// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar`
/// assert_eq!(mem::size_of_val(&not_bar_ptr), 0);
///
/// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer
/// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());
///
/// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar`
/// ```
///
/// The last line shows that `&bar` is not a function pointer either. Rather, it
/// is a reference to the function-specific ZST. `&bar` is basically never what you
/// want when `bar` is a function.
///
/// ### Traits
///
/// Function pointers implement the following traits:
///
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl Step for Llvm {
.define("LLVM_TARGET_ARCH", target_native.split('-').next().unwrap())
.define("LLVM_DEFAULT_TARGET_TRIPLE", target_native);

if !target.contains("netbsd") {
if !target.contains("netbsd") && target != "aarch64-apple-darwin" {
cfg.define("LLVM_ENABLE_ZLIB", "ON");
} else {
// FIXME: Enable zlib on NetBSD too
Expand Down
1 change: 0 additions & 1 deletion src/librustc_ast/util/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ impl AssocOp {
Greater | // `{ 42 } > 3`
GreaterEqual | // `{ 42 } >= 3`
AssignOp(_) | // `{ 42 } +=`
LAnd | // `{ 42 } &&foo`
As | // `{ 42 } as usize`
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
Expand Down
33 changes: 13 additions & 20 deletions src/librustc_builtin_macros/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ fn parse_args<'a>(
return Err(err);
} else {
// ...after that delegate to `expect` to also include the other expected tokens.
return Err(p.expect(&token::Comma).err().unwrap());
let _ = p.expect(&token::Comma)?;
}
}
first = false;
Expand Down Expand Up @@ -359,24 +359,18 @@ impl<'a, 'b> Context<'a, 'b> {
// for `println!("{7:7$}", 1);`
refs.sort();
refs.dedup();
let (arg_list, mut sp) = if refs.len() == 1 {
let spans: Vec<_> = spans.into_iter().filter_map(|sp| sp.copied()).collect();
(
format!("argument {}", refs[0]),
if spans.is_empty() {
MultiSpan::from_span(self.fmtsp)
} else {
MultiSpan::from_spans(spans)
},
)
let spans: Vec<_> = spans.into_iter().filter_map(|sp| sp.copied()).collect();
let sp = if self.arg_spans.is_empty() || spans.is_empty() {
MultiSpan::from_span(self.fmtsp)
} else {
MultiSpan::from_spans(spans)
};
let arg_list = if refs.len() == 1 {
format!("argument {}", refs[0])
} else {
let pos = MultiSpan::from_spans(spans.into_iter().map(|s| *s.unwrap()).collect());
let reg = refs.pop().unwrap();
(format!("arguments {head} and {tail}", head = refs.join(", "), tail = reg,), pos)
format!("arguments {head} and {tail}", head = refs.join(", "), tail = reg)
};
if self.arg_spans.is_empty() {
sp = MultiSpan::from_span(self.fmtsp);
}

e = self.ecx.struct_span_err(
sp,
Expand Down Expand Up @@ -1067,10 +1061,9 @@ pub fn expand_preparsed_format_args(
let args_unused = errs_len;

let mut diag = {
if errs_len == 1 {
let (sp, msg) = errs.into_iter().next().unwrap();
let mut diag = cx.ecx.struct_span_err(sp, msg);
diag.span_label(sp, msg);
if let [(sp, msg)] = &errs[..] {
let mut diag = cx.ecx.struct_span_err(*sp, *msg);
diag.span_label(*sp, *msg);
diag
} else {
let mut diag = cx.ecx.struct_span_err(
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_codegen_llvm/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ unsafe fn configure_llvm(sess: &Session) {
llvm_c_strs.push(s);
}
};
add("rustc", true); // fake program name
// Set the llvm "program name" to make usage and invalid argument messages more clear.
add("rustc -Cllvm-args=\"...\" with", true);
if sess.time_llvm_passes() {
add("-time-passes", false);
}
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_codegen_ssa/mir/debuginfo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::traits::*;
use rustc_hir::def_id::CrateNum;
use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
use rustc_session::config::DebugInfo;
Expand Down Expand Up @@ -216,6 +217,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
LocalRef::Operand(None) => return,

LocalRef::Operand(Some(operand)) => {
// Don't spill operands onto the stack in naked functions.
// See: https://github.com/rust-lang/rust/issues/42779
let attrs = bx.tcx().codegen_fn_attrs(self.instance.def_id());
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
return;
}

// "Spill" the value onto the stack, for debuginfo,
// without forcing non-debuginfo uses of the local
// to also load from the stack every single time.
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_error_codes/error_codes/E0477.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ fn i_want_static_closure<F>(a: F)

fn print_string(s: Mutex<MyString<'static>>) {

i_want_static_closure(move || { // error: this closure has lifetime 'a
// rather than 'static
i_want_static_closure(move || { // ok!
println!("{}", s.lock().unwrap().data);
});
}
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_middle/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,9 +857,12 @@ pub struct LocalDecl<'tcx> {
#[cfg(target_arch = "x86_64")]
static_assert_size!(LocalDecl<'_>, 56);

/// Extra information about a some locals that's used for diagnostics. (Not
/// used for non-StaticRef temporaries, the return place, or anonymous function
/// parameters.)
/// Extra information about a some locals that's used for diagnostics and for
/// classifying variables into local variables, statics, etc, which is needed e.g.
/// for unsafety checking.
///
/// Not used for non-StaticRef temporaries, the return place, or anonymous
/// function parameters.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
pub enum LocalInfo<'tcx> {
/// A user-defined local variable or function parameter
Expand Down
46 changes: 45 additions & 1 deletion src/librustc_middle/ty/query/profiling_support.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::ty::context::TyCtxt;
use crate::ty::WithOptConstParam;
use measureme::{StringComponent, StringId};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfiler;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
use rustc_query_system::query::QueryCache;
use rustc_query_system::query::QueryState;
Expand Down Expand Up @@ -154,6 +155,49 @@ impl SpecIntoSelfProfilingString for DefIndex {
}
}

impl SpecIntoSelfProfilingString for LocalDefId {
fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: self.local_def_index })
}
}

impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> {
fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
// We print `WithOptConstParam` values as tuples to make them shorter
// and more readable, without losing information:
//
// "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }"
// becomes "(foo::bar, foo::baz)" and
// "WithOptConstParam { did: foo::bar, const_param_did: None }"
// becomes "(foo::bar, _)".

let did = StringComponent::Ref(self.did.to_self_profile_string(builder));

let const_param_did = if let Some(const_param_did) = self.const_param_did {
let const_param_did = builder.def_id_to_string_id(const_param_did);
StringComponent::Ref(const_param_did)
} else {
StringComponent::Value("_")
};

let components = [
StringComponent::Value("("),
did,
StringComponent::Value(", "),
const_param_did,
StringComponent::Value(")"),
];

builder.profiler.alloc_string(&components[..])
}
}

impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1)
where
T0: SpecIntoSelfProfilingString,
Expand Down
12 changes: 1 addition & 11 deletions src/librustc_mir_build/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use rustc_hir::lang_items;
use rustc_hir::{GeneratorKind, HirIdMap, Node};
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use rustc_middle::ty::subst::Subst;
Expand Down Expand Up @@ -798,22 +797,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
argument_scope: region::Scope,
ast_body: &'tcx hir::Expr<'tcx>,
) -> BlockAnd<()> {
let tcx = self.hir.tcx();
let attrs = tcx.codegen_fn_attrs(fn_def_id);
let naked = attrs.flags.contains(CodegenFnAttrFlags::NAKED);

// Allocate locals for the function arguments
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
let source_info =
SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span));
let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));

// Emit function argument debuginfo only for non-naked functions.
// See: https://github.com/rust-lang/rust/issues/42779
if naked {
continue;
}

// If this is a simple binding pattern, give debuginfo a nice name.
if let Some(arg) = arg_opt {
if let Some(ident) = arg.pat.simple_ident() {
Expand All @@ -826,6 +815,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

let tcx = self.hir.tcx();
let tcx_hir = tcx.hir();
let hir_typeck_results = self.hir.typeck_results();

Expand Down
11 changes: 9 additions & 2 deletions src/librustc_parse/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,18 @@ impl<'a> Parser<'a> {
// want to keep their span info to improve diagnostics in these cases in a later stage.
(true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
(true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
(true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475)
(true, Some(AssocOp::Add)) // `{ 42 } + 42
// If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
// `if x { a } else { b } && if y { c } else { d }`
if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
if !self.look_ahead(1, |t| t.is_used_keyword()) => {
// These cases are ambiguous and can't be identified in the parser alone.
let sp = self.sess.source_map().start_point(self.token.span);
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
false
}
(true, Some(AssocOp::LAnd)) => {
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
// above due to #74233.
// These cases are ambiguous and can't be identified in the parser alone.
let sp = self.sess.source_map().start_point(self.token.span);
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
Expand Down
9 changes: 3 additions & 6 deletions src/librustc_query_system/query/caches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ pub trait QueryCache: QueryStorage {
OnHit: FnOnce(&Self::Stored, DepNodeIndex) -> R,
OnMiss: FnOnce(Self::Key, QueryLookup<'_, CTX, Self::Key, Self::Sharded>) -> R;

fn complete<CTX: QueryContext>(
fn complete(
&self,
tcx: CTX,
lock_sharded_storage: &mut Self::Sharded,
key: Self::Key,
value: Self::Value,
Expand Down Expand Up @@ -112,9 +111,8 @@ impl<K: Eq + Hash, V: Clone> QueryCache for DefaultCache<K, V> {
}

#[inline]
fn complete<CTX: QueryContext>(
fn complete(
&self,
_: CTX,
lock_sharded_storage: &mut Self::Sharded,
key: K,
value: V,
Expand Down Expand Up @@ -195,9 +193,8 @@ impl<'tcx, K: Eq + Hash, V: 'tcx> QueryCache for ArenaCache<'tcx, K, V> {
}

#[inline]
fn complete<CTX: QueryContext>(
fn complete(
&self,
_: CTX,
lock_sharded_storage: &mut Self::Sharded,
key: K,
value: V,
Expand Down
Loading