Skip to content

Commit d3163e9

Browse files
committed
Auto merge of #81355 - jonas-schievink:rollup-vpaadij, r=jonas-schievink
Rollup of 14 pull requests Successful merges: - #75180 (Implement Error for &(impl Error)) - #78578 (Permit mutable references in all const contexts) - #79174 (Make std::future a re-export of core::future) - #79884 (Replace magic numbers with existing constants) - #80855 (Expand assert!(expr, args..) to include $crate for hygiene on 2021.) - #80933 (Fix sysroot option not being honored across rustc) - #81259 (Replace version_check dependency with own version parsing code) - #81264 (Add unstable option to control doctest run directory) - #81279 (Small refactor in typeck) - #81297 (Don't provide backend_optimization_level query for extern crates) - #81302 (Fix rendering of stabilization version for trait implementors) - #81310 (Do not mark unit variants as used when in path pattern) - #81320 (Make bad shlex parsing a pretty error) - #81338 (Clean up `dominators_given_rpo`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1d0d76f + 529f15f commit d3163e9

File tree

67 files changed

+942
-441
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+942
-441
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -3568,7 +3568,6 @@ dependencies = [
35683568
"rustc_serialize",
35693569
"rustc_session",
35703570
"rustc_span",
3571-
"version_check",
35723571
]
35733572

35743573
[[package]]

compiler/rustc_attr/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,3 @@ rustc_lexer = { path = "../rustc_lexer" }
1818
rustc_macros = { path = "../rustc_macros" }
1919
rustc_session = { path = "../rustc_session" }
2020
rustc_ast = { path = "../rustc_ast" }
21-
version_check = "0.9"

compiler/rustc_attr/src/builtin.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_session::Session;
1010
use rustc_span::hygiene::Transparency;
1111
use rustc_span::{symbol::sym, symbol::Symbol, Span};
1212
use std::num::NonZeroU32;
13-
use version_check::Version;
1413

1514
pub fn is_builtin_attr(attr: &Attribute) -> bool {
1615
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
@@ -526,6 +525,26 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F
526525
}
527526
}
528527

528+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
529+
struct Version {
530+
major: u16,
531+
minor: u16,
532+
patch: u16,
533+
}
534+
535+
fn parse_version(s: &str, allow_appendix: bool) -> Option<Version> {
536+
let mut components = s.split('-');
537+
let d = components.next()?;
538+
if !allow_appendix && components.next().is_some() {
539+
return None;
540+
}
541+
let mut digits = d.splitn(3, '.');
542+
let major = digits.next()?.parse().ok()?;
543+
let minor = digits.next()?.parse().ok()?;
544+
let patch = digits.next().unwrap_or("0").parse().ok()?;
545+
Some(Version { major, minor, patch })
546+
}
547+
529548
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
530549
/// evaluate individual items.
531550
pub fn eval_condition(
@@ -555,16 +574,21 @@ pub fn eval_condition(
555574
return false;
556575
}
557576
};
558-
let min_version = match Version::parse(&min_version.as_str()) {
577+
let min_version = match parse_version(&min_version.as_str(), false) {
559578
Some(ver) => ver,
560579
None => {
561-
sess.span_diagnostic.struct_span_err(*span, "invalid version literal").emit();
580+
sess.span_diagnostic
581+
.struct_span_warn(
582+
*span,
583+
"unknown version literal format, assuming it refers to a future version",
584+
)
585+
.emit();
562586
return false;
563587
}
564588
};
565589
let channel = env!("CFG_RELEASE_CHANNEL");
566590
let nightly = channel == "nightly" || channel == "dev";
567-
let rustc_version = Version::parse(env!("CFG_RELEASE")).unwrap();
591+
let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap();
568592

569593
// See https://github.com/rust-lang/rust/issues/64796#issuecomment-625474439 for details
570594
if nightly { rustc_version > min_version } else { rustc_version >= min_version }

compiler/rustc_builtin_macros/src/assert.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,43 @@ use rustc_span::{Span, DUMMY_SP};
1212

1313
pub fn expand_assert<'cx>(
1414
cx: &'cx mut ExtCtxt<'_>,
15-
sp: Span,
15+
span: Span,
1616
tts: TokenStream,
1717
) -> Box<dyn MacResult + 'cx> {
18-
let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
18+
let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) {
1919
Ok(assert) => assert,
2020
Err(mut err) => {
2121
err.emit();
22-
return DummyResult::any(sp);
22+
return DummyResult::any(span);
2323
}
2424
};
2525

