Skip to content

Commit 771170b

Browse files
committed
rust-timer simulated merge of 330e196
Original message: Rollup merge of rust-lang#80796 - cuviper:llvm-11.0.1, r=nikic Update to LLVM 11.0.1 This updates to a new LLVM branch, rebased on the upstream `llvmorg-11.0.1`. All our patches applied cleanly except the fortanix unwind changes, which just needed a small adjustment in cmake files. r? `@nikic` Fixes rust-lang#73722
1 parent c8b2c01 commit 771170b

37 files changed

+575
-44
lines changed

.gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
[submodule "src/llvm-project"]
3838
path = src/llvm-project
3939
url = https://github.com/rust-lang/llvm-project.git
40-
branch = rustc/11.0-2020-10-12
40+
branch = rustc/11.0-2021-01-05
4141
[submodule "src/doc/embedded-book"]
4242
path = src/doc/embedded-book
4343
url = https://github.com/rust-embedded/book.git

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub(super) fn note_and_explain_region(
9898
// uh oh, hope no user ever sees THIS
9999
ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None),
100100

101-
ty::RePlaceholder(_) => ("any other region".to_string(), None),
101+
ty::RePlaceholder(_) => return,
102102

103103
// FIXME(#13998) RePlaceholder should probably print like
104104
// ReFree rather than dumping Debug output on the user.
@@ -1675,6 +1675,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16751675
self.check_and_note_conflicting_crates(diag, terr);
16761676
self.tcx.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id.to_def_id());
16771677

1678+
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values {
1679+
if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() {
1680+
if let Some(def_id) = def_id.as_local() {
1681+
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
1682+
let span = self.tcx.hir().span(hir_id);
1683+
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
1684+
}
1685+
}
1686+
}
1687+
16781688
// It reads better to have the error origin as the final
16791689
// thing.
16801690
self.note_error_origin(diag, cause, exp_found);

compiler/rustc_infer/src/infer/error_reporting/note.rs

+53-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
22
use crate::infer::{self, InferCtxt, SubregionOrigin};
33
use rustc_errors::{struct_span_err, DiagnosticBuilder};
4+
use rustc_middle::traits::ObligationCauseCode;
45
use rustc_middle::ty::error::TypeError;
56
use rustc_middle::ty::{self, Region};
67

@@ -107,14 +108,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
107108
infer::Subtype(box trace) => {
108109
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
109110
let mut err = self.report_and_explain_type_error(trace, &terr);
110-
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
111-
note_and_explain_region(
112-
self.tcx,
113-
&mut err,
114-
"...does not necessarily outlive ",
115-
sub,
116-
"",
117-
);
111+
match (sub, sup) {
112+
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
113+
(ty::RePlaceholder(_), _) => {
114+
note_and_explain_region(
115+
self.tcx,
116+
&mut err,
117+
"",
118+
sup,
119+
" doesn't meet the lifetime requirements",
120+
);
121+
}
122+
(_, ty::RePlaceholder(_)) => {
123+
note_and_explain_region(
124+
self.tcx,
125+
&mut err,
126+
"the required lifetime does not necessarily outlive ",
127+
sub,
128+
"",
129+
);
130+
}
131+
_ => {
132+
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
133+
note_and_explain_region(
134+
self.tcx,
135+
&mut err,
136+
"...does not necessarily outlive ",
137+
sub,
138+
"",
139+
);
140+
}
141+
}
118142
err
119143
}
120144
infer::Reborrow(span) => {
@@ -286,13 +310,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
286310
sup: Region<'tcx>,
287311
) -> DiagnosticBuilder<'tcx> {
288312
// I can't think how to do better than this right now. -nikomatsakis
313+
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
289314
match placeholder_origin {
315+
infer::Subtype(box ref trace)
316+
if matches!(
317+
&trace.cause.code.peel_derives(),
318+
ObligationCauseCode::BindingObligation(..)
319+
) =>
320+
{
321+
// Hack to get around the borrow checker because trace.cause has an `Rc`.
322+
if let ObligationCauseCode::BindingObligation(_, span) =
323+
&trace.cause.code.peel_derives()
324+
{
325+
let span = *span;
326+
let mut err = self.report_concrete_failure(placeholder_origin, sub, sup);
327+
err.span_note(span, "the lifetime requirement is introduced here");
328+
err
329+
} else {
330+
unreachable!()
331+
}
332+
}
290333
infer::Subtype(box trace) => {
291334
let terr = TypeError::RegionsPlaceholderMismatch;
292-
self.report_and_explain_type_error(trace, &terr)
335+
return self.report_and_explain_type_error(trace, &terr);
293336
}
294-
295-
_ => self.report_concrete_failure(placeholder_origin, sub, sup),
337+
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
296338
}
297339
}
298340
}

