mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #80960 - Dylan-DPC:rollup-89tri8x, r=Dylan-DPC
Rollup of 10 pull requests Successful merges: - #78901 (diagnostics: Note capturing closures can't be coerced to fns) - #79588 (Provide more information for HRTB lifetime errors involving closures) - #80232 (Remove redundant def_id lookups) - #80662 (Added support for i386-unknown-linux-gnu and i486-unknown-linux-gnu) - #80736 (use Once instead of Mutex to manage capture resolution) - #80796 (Update to LLVM 11.0.1) - #80859 (Fix --pretty=expanded with --remap-path-prefix) - #80922 (Revert "Auto merge of #76896 - spastorino:codegen-inline-fns2) - #80924 (Fix rustdoc --test-builder argument parsing) - #80935 (Rename `rustc_middle::lint::LevelSource` to `LevelAndSource`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fc93e4719c
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -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
|
||||
|
@ -363,8 +363,15 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> {
|
||||
|
||||
fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
|
||||
let src_name = input.source_name();
|
||||
let src =
|
||||
String::clone(&sess.source_map().get_source_file(&src_name).unwrap().src.as_ref().unwrap());
|
||||
let src = String::clone(
|
||||
&sess
|
||||
.source_map()
|
||||
.get_source_file(&src_name)
|
||||
.expect("get_source_file")
|
||||
.src
|
||||
.as_ref()
|
||||
.expect("src"),
|
||||
);
|
||||
(src, src_name)
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -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);
|
||||
|
@ -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};
|
||||
|
||||
@ -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) => {
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_hir::{intravisit, HirId};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::lint::LevelSource;
|
||||
use rustc_middle::lint::LevelAndSource;
|
||||
use rustc_middle::lint::LintDiagnosticBuilder;
|
||||
use rustc_middle::lint::{
|
||||
struct_lint_level, LintLevelMap, LintLevelSets, LintLevelSource, LintSet,
|
||||
@ -106,9 +106,9 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
/// diagnostic with no change to `specs`.
|
||||
fn insert_spec(
|
||||
&mut self,
|
||||
specs: &mut FxHashMap<LintId, LevelSource>,
|
||||
specs: &mut FxHashMap<LintId, LevelAndSource>,
|
||||
id: LintId,
|
||||
(level, src): LevelSource,
|
||||
(level, src): LevelAndSource,
|
||||
) {
|
||||
// Setting to a non-forbid level is an error if the lint previously had
|
||||
// a forbid level. Note that this is not necessarily true even with a
|
||||
|
@ -46,7 +46,7 @@ impl LintLevelSource {
|
||||
}
|
||||
|
||||
/// A tuple of a lint level and its source.
|
||||
pub type LevelSource = (Level, LintLevelSource);
|
||||
pub type LevelAndSource = (Level, LintLevelSource);
|
||||
|
||||
pub struct LintLevelSets {
|
||||
pub list: Vec<LintSet>,
|
||||
@ -57,11 +57,11 @@ pub enum LintSet {
|
||||
CommandLine {
|
||||
// -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
|
||||
// flag.
|
||||
specs: FxHashMap<LintId, LevelSource>,
|
||||
specs: FxHashMap<LintId, LevelAndSource>,
|
||||
},
|
||||
|
||||
Node {
|
||||
specs: FxHashMap<LintId, LevelSource>,
|
||||
specs: FxHashMap<LintId, LevelAndSource>,
|
||||
parent: u32,
|
||||
},
|
||||
}
|
||||
@ -75,9 +75,9 @@ impl LintLevelSets {
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
idx: u32,
|
||||
aux: Option<&FxHashMap<LintId, LevelSource>>,
|
||||
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
|
||||
sess: &Session,
|
||||
) -> LevelSource {
|
||||
) -> LevelAndSource {
|
||||
let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux);
|
||||
|
||||
// If `level` is none then we actually assume the default level for this
|
||||
@ -113,7 +113,7 @@ impl LintLevelSets {
|
||||
&self,
|
||||
id: LintId,
|
||||
mut idx: u32,
|
||||
aux: Option<&FxHashMap<LintId, LevelSource>>,
|
||||
aux: Option<&FxHashMap<LintId, LevelAndSource>>,
|
||||
) -> (Option<Level>, LintLevelSource) {
|
||||
if let Some(specs) = aux {
|
||||
if let Some(&(level, src)) = specs.get(&id) {
|
||||
@ -157,7 +157,7 @@ impl LintLevelMap {
|
||||
lint: &'static Lint,
|
||||
id: HirId,
|
||||
session: &Session,
|
||||
) -> Option<LevelSource> {
|
||||
) -> Option<LevelAndSource> {
|
||||
self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::dep_graph::{dep_constructor, DepNode, WorkProduct, WorkProductId};
|
||||
use crate::ich::{NodeIdHashingMode, StableHashingContext};
|
||||
use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
|
||||
use rustc_attr::InlineAttr;
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -78,6 +79,14 @@ impl<'tcx> MonoItem<'tcx> {
|
||||
}
|
||||
|
||||
pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
||||
let generate_cgu_internal_copies = tcx
|
||||
.sess
|
||||
.opts
|
||||
.debugging_opts
|
||||
.inline_in_all_cgus
|
||||
.unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
|
||||
&& !tcx.sess.link_dead_code();
|
||||
|
||||
match *self {
|
||||
MonoItem::Fn(ref instance) => {
|
||||
let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id);
|
||||
@ -90,26 +99,21 @@ impl<'tcx> MonoItem<'tcx> {
|
||||
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||
}
|
||||
|
||||
let generate_cgu_internal_copies = tcx
|
||||
.sess
|
||||
.opts
|
||||
.debugging_opts
|
||||
.inline_in_all_cgus
|
||||
.unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No)
|
||||
&& !tcx.sess.link_dead_code();
|
||||
|
||||
// At this point we don't have explicit linkage and we're an
|
||||
// inlined function. If we should generate local copies for each CGU,
|
||||
// then return `LocalCopy`, otherwise we'll just generate one copy
|
||||
// and share it with all CGUs in this crate.
|
||||
// inlined function. If we're inlining into all CGUs then we'll
|
||||
// be creating a local copy per CGU.
|
||||
if generate_cgu_internal_copies {
|
||||
InstantiationMode::LocalCopy
|
||||
} else {
|
||||
// Finally, if we've reached this point, then we should optimize for
|
||||
// compilation speed. In that regard, we will ignore any `#[inline]`
|
||||
// annotations on the function and simply codegen it as usual. This could
|
||||
// conflict with upstream crates as it could be an exported symbol.
|
||||
InstantiationMode::GloballyShared { may_conflict: true }
|
||||
return InstantiationMode::LocalCopy;
|
||||
}
|
||||
|
||||
// Finally, if this is `#[inline(always)]` we're sure to respect
|
||||
// that with an inline copy per CGU, but otherwise we'll be
|
||||
// creating one copy of this `#[inline]` function which may
|
||||
// conflict with upstream crates as it could be an exported
|
||||
// symbol.
|
||||
match tcx.codegen_fn_attrs(instance.def_id()).inline {
|
||||
InlineAttr::Always => InstantiationMode::LocalCopy,
|
||||
_ => InstantiationMode::GloballyShared { may_conflict: true },
|
||||
}
|
||||
}
|
||||
MonoItem::Static(..) | MonoItem::GlobalAsm(..) => {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -872,8 +872,10 @@ impl SourceMap {
|
||||
}
|
||||
|
||||
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
|
||||
// Remap filename before lookup
|
||||
let filename = self.path_mapping().map_filename_prefix(filename).0;
|
||||
for sf in self.files.borrow().source_files.iter() {
|
||||
if *filename == sf.name {
|
||||
if filename == sf.name {
|
||||
return Some(sf.clone());
|
||||
}
|
||||
}
|
||||
@ -1041,4 +1043,15 @@ impl FilePathMapping {
|
||||
|
||||
(path, false)
|
||||
}
|
||||
|
||||
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
|
||||
match file {
|
||||
FileName::Real(realfile) => {
|
||||
let path = realfile.local_path();
|
||||
let (path, mapped) = self.map_prefix(path.to_path_buf());
|
||||
(FileName::Real(RealFileName::Named(path)), mapped)
|
||||
}
|
||||
other => (other.clone(), false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
compiler/rustc_target/src/spec/i386_unknown_linux_gnu.rs
Normal file
8
compiler/rustc_target/src/spec/i386_unknown_linux_gnu.rs
Normal file
@ -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
compiler/rustc_target/src/spec/i486_unknown_linux_gnu.rs
Normal file
8
compiler/rustc_target/src/spec/i486_unknown_linux_gnu.rs
Normal file
@ -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
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
@ -132,7 +133,7 @@ pub enum BacktraceStatus {
|
||||
enum Inner {
|
||||
Unsupported,
|
||||
Disabled,
|
||||
Captured(Mutex<Capture>),
|
||||
Captured(LazilyResolvedCapture),
|
||||
}
|
||||
|
||||
struct Capture {
|
||||
@ -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..];
|
||||
|
||||
@ -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,
|
||||
@ -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 {
|
||||
@ -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!
|
||||
|
@ -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![
|
||||
@ -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);
|
||||
}
|
||||
|
@ -412,11 +412,7 @@ fn opts() -> Vec<RustcOptGroup> {
|
||||
)
|
||||
}),
|
||||
unstable("test-builder", |o| {
|
||||
o.optflag(
|
||||
"",
|
||||
"test-builder",
|
||||
"specified the rustc-like binary to use as the test builder",
|
||||
)
|
||||
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
|
||||
}),
|
||||
unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")),
|
||||
]
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit fb115ee43b77601b237717c21ab0a8f5b5b9d50a
|
||||
Subproject commit f9a8d70b6e0365ac2172ca6b7f1de0341297458d
|
@ -1,5 +1,5 @@
|
||||
// revisions:rpass1 rpass2
|
||||
// compile-flags: -Z query-dep-graph -O
|
||||
// compile-flags: -Z query-dep-graph
|
||||
// aux-build:cached_hygiene.rs
|
||||
|
||||
// This tests the folllowing scenario
|
||||
@ -19,12 +19,7 @@
|
||||
// the metadata. Specifically, we were not resetting `orig_id`
|
||||
// for an `EpxnData` generate in the current crate, which would cause
|
||||
// us to serialize the `ExpnId` pointing to a garbage location in
|
||||
// the metadata.o
|
||||
|
||||
// NOTE: We're explicitly passing the `-O` optimization flag because if optimizations are not
|
||||
// enabled, then rustc will ignore the `#[inline(always)]` attribute which means we do not load
|
||||
// the optimized mir for the unmodified function to be loaded and so the CGU containing that
|
||||
// function will be reused.
|
||||
// the metadata.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
// revisions:rpass1 rpass2 rpass3
|
||||
// compile-flags: -Z query-dep-graph -g -O
|
||||
// compile-flags: -Z query-dep-graph -g
|
||||
// aux-build:extern_crate.rs
|
||||
|
||||
// ignore-asmjs wasm2js does not support source maps yet
|
||||
|
||||
// This test case makes sure that we detect if paths emitted into debuginfo
|
||||
// are changed, even when the change happens in an external crate.
|
||||
|
||||
// NOTE: We're explicitly passing the `-O` optimization flag because if no optimizations are
|
||||
// requested, rustc will ignore the `#[inline]` attribute. This is a performance optimization for
|
||||
// non-optimized builds which causes us to generate fewer copies of inlined functions when
|
||||
// runtime performance doesn't matter. Without this flag, the function will go into a different
|
||||
// CGU which can be reused by this crate.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#![rustc_partition_reused(module="main", cfg="rpass2")]
|
||||
|
13
src/test/pretty/expanded-and-path-remap-80832.pp
Normal file
13
src/test/pretty/expanded-and-path-remap-80832.pp
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(prelude_import)]
|
||||
#![no_std]
|
||||
#[prelude_import]
|
||||
use ::std::prelude::v1::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
// Test for issue 80832
|
||||
//
|
||||
// pretty-mode:expanded
|
||||
// pp-exact:expanded-and-path-remap-80832.pp
|
||||
// compile-flags: --remap-path-prefix {{src-base}}=the/src
|
||||
|
||||
fn main() { }
|
7
src/test/pretty/expanded-and-path-remap-80832.rs
Normal file
7
src/test/pretty/expanded-and-path-remap-80832.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// Test for issue 80832
|
||||
//
|
||||
// pretty-mode:expanded
|
||||
// pp-exact:expanded-and-path-remap-80832.pp
|
||||
// compile-flags: --remap-path-prefix {{src-base}}=the/src
|
||||
|
||||
fn main() {}
|
@ -1,12 +1,7 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2 -C opt-level=0
|
||||
if ![cat $(TMPDIR)/*.ll | $(CGREP) -e '\bcall\b']; then \
|
||||
echo "not found call instruction when one was expected"; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2 -C opt-level=1
|
||||
$(RUSTC) foo.rs --emit llvm-ir -C codegen-units=2
|
||||
if cat $(TMPDIR)/*.ll | $(CGREP) -e '\bcall\b'; then \
|
||||
echo "found call instruction when one wasn't expected"; \
|
||||
exit 1; \
|
||||
|
6
src/test/rustdoc/issue-80893.rs
Normal file
6
src/test/rustdoc/issue-80893.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// compile-flags: --test -Z unstable-options --test-builder true
|
||||
|
||||
/// ```no_run
|
||||
/// This tests that `--test-builder` is accepted as a flag by rustdoc.
|
||||
/// ```
|
||||
pub struct Foo;
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
8
src/test/ui/closures/closure-no-fn-4.rs
Normal file
8
src/test/ui/closures/closure-no-fn-4.rs
Normal file
@ -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
|
||||
};
|
||||
}
|
24
src/test/ui/closures/closure-no-fn-4.stderr
Normal file
24
src/test/ui/closures/closure-no-fn-4.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error[E0308]: `match` arms have incompatible types
|
||||
--> $DIR/closure-no-fn-4.rs:5:18
|
||||
|
|
||||
LL | let _: fn(usize) -> usize = match true {
|
||||
| _________________________________-
|
||||
LL | | true => |a| a + 1,
|
||||
| | --------- this is found to be of type `fn(usize) -> usize`
|
||||
LL | | false => |a| a - b,
|
||||
| | ^^^^^^^^^ expected fn pointer, found closure
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____- `match` arms have incompatible types
|
||||
|
|
||||
= note: expected fn pointer `fn(usize) -> usize`
|
||||
found closure `[closure@$DIR/closure-no-fn-4.rs:5:18: 5:27]`
|
||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||
--> $DIR/closure-no-fn-4.rs:5:26
|
||||
|
|
||||
LL | false => |a| a - b,
|
||||
| ^ `b` captured here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
12
src/test/ui/closures/closure-no-fn-5.rs
Normal file
12
src/test/ui/closures/closure-no-fn-5.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// When providing diagnostics about not being able to coerce a capturing-closure
|
||||
// to fn type, we want to report only upto 4 captures.
|
||||
|
||||
fn main() {
|
||||
let a = 0u8;
|
||||
let b = 0u8;
|
||||
let c = 0u8;
|
||||
let d = 0u8;
|
||||
let e = 0u8;
|
||||
let bar: fn() -> u8 = || { a; b; c; d; e };
|
||||
//~^ ERROR mismatched types
|
||||
}
|
23
src/test/ui/closures/closure-no-fn-5.stderr
Normal file
23
src/test/ui/closures/closure-no-fn-5.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-no-fn-5.rs:10:27
|
||||
|
|
||||
LL | let bar: fn() -> u8 = || { a; b; c; d; e };
|
||||
| ---------- ^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `fn() -> u8`
|
||||
found closure `[closure@$DIR/closure-no-fn-5.rs:10:27: 10:47]`
|
||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||
--> $DIR/closure-no-fn-5.rs:10:32
|
||||
|
|
||||
LL | let bar: fn() -> u8 = || { a; b; c; d; e };
|
||||
| ^ ^ ^ ^ `d` captured here
|
||||
| | | |
|
||||
| | | `c` captured here
|
||||
| | `b` captured here
|
||||
| `a` captured here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -8,6 +8,11 @@ LL | call_bare(f)
|
||||
|
|
||||
= note: expected fn pointer `for<'r> fn(&'r str)`
|
||||
found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50]`
|
||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||
--> $DIR/closure-reform-bad.rs:10:43
|
||||
|
|
||||
LL | let f = |s: &str| println!("{}{}", s, string);
|
||||
| ^^^^^^ `string` captured here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,11 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
||||
|
|
||||
= note: expected fn pointer `fn(u8) -> u8`
|
||||
found closure `[main::{closure#0} closure_substs=(unavailable)]`
|
||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||
--> $DIR/closure-print-verbose.rs:10:39
|
||||
|
|
||||
LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
||||
| ^ `a` captured here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,8 +2,9 @@
|
||||
// Tests that we can compare various kinds of extern fn signatures.
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
extern fn voidret1() {}
|
||||
extern fn voidret2() {}
|
||||
// `dbg!()` differentiates these functions to ensure they won't be merged.
|
||||
extern fn voidret1() { dbg!() }
|
||||
extern fn voidret2() { dbg!() }
|
||||
|
||||
extern fn uintret() -> usize { 22 }
|
||||
|
||||
|
@ -2,19 +2,47 @@ error[E0308]: mismatched types
|
||||
--> $DIR/resume-arg-late-bound.rs:15:5
|
||||
|
|
||||
LL | test(gen);
|
||||
| ^^^^ one type is more general than the other
|
||||
| ^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'a> Generator<&'a mut bool>`
|
||||
found type `Generator<&mut bool>`
|
||||
note: the required lifetime does not necessarily outlive the anonymous lifetime #1 defined on the body at 11:15
|
||||
--> $DIR/resume-arg-late-bound.rs:11:15
|
||||
|
|
||||
LL | let gen = |arg: &mut bool| {
|
||||
| _______________^
|
||||
LL | | yield ();
|
||||
LL | | *arg = true;
|
||||
LL | | };
|
||||
| |_____^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/resume-arg-late-bound.rs:8:17
|
||||
|
|
||||
LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/resume-arg-late-bound.rs:15:5
|
||||
|
|
||||
LL | test(gen);
|
||||
| ^^^^ one type is more general than the other
|
||||
| ^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'a> Generator<&'a mut bool>`
|
||||
found type `Generator<&mut bool>`
|
||||
note: the anonymous lifetime #1 defined on the body at 11:15 doesn't meet the lifetime requirements
|
||||
--> $DIR/resume-arg-late-bound.rs:11:15
|
||||
|
|
||||
LL | let gen = |arg: &mut bool| {
|
||||
| _______________^
|
||||
LL | | yield ();
|
||||
LL | | *arg = true;
|
||||
LL | | };
|
||||
| |_____^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/resume-arg-late-bound.rs:8:17
|
||||
|
|
||||
LL | fn test(a: impl for<'a> Generator<&'a mut bool>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,19 +2,39 @@ error[E0308]: mismatched types
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:46:5
|
||||
|
|
||||
LL | foo_hrtb_bar_not(&mut t);
|
||||
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
| ^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `Bar<&'a isize>`
|
||||
found type `Bar<&'b isize>`
|
||||
note: the required lifetime does not necessarily outlive the lifetime `'b` as defined on the function body at 39:21
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:39:21
|
||||
|
|
||||
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:40:15
|
||||
|
|
||||
LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:46:5
|
||||
|
|
||||
LL | foo_hrtb_bar_not(&mut t);
|
||||
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
| ^^^^^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `Bar<&'a isize>`
|
||||
found type `Bar<&'b isize>`
|
||||
note: the lifetime `'b` as defined on the function body at 39:21 doesn't meet the lifetime requirements
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:39:21
|
||||
|
|
||||
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/hrtb-perfect-forwarding.rs:40:15
|
||||
|
|
||||
LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -3,8 +3,6 @@ error[E0477]: the type `&'a i32` does not fulfill the required lifetime
|
||||
|
|
||||
LL | foo::<&'a i32>();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: type must outlive any other region
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,6 +6,11 @@ LL | Foo(Box::new(|_| ()));
|
||||
|
|
||||
= note: expected type `FnOnce<(&'a bool,)>`
|
||||
found type `FnOnce<(&bool,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57843.rs:23:18
|
||||
|
|
||||
LL | Foo(Box::new(|_| ()));
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
44
src/test/ui/lifetimes/issue-79187-2.nll.stderr
Normal file
44
src/test/ui/lifetimes/issue-79187-2.nll.stderr
Normal file
@ -0,0 +1,44 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-79187-2.rs:9:24
|
||||
|
|
||||
LL | take_foo(|a: &i32| a);
|
||||
| - - ^ returning this value requires that `'1` must outlive `'2`
|
||||
| | |
|
||||
| | return type of closure is &'2 i32
|
||||
| let's call the lifetime of this reference `'1`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-79187-2.rs:10:34
|
||||
|
|
||||
LL | take_foo(|a: &i32| -> &i32 { a });
|
||||
| - - ^ returning this value requires that `'1` must outlive `'2`
|
||||
| | |
|
||||
| | let's call the lifetime of this reference `'2`
|
||||
| let's call the lifetime of this reference `'1`
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187-2.rs:8:5
|
||||
|
|
||||
LL | take_foo(|a| a);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187-2.rs:8:5
|
||||
|
|
||||
LL | take_foo(|a| a);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187-2.rs:9:5
|
||||
|
|
||||
LL | take_foo(|a: &i32| a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187-2.rs:10:5
|
||||
|
|
||||
LL | take_foo(|a: &i32| -> &i32 { a });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
23
src/test/ui/lifetimes/issue-79187-2.rs
Normal file
23
src/test/ui/lifetimes/issue-79187-2.rs
Normal file
@ -0,0 +1,23 @@
|
||||
trait Foo {}
|
||||
|
||||
impl<F> Foo for F where F: Fn(&i32) -> &i32 {}
|
||||
|
||||
fn take_foo(_: impl Foo) {}
|
||||
|
||||
fn main() {
|
||||
take_foo(|a| a); //~ ERROR mismatched types
|
||||
take_foo(|a: &i32| a); //~ ERROR mismatched types
|
||||
take_foo(|a: &i32| -> &i32 { a }); //~ ERROR mismatched types
|
||||
|
||||
// OK
|
||||
take_foo(identity(|a| a));
|
||||
take_foo(identity(|a: &i32| a));
|
||||
take_foo(identity(|a: &i32| -> &i32 { a }));
|
||||
|
||||
fn identity<F>(t: F) -> F
|
||||
where
|
||||
F: Fn(&i32) -> &i32,
|
||||
{
|
||||
t
|
||||
}
|
||||
}
|
60
src/test/ui/lifetimes/issue-79187-2.stderr
Normal file
60
src/test/ui/lifetimes/issue-79187-2.stderr
Normal file
@ -0,0 +1,60 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-79187-2.rs:8:5
|
||||
|
|
||||
LL | take_foo(|a| a);
|
||||
| ^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r i32,)>`
|
||||
found type `Fn<(&i32,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-79187-2.rs:8:14
|
||||
|
|
||||
LL | take_foo(|a| a);
|
||||
| ^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-79187-2.rs:5:21
|
||||
|
|
||||
LL | fn take_foo(_: impl Foo) {}
|
||||
| ^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-79187-2.rs:9:5
|
||||
|
|
||||
LL | take_foo(|a: &i32| a);
|
||||
| ^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected reference `&i32`
|
||||
found reference `&i32`
|
||||
note: the anonymous lifetime #1 defined on the body at 9:14 doesn't meet the lifetime requirements
|
||||
--> $DIR/issue-79187-2.rs:9:14
|
||||
|
|
||||
LL | take_foo(|a: &i32| a);
|
||||
| ^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-79187-2.rs:5:21
|
||||
|
|
||||
LL | fn take_foo(_: impl Foo) {}
|
||||
| ^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-79187-2.rs:10:5
|
||||
|
|
||||
LL | take_foo(|a: &i32| -> &i32 { a });
|
||||
| ^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected reference `&i32`
|
||||
found reference `&i32`
|
||||
note: the anonymous lifetime #1 defined on the body at 10:14 doesn't meet the lifetime requirements
|
||||
--> $DIR/issue-79187-2.rs:10:14
|
||||
|
|
||||
LL | take_foo(|a: &i32| -> &i32 { a });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-79187-2.rs:5:21
|
||||
|
|
||||
LL | fn take_foo(_: impl Foo) {}
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
14
src/test/ui/lifetimes/issue-79187.nll.stderr
Normal file
14
src/test/ui/lifetimes/issue-79187.nll.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187.rs:5:5
|
||||
|
|
||||
LL | thing(f);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/issue-79187.rs:5:5
|
||||
|
|
||||
LL | thing(f);
|
||||
| ^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
6
src/test/ui/lifetimes/issue-79187.rs
Normal file
6
src/test/ui/lifetimes/issue-79187.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn thing(x: impl FnOnce(&u32)) {}
|
||||
|
||||
fn main() {
|
||||
let f = |_| ();
|
||||
thing(f); //~ERROR mismatched types
|
||||
}
|
22
src/test/ui/lifetimes/issue-79187.stderr
Normal file
22
src/test/ui/lifetimes/issue-79187.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-79187.rs:5:5
|
||||
|
|
||||
LL | thing(f);
|
||||
| ^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `FnOnce<(&u32,)>`
|
||||
found type `FnOnce<(&u32,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-79187.rs:4:13
|
||||
|
|
||||
LL | let f = |_| ();
|
||||
| ^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-79187.rs:1:18
|
||||
|
|
||||
LL | fn thing(x: impl FnOnce(&u32)) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -26,37 +26,77 @@ error[E0308]: mismatched types
|
||||
--> $DIR/closure-arg-type-mismatch.rs:10:5
|
||||
|
|
||||
LL | baz(f);
|
||||
| ^^^ one type is more general than the other
|
||||
| ^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(*mut &'r u32,)>`
|
||||
found type `Fn<(*mut &'a u32,)>`
|
||||
note: the required lifetime does not necessarily outlive the lifetime `'a` as defined on the function body at 9:10
|
||||
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
||||
|
|
||||
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
||||
|
|
||||
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-arg-type-mismatch.rs:10:5
|
||||
|
|
||||
LL | baz(f);
|
||||
| ^^^ one type is more general than the other
|
||||
| ^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `FnOnce<(*mut &u32,)>`
|
||||
found type `FnOnce<(*mut &'a u32,)>`
|
||||
note: the required lifetime does not necessarily outlive the lifetime `'a` as defined on the function body at 9:10
|
||||
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
||||
|
|
||||
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
||||
|
|
||||
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-arg-type-mismatch.rs:10:5
|
||||
|
|
||||
LL | baz(f);
|
||||
| ^^^ one type is more general than the other
|
||||
| ^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(*mut &'r u32,)>`
|
||||
found type `Fn<(*mut &'a u32,)>`
|
||||
note: the lifetime `'a` as defined on the function body at 9:10 doesn't meet the lifetime requirements
|
||||
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
||||
|
|
||||
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
||||
|
|
||||
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/closure-arg-type-mismatch.rs:10:5
|
||||
|
|
||||
LL | baz(f);
|
||||
| ^^^ one type is more general than the other
|
||||
| ^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `FnOnce<(*mut &u32,)>`
|
||||
found type `FnOnce<(*mut &'a u32,)>`
|
||||
note: the lifetime `'a` as defined on the function body at 9:10 doesn't meet the lifetime requirements
|
||||
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
||||
|
|
||||
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
|
||||
| ^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
||||
|
|
||||
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -2,10 +2,20 @@ error[E0308]: mismatched types
|
||||
--> $DIR/closure-mismatch.rs:8:5
|
||||
|
|
||||
LL | baz(|_| ());
|
||||
| ^^^ one type is more general than the other
|
||||
| ^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r (),)>`
|
||||
found type `Fn<(&(),)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/closure-mismatch.rs:8:9
|
||||
|
|
||||
LL | baz(|_| ());
|
||||
| ^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/closure-mismatch.rs:5:11
|
||||
|
|
||||
LL | fn baz<T: Foo>(_: T) {}
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -18,6 +18,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'static X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:17:16
|
||||
@ -27,6 +32,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `FnOnce<(&X,)>`
|
||||
found type `FnOnce<(&'static X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -6,6 +6,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `FnOnce<(&X,)>`
|
||||
found type `FnOnce<(&X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:17:16
|
||||
@ -15,6 +20,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:17:16
|
||||
@ -24,6 +34,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `FnOnce<(&X,)>`
|
||||
found type `FnOnce<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:17:16
|
||||
@ -33,6 +48,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `for<'r> Fn<(&'r X,)>`
|
||||
found type `Fn<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57611-trait-alias.rs:17:16
|
||||
@ -42,6 +62,11 @@ LL | type Bar = impl Baz<Self, Self>;
|
||||
|
|
||||
= note: expected type `FnOnce<(&X,)>`
|
||||
found type `FnOnce<(&'<empty> X,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-57611-trait-alias.rs:25:9
|
||||
|
|
||||
LL | |x| x
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -2,10 +2,15 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-30906.rs:15:5
|
||||
|
|
||||
LL | test(Compose(f, |_| {}));
|
||||
| ^^^^ one type is more general than the other
|
||||
| ^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected type `FnOnce<(&'x str,)>`
|
||||
found type `FnOnce<(&str,)>`
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-30906.rs:3:12
|
||||
|
|
||||
LL | fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user