2626
// `core::panic` and `std::panic` are different macros, so we use call-site
2727
// context to pick up whichever is currently in scope.
28-
let sp = cx.with_call_site_ctxt(sp);
28+
let sp = cx.with_call_site_ctxt(span);
2929

3030
let panic_call = if let Some(tokens) = custom_message {
31+
let path = if span.rust_2021() {
32+
// On edition 2021, we always call `$crate::panic!()`.
33+
Path {
34+
span: sp,
35+
segments: cx
36+
.std_path(&[sym::panic])
37+
.into_iter()
38+
.map(|ident| PathSegment::from_ident(ident))
39+
.collect(),
40+
tokens: None,
41+
}
42+
} else {
43+
// Before edition 2021, we call `panic!()` unqualified,
44+
// such that it calls either `std::panic!()` or `core::panic!()`.
45+
Path::from_ident(Ident::new(sym::panic, sp))
46+
};
3147
// Pass the custom message to panic!().
3248
cx.expr(
3349
sp,
3450
ExprKind::MacCall(MacCall {
35-
path: Path::from_ident(Ident::new(sym::panic, sp)),
51+
path,
3652
args: P(MacArgs::Delimited(
3753
DelimSpan::from_single(sp),
3854
MacDelimiter::Parenthesis,

compiler/rustc_codegen_ssa/src/back/link.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -885,9 +885,22 @@ fn link_sanitizers(sess: &Session, crate_type: CrateType, linker: &mut dyn Linke
885885
}
886886

887887
fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
888-
let default_sysroot = filesearch::get_or_default_sysroot();
889-
let default_tlib =
890-
filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.triple());
888+
fn find_sanitizer_runtime(sess: &Session, filename: &String) -> PathBuf {
889+
let session_tlib =
890+
filesearch::make_target_lib_path(&sess.sysroot, sess.opts.target_triple.triple());
891+
let path = session_tlib.join(&filename);
892+
if path.exists() {
893+
return session_tlib;
894+
} else {
895+
let default_sysroot = filesearch::get_or_default_sysroot();
896+
let default_tlib = filesearch::make_target_lib_path(
897+
&default_sysroot,
898+
sess.opts.target_triple.triple(),
899+
);
900+
return default_tlib;
901+
}
902+
}
903+
891904
let channel = option_env!("CFG_RELEASE_CHANNEL")
892905
.map(|channel| format!("-{}", channel))
893906
.unwrap_or_default();
@@ -898,18 +911,19 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
898911
// LLVM will link to `@rpath/*.dylib`, so we need to specify an
899912
// rpath to the library as well (the rpath should be absolute, see
900913
// PR #41352 for details).
901-
let libname = format!("rustc{}_rt.{}", channel, name);
902-
let rpath = default_tlib.to_str().expect("non-utf8 component in path");
914+
let filename = format!("rustc{}_rt.{}", channel, name);
915+
let path = find_sanitizer_runtime(&sess, &filename);
916+
let rpath = path.to_str().expect("non-utf8 component in path");
903917
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
904-
linker.link_dylib(Symbol::intern(&libname));
918+
linker.link_dylib(Symbol::intern(&filename));
905919
}
906920
"aarch64-fuchsia"
907921
| "aarch64-unknown-linux-gnu"
908922
| "x86_64-fuchsia"
909923
| "x86_64-unknown-freebsd"
910924
| "x86_64-unknown-linux-gnu" => {
911925
let filename = format!("librustc{}_rt.{}.a", channel, name);
912-
let path = default_tlib.join(&filename);
926+
let path = find_sanitizer_runtime(&sess, &filename).join(&filename);
913927
linker.link_whole_rlib(&path);
914928
}
915929
_ => {}

compiler/rustc_codegen_ssa/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ impl CrateInfo {
783783
}
784784
}
785785

786-
pub fn provide_both(providers: &mut Providers) {
786+
pub fn provide(providers: &mut Providers) {
787787
providers.backend_optimization_level = |tcx, cratenum| {
788788
let for_speed = match tcx.sess.opts.optimize {
789789
// If globally no optimisation is done, #[optimize] has no effect.

compiler/rustc_codegen_ssa/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,12 @@ pub struct CodegenResults {
160160

161161
pub fn provide(providers: &mut Providers) {
162162
crate::back::symbol_export::provide(providers);
163-
crate::base::provide_both(providers);
163+
crate::base::provide(providers);
164164
crate::target_features::provide(providers);
165165
}
166166

167167
pub fn provide_extern(providers: &mut Providers) {
168168
crate::back::symbol_export::provide_extern(providers);
169-
crate::base::provide_both(providers);
170169
}
171170

172171
/// Checks if the given filename ends with the `.rcgu.o` extension that `rustc`

compiler/rustc_data_structures/src/graph/dominators/mod.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use super::iterate::reverse_post_order;
99
use super::ControlFlowGraph;
1010
use rustc_index::vec::{Idx, IndexVec};
11-
use std::borrow::BorrowMut;
1211
use std::cmp::Ordering;
1312

1413
#[cfg(test)]
@@ -20,22 +19,17 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> {
2019
dominators_given_rpo(graph, &rpo)
2120
}
2221

23-
fn dominators_given_rpo<G: ControlFlowGraph + BorrowMut<G>>(
24-
mut graph: G,
25-
rpo: &[G::Node],
26-
) -> Dominators<G::Node> {
27-
let start_node = graph.borrow().start_node();
22+
fn dominators_given_rpo<G: ControlFlowGraph>(graph: G, rpo: &[G::Node]) -> Dominators<G::Node> {
23+
let start_node = graph.start_node();
2824
assert_eq!(rpo[0], start_node);
2925

3026
// compute the post order index (rank) for each node
31-
let mut post_order_rank: IndexVec<G::Node, usize> =
32-
(0..graph.borrow().num_nodes()).map(|_| 0).collect();
27+
let mut post_order_rank = IndexVec::from_elem_n(0, graph.num_nodes());
3328
for (index, node) in rpo.iter().rev().cloned().enumerate() {
3429
post_order_rank[node] = index;
3530
}
3631

37-
let mut immediate_dominators: IndexVec<G::Node, Option<G::Node>> =
38-
(0..graph.borrow().num_nodes()).map(|_| None).collect();
32+
let mut immediate_dominators = IndexVec::from_elem_n(None, graph.num_nodes());
3933
immediate_dominators[start_node] = Some(start_node);
4034

4135
let mut changed = true;
@@ -44,7 +38,7 @@ fn dominators_given_rpo<G: ControlFlowGraph + BorrowMut<G>>(
4438

4539
for &node in &rpo[1..] {
4640
let mut new_idom = None;
47-
for pred in graph.borrow_mut().predecessors(node) {
41+
for pred in graph.predecessors(node) {
4842
if immediate_dominators[pred].is_some() {
4943
// (*) dominators for `pred` have been calculated
5044
new_idom = Some(if let Some(new_idom) = new_idom {

compiler/rustc_mir/src/transform/check_consts/ops.rs

+44-27
Original file line numberDiff line numberDiff line change
@@ -268,16 +268,20 @@ impl NonConstOp for CellBorrow {
268268
}
269269

270270
#[derive(Debug)]
271+
/// This op is for `&mut` borrows in the trailing expression of a constant
272+
/// which uses the "enclosing scopes rule" to leak its locals into anonymous
273+
/// static or const items.
271274
pub struct MutBorrow(pub hir::BorrowKind);
272275

273276
impl NonConstOp for MutBorrow {
274-
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
275-
// Forbid everywhere except in const fn with a feature gate
276-
if ccx.const_kind() == hir::ConstContext::ConstFn {
277-
Status::Unstable(sym::const_mut_refs)
278-
} else {
279-
Status::Forbidden
280-
}
277+
fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
278+
Status::Forbidden
279+
}
280+
281+
fn importance(&self) -> DiagnosticImportance {
282+
// If there were primary errors (like non-const function calls), do not emit further
283+
// errors about mutable references.
284+
DiagnosticImportance::Secondary
281285
}
282286

283287
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
@@ -286,25 +290,15 @@ impl NonConstOp for MutBorrow {
286290
hir::BorrowKind::Ref => "",
287291
};
288292

289-
let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn {
290-
feature_err(
291-
&ccx.tcx.sess.parse_sess,
292-
sym::const_mut_refs,
293-
span,
294-
&format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()),
295-
)
296-
} else {
297-
let mut err = struct_span_err!(
298-
ccx.tcx.sess,
299-
span,
300-
E0764,
301-
"{}mutable references are not allowed in {}s",
302-
raw,
303-
ccx.const_kind(),
304-
);
305-
err.span_label(span, format!("`&{}mut` is only allowed in `const fn`", raw));
306-
err
307-
};
293+
let mut err = struct_span_err!(
294+
ccx.tcx.sess,
295+
span,
296+
E0764,
297+
"{}mutable references are not allowed in the final value of {}s",
298+
raw,
299+
ccx.const_kind(),
300+
);
301+
308302
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
309303
err.note(
310304
"References in statics and constants may only refer \
@@ -321,6 +315,29 @@ impl NonConstOp for MutBorrow {
321315
}
322316
}
323317

318+
#[derive(Debug)]
319+
pub struct TransientMutBorrow(pub hir::BorrowKind);
320+
321+
impl NonConstOp for TransientMutBorrow {
322+
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
323+
Status::Unstable(sym::const_mut_refs)
324+
}
325+
326+
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
327+
let raw = match self.0 {
328+
hir::BorrowKind::Raw => "raw ",
329+
hir::BorrowKind::Ref => "",
330+
};
331+
332+
feature_err(
333+
&ccx.tcx.sess.parse_sess,
334+
sym::const_mut_refs,
335+
span,
336+
&format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()),
337+
)
338+
}
339+
}
340+
324341
#[derive(Debug)]
325342
pub struct MutDeref;
326343
impl NonConstOp for MutDeref {
@@ -329,7 +346,7 @@ impl NonConstOp for MutDeref {
329346
}
330347

331348
fn importance(&self) -> DiagnosticImportance {
332-
// Usually a side-effect of a `MutBorrow` somewhere.
349+
// Usually a side-effect of a `TransientMutBorrow` somewhere.
333350
DiagnosticImportance::Secondary
334351
}
335352

compiler/rustc_mir/src/transform/check_consts/validation.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,29 @@ impl Validator<'mir, 'tcx> {
466466
}
467467
}
468468
}
469+
470+
fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) {
471+
match self.const_kind() {
472+
// In a const fn all borrows are transient or point to the places given via
473+
// references in the arguments (so we already checked them with
474+
// TransientMutBorrow/MutBorrow as appropriate).
475+
// The borrow checker guarantees that no new non-transient borrows are created.
476+
// NOTE: Once we have heap allocations during CTFE we need to figure out
477+
// how to prevent `const fn` to create long-lived allocations that point
478+
// to mutable memory.
479+
hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)),
480+
_ => {
481+
// Locals with StorageDead do not live beyond the evaluation and can
482+
// thus safely be borrowed without being able to be leaked to the final
483+
// value of the constant.
484+
if self.local_has_storage_dead(local) {
485+
self.check_op(ops::TransientMutBorrow(kind));
486+
} else {
487+
self.check_op(ops::MutBorrow(kind));
488+
}
489+
}
490+
}
491+
}
469492
}
470493

471494
impl Visitor<'tcx> for Validator<'mir, 'tcx> {
@@ -562,15 +585,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
562585

563586
if !is_allowed {
564587
if let BorrowKind::Mut { .. } = kind {
565-
self.check_op(ops::MutBorrow(hir::BorrowKind::Ref));
588+
self.check_mut_borrow(place.local, hir::BorrowKind::Ref)
566589
} else {
567590
self.check_op(ops::CellBorrow);
568591
}
569592
}
570593
}
571594

572-
Rvalue::AddressOf(Mutability::Mut, _) => {
573-
self.check_op(ops::MutBorrow(hir::BorrowKind::Raw))
595+
Rvalue::AddressOf(Mutability::Mut, ref place) => {
596+
self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
574597
}
575598

576599
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place)

0 commit comments

Comments
 (0)