compiler/rustc_middle/src/ty/consts.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ impl<'tcx> Const<'tcx> {
9292
let item_id = tcx.hir().get_parent_node(hir_id);
9393
let item_def_id = tcx.hir().local_def_id(item_id);
9494
let generics = tcx.generics_of(item_def_id.to_def_id());
95-
let index =
96-
generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id).to_def_id()];
95+
let index = generics.param_def_id_to_index[&def_id];
9796
let name = tcx.hir().name(hir_id);
9897
ty::ConstKind::Param(ty::ParamConst::new(index, name))
9998
}

compiler/rustc_mir_build/src/thir/cx/expr.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,7 @@ fn convert_path_expr<'a, 'tcx>(
813813
let item_id = cx.tcx.hir().get_parent_node(hir_id);
814814
let item_def_id = cx.tcx.hir().local_def_id(item_id);
815815
let generics = cx.tcx.generics_of(item_def_id);
816-
let local_def_id = cx.tcx.hir().local_def_id(hir_id);
817-
let index = generics.param_def_id_to_index[&local_def_id.to_def_id()];
816+
let index = generics.param_def_id_to_index[&def_id];
818817
let name = cx.tcx.hir().name(hir_id);
819818
let val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
820819
ExprKind::Literal {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use crate::spec::Target;
2+
3+
pub fn target() -> Target {
4+
let mut base = super::i686_unknown_linux_gnu::target();
5+
base.cpu = "i386".to_string();
6+
base.llvm_target = "i386-unknown-linux-gnu".to_string();
7+
base
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use crate::spec::Target;
2+
3+
pub fn target() -> Target {
4+
let mut base = super::i686_unknown_linux_gnu::target();
5+
base.cpu = "i486".to_string();
6+
base.llvm_target = "i486-unknown-linux-gnu".to_string();
7+
base
8+
}

compiler/rustc_typeck/src/check/demand.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3232
if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
3333
return;
3434
}
35+
self.suggest_no_capture_closure(err, expected, expr_ty);
3536
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
3637
self.suggest_missing_parentheses(err, expr);
3738
self.note_need_for_fn_pointer(err, expected, expr_ty);

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::FnCtxt;
22
use crate::astconv::AstConv;
33

44
use rustc_ast::util::parser::ExprPrecedence;
5-
use rustc_span::{self, Span};
5+
use rustc_span::{self, MultiSpan, Span};
66

77
use rustc_errors::{Applicability, DiagnosticBuilder};
88
use rustc_hir as hir;
@@ -287,6 +287,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
287287
}
288288
}
289289

290+
/// When encountering a closure that captures variables, where a FnPtr is expected,
291+
/// suggest a non-capturing closure
292+
pub(in super::super) fn suggest_no_capture_closure(
293+
&self,
294+
err: &mut DiagnosticBuilder<'_>,
295+
expected: Ty<'tcx>,
296+
found: Ty<'tcx>,
297+
) {
298+
if let (ty::FnPtr(_), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) {
299+
if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) {
300+
// Report upto four upvars being captured to reduce the amount error messages
301+
// reported back to the user.
302+
let spans_and_labels = upvars
303+
.iter()
304+
.take(4)
305+
.map(|(var_hir_id, upvar)| {
306+
let var_name = self.tcx.hir().name(*var_hir_id).to_string();
307+
let msg = format!("`{}` captured here", var_name);
308+
(upvar.span, msg)
309+
})
310+
.collect::<Vec<_>>();
311+
312+
let mut multi_span: MultiSpan =
313+
spans_and_labels.iter().map(|(sp, _)| *sp).collect::<Vec<_>>().into();
314+
for (sp, label) in spans_and_labels {
315+
multi_span.push_span_label(sp, label);
316+
}
317+
err.span_note(multi_span, "closures can only be coerced to `fn` types if they do not capture any variables");
318+
}
319+
}
320+
}
321+
290322
/// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
291323
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
292324
&self,

library/std/src/backtrace.rs

+35-9
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,12 @@ mod tests;
9595
// a backtrace or actually symbolizing it.
9696

9797
use crate::backtrace_rs::{self, BytesOrWideString};
98+
use crate::cell::UnsafeCell;
9899
use crate::env;
99100
use crate::ffi::c_void;
100101
use crate::fmt;
101102
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
102-
use crate::sync::Mutex;
103+
use crate::sync::Once;
103104
use crate::sys_common::backtrace::{lock, output_filename};
104105
use crate::vec::Vec;
105106

