Skip to content

Commit

Permalink
rust-timer simulated merge of 330e196
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rust-timer committed Jan 20, 2021
1 parent c8b2c01 commit 771170b
Show file tree
Hide file tree
Showing 37 changed files with 575 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
branch = rustc/11.0-2020-10-12
branch = rustc/11.0-2021-01-05
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub(super) fn note_and_explain_region(
// uh oh, hope no user ever sees THIS
ty::ReEmpty(ui) => (format!("the empty lifetime in universe {:?}", ui), None),

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

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

if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values {
if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() {
if let Some(def_id) = def_id.as_local() {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let span = self.tcx.hir().span(hir_id);
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
}
}
}

// It reads better to have the error origin as the final
// thing.
self.note_error_origin(diag, cause, exp_found);
Expand Down
64 changes: 53 additions & 11 deletions compiler/rustc_infer/src/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::infer::error_reporting::{note_and_explain_region, ObligationCauseExt};
use crate::infer::{self, InferCtxt, SubregionOrigin};
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, Region};

Expand Down Expand Up @@ -107,14 +108,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, &terr);
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
note_and_explain_region(
self.tcx,
&mut err,
"...does not necessarily outlive ",
sub,
"",
);
match (sub, sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
note_and_explain_region(
self.tcx,
&mut err,
"",
sup,
" doesn't meet the lifetime requirements",
);
}
(_, ty::RePlaceholder(_)) => {
note_and_explain_region(
self.tcx,
&mut err,
"the required lifetime does not necessarily outlive ",
sub,
"",
);
}
_ => {
note_and_explain_region(self.tcx, &mut err, "", sup, "...");
note_and_explain_region(
self.tcx,
&mut err,
"...does not necessarily outlive ",
sub,
"",
);
}
}
err
}
infer::Reborrow(span) => {
Expand Down Expand Up @@ -286,13 +310,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
sup: Region<'tcx>,
) -> DiagnosticBuilder<'tcx> {
// I can't think how to do better than this right now. -nikomatsakis
debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure");
match placeholder_origin {
infer::Subtype(box ref trace)
if matches!(
&trace.cause.code.peel_derives(),
ObligationCauseCode::BindingObligation(..)
) =>
{
// Hack to get around the borrow checker because trace.cause has an `Rc`.
if let ObligationCauseCode::BindingObligation(_, span) =
&trace.cause.code.peel_derives()
{
let span = *span;
let mut err = self.report_concrete_failure(placeholder_origin, sub, sup);
err.span_note(span, "the lifetime requirement is introduced here");
err
} else {
unreachable!()
}
}
infer::Subtype(box trace) => {
let terr = TypeError::RegionsPlaceholderMismatch;
self.report_and_explain_type_error(trace, &terr)
return self.report_and_explain_type_error(trace, &terr);
}

_ => self.report_concrete_failure(placeholder_origin, sub, sup),
_ => return self.report_concrete_failure(placeholder_origin, sub, sup),
}
}
}
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ impl<'tcx> Const<'tcx> {
let item_id = tcx.hir().get_parent_node(hir_id);
let item_def_id = tcx.hir().local_def_id(item_id);
let generics = tcx.generics_of(item_def_id.to_def_id());
let index =
generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id).to_def_id()];
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.hir().name(hir_id);
ty::ConstKind::Param(ty::ParamConst::new(index, name))
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,7 @@ fn convert_path_expr<'a, 'tcx>(
let item_id = cx.tcx.hir().get_parent_node(hir_id);
let item_def_id = cx.tcx.hir().local_def_id(item_id);
let generics = cx.tcx.generics_of(item_def_id);
let local_def_id = cx.tcx.hir().local_def_id(hir_id);
let index = generics.param_def_id_to_index[&local_def_id.to_def_id()];
let index = generics.param_def_id_to_index[&def_id];
let name = cx.tcx.hir().name(hir_id);
let val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
ExprKind::Literal {
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_target/src/spec/i386_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::spec::Target;

pub fn target() -> Target {
let mut base = super::i686_unknown_linux_gnu::target();
base.cpu = "i386".to_string();
base.llvm_target = "i386-unknown-linux-gnu".to_string();
base
}
8 changes: 8 additions & 0 deletions compiler/rustc_target/src/spec/i486_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::spec::Target;

pub fn target() -> Target {
let mut base = super::i686_unknown_linux_gnu::target();
base.cpu = "i486".to_string();
base.llvm_target = "i486-unknown-linux-gnu".to_string();
base
}
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
return;
}
self.suggest_no_capture_closure(err, expected, expr_ty);
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
self.suggest_missing_parentheses(err, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
Expand Down
34 changes: 33 additions & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::FnCtxt;
use crate::astconv::AstConv;

use rustc_ast::util::parser::ExprPrecedence;
use rustc_span::{self, Span};
use rustc_span::{self, MultiSpan, Span};

use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
Expand Down Expand Up @@ -287,6 +287,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// When encountering a closure that captures variables, where a FnPtr is expected,
/// suggest a non-capturing closure
pub(in super::super) fn suggest_no_capture_closure(
&self,
err: &mut DiagnosticBuilder<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
) {
if let (ty::FnPtr(_), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) {
if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) {
// Report upto four upvars being captured to reduce the amount error messages
// reported back to the user.
let spans_and_labels = upvars
.iter()
.take(4)
.map(|(var_hir_id, upvar)| {
let var_name = self.tcx.hir().name(*var_hir_id).to_string();
let msg = format!("`{}` captured here", var_name);
(upvar.span, msg)
})
.collect::<Vec<_>>();

let mut multi_span: MultiSpan =
spans_and_labels.iter().map(|(sp, _)| *sp).collect::<Vec<_>>().into();
for (sp, label) in spans_and_labels {
multi_span.push_span_label(sp, label);
}
err.span_note(multi_span, "closures can only be coerced to `fn` types if they do not capture any variables");
}
}
}

/// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
&self,
Expand Down
44 changes: 35 additions & 9 deletions library/std/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ mod tests;
// a backtrace or actually symbolizing it.

use crate::backtrace_rs::{self, BytesOrWideString};
use crate::cell::UnsafeCell;
use crate::env;
use crate::ffi::c_void;
use crate::fmt;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use crate::sync::Mutex;
use crate::sync::Once;
use crate::sys_common::backtrace::{lock, output_filename};
use crate::vec::Vec;

Expand Down Expand Up @@ -132,7 +133,7 @@ pub enum BacktraceStatus {
enum Inner {
Unsupported,
Disabled,
Captured(Mutex<Capture>),
Captured(LazilyResolvedCapture),
}

struct Capture {
Expand Down Expand Up @@ -171,12 +172,11 @@ enum BytesOrWide {

impl fmt::Debug for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut capture = match &self.inner {
let capture = match &self.inner {
Inner::Unsupported => return fmt.write_str("<unsupported>"),
Inner::Disabled => return fmt.write_str("<disabled>"),
Inner::Captured(c) => c.lock().unwrap(),
Inner::Captured(c) => c.force(),
};
capture.resolve();

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

Expand Down Expand Up @@ -331,7 +331,7 @@ impl Backtrace {
let inner = if frames.is_empty() {
Inner::Unsupported
} else {
Inner::Captured(Mutex::new(Capture {
Inner::Captured(LazilyResolvedCapture::new(Capture {
actual_start: actual_start.unwrap_or(0),
frames,
resolved: false,
Expand All @@ -355,12 +355,11 @@ impl Backtrace {

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

let full = fmt.alternate();
let (frames, style) = if full {
Expand Down Expand Up @@ -404,6 +403,33 @@ impl fmt::Display for Backtrace {
}
}

struct LazilyResolvedCapture {
sync: Once,
capture: UnsafeCell<Capture>,
}

impl LazilyResolvedCapture {
fn new(capture: Capture) -> Self {
LazilyResolvedCapture { sync: Once::new(), capture: UnsafeCell::new(capture) }
}

fn force(&self) -> &Capture {
self.sync.call_once(|| {
// SAFETY: This exclusive reference can't overlap with any others
// `Once` guarantees callers will block until this closure returns
// `Once` also guarantees only a single caller will enter this closure
unsafe { &mut *self.capture.get() }.resolve();
});

// SAFETY: This shared reference can't overlap with the exclusive reference above
unsafe { &*self.capture.get() }
}
}

// SAFETY: Access to the inner value is synchronized using a thread-safe `Once`
// So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}

impl Capture {
fn resolve(&mut self) {
// If we're already resolved, nothing to do!
Expand Down
5 changes: 4 additions & 1 deletion library/std/src/backtrace/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::*;
#[test]
fn test_debug() {
let backtrace = Backtrace {
inner: Inner::Captured(Mutex::new(Capture {
inner: Inner::Captured(LazilyResolvedCapture::new(Capture {
actual_start: 1,
resolved: true,
frames: vec![
Expand Down Expand Up @@ -54,4 +54,7 @@ fn test_debug() {
\n]";

assert_eq!(format!("{:#?}", backtrace), expected);

// Format the backtrace a second time, just to make sure lazily resolved state is stable
assert_eq!(format!("{:#?}", backtrace), expected);
}
2 changes: 1 addition & 1 deletion src/llvm-project
Submodule llvm-project updated 186 files
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ error[E0308]: mismatched types
--> $DIR/higher-ranked-projection.rs:25:5
|
LL | foo(());
| ^^^ one type is more general than the other
| ^^^ lifetime mismatch
|
= note: expected type `&'a ()`
found type `&()`
note: the lifetime requirement is introduced here
--> $DIR/higher-ranked-projection.rs:15:33
|
LL | where for<'a> &'a T: Mirror<Image=U>
| ^^^^^^^

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/closures/closure-no-fn-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
= note: expected fn pointer `fn(u8) -> u8`
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50]`
note: closures can only be coerced to `fn` types if they do not capture any variables
--> $DIR/closure-no-fn-1.rs:6:39
|
LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
| ^ `a` captured here

error: aborting due to previous error

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/closures/closure-no-fn-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ LL | let bar: fn() -> u8 = || { b };
|
= note: expected fn pointer `fn() -> u8`
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35]`
note: closures can only be coerced to `fn` types if they do not capture any variables
--> $DIR/closure-no-fn-2.rs:6:32
|
LL | let bar: fn() -> u8 = || { b };
| ^ `b` captured here

error: aborting due to previous error

Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/closures/closure-no-fn-4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let b = 2;
let _: fn(usize) -> usize = match true {
true => |a| a + 1,
false => |a| a - b,
//~^ ERROR `match` arms have incompatible types
};
}
Loading

0 comments on commit 771170b

Please sign in to comment.