@@ -132,7 +133,7 @@ pub enum BacktraceStatus {
132133
enum Inner {
133134
Unsupported,
134135
Disabled,
135-
Captured(Mutex<Capture>),
136+
Captured(LazilyResolvedCapture),
136137
}
137138

138139
struct Capture {
@@ -171,12 +172,11 @@ enum BytesOrWide {
171172

172173
impl fmt::Debug for Backtrace {
173174
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
174-
let mut capture = match &self.inner {
175+
let capture = match &self.inner {
175176
Inner::Unsupported => return fmt.write_str("<unsupported>"),
176177
Inner::Disabled => return fmt.write_str("<disabled>"),
177-
Inner::Captured(c) => c.lock().unwrap(),
178+
Inner::Captured(c) => c.force(),
178179
};
179-
capture.resolve();
180180

181181
let frames = &capture.frames[capture.actual_start..];
182182

@@ -331,7 +331,7 @@ impl Backtrace {
331331
let inner = if frames.is_empty() {
332332
Inner::Unsupported
333333
} else {
334-
Inner::Captured(Mutex::new(Capture {
334+
Inner::Captured(LazilyResolvedCapture::new(Capture {
335335
actual_start: actual_start.unwrap_or(0),
336336
frames,
337337
resolved: false,
@@ -355,12 +355,11 @@ impl Backtrace {
355355

356356
impl fmt::Display for Backtrace {
357357
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
358-
let mut capture = match &self.inner {
358+
let capture = match &self.inner {
359359
Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
360360
Inner::Disabled => return fmt.write_str("disabled backtrace"),
361-
Inner::Captured(c) => c.lock().unwrap(),
361+
Inner::Captured(c) => c.force(),
362362
};
363-
capture.resolve();
364363

365364
let full = fmt.alternate();
366365
let (frames, style) = if full {
@@ -404,6 +403,33 @@ impl fmt::Display for Backtrace {
404403
}
405404
}
406405

406+
struct LazilyResolvedCapture {
407+
sync: Once,
408+
capture: UnsafeCell<Capture>,
409+
}
410+
411+
impl LazilyResolvedCapture {
412+
fn new(capture: Capture) -> Self {
413+
LazilyResolvedCapture { sync: Once::new(), capture: UnsafeCell::new(capture) }
414+
}
415+
416+
fn force(&self) -> &Capture {
417+
self.sync.call_once(|| {
418+
// SAFETY: This exclusive reference can't overlap with any others
419+
// `Once` guarantees callers will block until this closure returns
420+
// `Once` also guarantees only a single caller will enter this closure
421+
unsafe { &mut *self.capture.get() }.resolve();
422+
});
423+
424+
// SAFETY: This shared reference can't overlap with the exclusive reference above
425+
unsafe { &*self.capture.get() }
426+
}
427+
}
428+
429+
// SAFETY: Access to the inner value is synchronized using a thread-safe `Once`
430+
// So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
431+
unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
432+
407433
impl Capture {
408434
fn resolve(&mut self) {
409435
// If we're already resolved, nothing to do!

library/std/src/backtrace/tests.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::*;
33
#[test]
44
fn test_debug() {
55
let backtrace = Backtrace {
6-
inner: Inner::Captured(Mutex::new(Capture {
6+
inner: Inner::Captured(LazilyResolvedCapture::new(Capture {
77
actual_start: 1,
88
resolved: true,
99
frames: vec![
@@ -54,4 +54,7 @@ fn test_debug() {
5454
\n]";
5555

5656
assert_eq!(format!("{:#?}", backtrace), expected);
57+
58+
// Format the backtrace a second time, just to make sure lazily resolved state is stable
59+
assert_eq!(format!("{:#?}", backtrace), expected);
5760
}

src/llvm-project

Submodule llvm-project updated 186 files

src/test/ui/associated-types/higher-ranked-projection.bad.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ error[E0308]: mismatched types
22
--> $DIR/higher-ranked-projection.rs:25:5
33
|
44
LL | foo(());
5-
| ^^^ one type is more general than the other
5+
| ^^^ lifetime mismatch
66
|
77
= note: expected type `&'a ()`
88
found type `&()`
9+
note: the lifetime requirement is introduced here
10+
--> $DIR/higher-ranked-projection.rs:15:33
11+
|
12+
LL | where for<'a> &'a T: Mirror<Image=U>
13+
| ^^^^^^^
914

1015
error: aborting due to previous error
1116

src/test/ui/closures/closure-no-fn-1.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
88
|
99
= note: expected fn pointer `fn(u8) -> u8`
1010
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50]`
11+
note: closures can only be coerced to `fn` types if they do not capture any variables
12+
--> $DIR/closure-no-fn-1.rs:6:39
13+
|
14+
LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
15+
| ^ `a` captured here
1116

1217
error: aborting due to previous error
1318

src/test/ui/closures/closure-no-fn-2.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ LL | let bar: fn() -> u8 = || { b };
88
|
99
= note: expected fn pointer `fn() -> u8`
1010
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35]`
11+
note: closures can only be coerced to `fn` types if they do not capture any variables
12+
--> $DIR/closure-no-fn-2.rs:6:32
13+
|
14+
LL | let bar: fn() -> u8 = || { b };
15+
| ^ `b` captured here
1116

1217
error: aborting due to previous error
1318

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let b = 2;
3+
let _: fn(usize) -> usize = match true {
4+
true => |a| a + 1,
5+
false => |a| a - b,
6+
//~^ ERROR `match` arms have incompatible types
7+
};
8+
}

0 commit comments

Comments
 (0)