From d61605cef866008a19e33eb596df1d76ff1571f3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2019 09:03:58 +1000 Subject: [PATCH 1/6] Don't call `self.parse()` in `Compiler::crate_name()` unless necessary. --- src/librustc_interface/queries.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index ed50dadb60099..996e9fae0db56 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -126,17 +126,18 @@ impl Compiler { pub fn crate_name(&self) -> Result<&Query> { self.queries.crate_name.compute(|| { - let parse_result = self.parse()?; - let krate = parse_result.peek(); - let result = match self.crate_name { + Ok(match self.crate_name { Some(ref crate_name) => crate_name.clone(), - None => rustc_codegen_utils::link::find_crate_name( - Some(self.session()), - &krate.attrs, - &self.input - ), - }; - Ok(result) + None => { + let parse_result = self.parse()?; + let krate = parse_result.peek(); + rustc_codegen_utils::link::find_crate_name( + Some(self.session()), + &krate.attrs, + &self.input + ) + } + }) }) } From cd0c21b0e5b68e29c63c3c98db9147cb0e5a3bc8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2019 16:24:01 +1000 Subject: [PATCH 2/6] Remove `lower_to_hir()` call from `prepare_output()`. It's a false dependency. The result isn't used and there are no relevant side-effects. --- src/librustc_interface/queries.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 996e9fae0db56..c281bc5360704 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -195,7 +195,6 @@ impl Compiler { pub fn prepare_outputs(&self) -> Result<&Query> { self.queries.prepare_outputs.compute(|| { - self.lower_to_hir()?; let krate = self.expansion()?; let krate = krate.peek(); let crate_name = self.crate_name()?; From c6117d949922a382d7b1ba11a523ea9aeafcabd4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2019 11:25:16 +1000 Subject: [PATCH 3/6] Merge `Compiler::{ongoing_codegen,link}`. They each have two call sites, and the sequencing is almost identical in both cases. --- src/librustc_driver/lib.rs | 7 +------ src/librustc_interface/queries.rs | 33 +++++++++++-------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 9a6a12e261c10..320b5b88a1d3d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -383,17 +383,12 @@ pub fn run_compiler( mem::drop(compiler.expansion()?.take()); } - compiler.ongoing_codegen()?; - - // Drop GlobalCtxt after starting codegen to free memory - mem::drop(compiler.global_ctxt()?.take()); + compiler.codegen_and_link()?; if sess.opts.debugging_opts.print_type_sizes { sess.code_stats.borrow().print_type_sizes(); } - compiler.link()?; - if sess.opts.debugging_opts.perf_stats { sess.print_perf_stats(); } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index c281bc5360704..5f8935dc0c256 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -83,8 +83,7 @@ pub(crate) struct Queries { codegen_channel: Query<(Steal>>, Steal>>)>, global_ctxt: Query, - ongoing_codegen: Query>, - link: Query<()>, + codegen_and_link: Query<()>, } impl Compiler { @@ -230,14 +229,14 @@ impl Compiler { }) } - pub fn ongoing_codegen(&self) -> Result<&Query>> { - self.queries.ongoing_codegen.compute(|| { + pub fn codegen_and_link(&self) -> Result<&Query<()>> { + self.queries.codegen_and_link.compute(|| { let rx = self.codegen_channel()?.peek().1.steal(); let outputs = self.prepare_outputs()?; - self.global_ctxt()?.peek_mut().enter(|tcx| { + let ongoing_codegen = self.global_ctxt()?.peek_mut().enter(|tcx| { tcx.analysis(LOCAL_CRATE).ok(); - // Don't do code generation if there were any errors + // Don't do code generation if there were any errors. self.session().compile_status()?; Ok(passes::start_codegen( @@ -246,21 +245,16 @@ impl Compiler { rx, &*outputs.peek() )) - }) - }) - } - - pub fn link(&self) -> Result<&Query<()>> { - self.queries.link.compute(|| { - let sess = self.session(); + })?; - let ongoing_codegen = self.ongoing_codegen()?.take(); + // Drop GlobalCtxt after starting codegen to free memory. + mem::drop(self.global_ctxt()?.take()); self.codegen_backend().join_codegen_and_link( ongoing_codegen, - sess, + self.session(), &*self.dep_graph()?.peek(), - &*self.prepare_outputs()?.peek(), + &*outputs.peek(), ).map_err(|_| ErrorReported)?; Ok(()) @@ -281,11 +275,6 @@ impl Compiler { // Drop AST after creating GlobalCtxt to free memory mem::drop(self.expansion()?.take()); - self.ongoing_codegen()?; - - // Drop GlobalCtxt after starting codegen to free memory - mem::drop(self.global_ctxt()?.take()); - - self.link().map(|_| ()) + self.codegen_and_link().map(|_| ()) } } From df952caf669ea62fad8029c965b7e0c3385d21cf Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2019 16:53:34 +1000 Subject: [PATCH 4/6] Move call site of `dep_graph_future()`. `Compiler::register_plugins()` calls `passes::register_plugins()`, which calls `Compiler::dep_graph_future()`. This is the only way in which a `passes` function calls a `Compiler` function. This commit moves the `dep_graph_future()` call out of `passes::register_plugins()` and into `Compiler::register_plugins()`, which is a more sensible spot for it. This will delay the loading of the dep graph slightly -- from the middle of plugin registration to the end of plugin registration -- but plugin registration is fast enough (especially compared to expansion) that the impact should be neglible. --- src/librustc_interface/passes.rs | 4 ---- src/librustc_interface/queries.rs | 14 +++++++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 24b44964e4fd2..200da05c57561 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -223,7 +223,6 @@ pub struct PluginInfo { } pub fn register_plugins<'a>( - compiler: &Compiler, sess: &'a Session, cstore: &'a CStore, mut krate: ast::Crate, @@ -261,9 +260,6 @@ pub fn register_plugins<'a>( }); } - // If necessary, compute the dependency graph (in the background). - compiler.dep_graph_future().ok(); - time(sess, "recursion limit", || { middle::recursion_limit::update_limits(sess, &krate); }); diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 5f8935dc0c256..e8aa0e1b4533e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -113,13 +113,21 @@ impl Compiler { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); - passes::register_plugins( - self, + let result = passes::register_plugins( self.session(), self.cstore(), krate, &crate_name, - ) + ); + + // Compute the dependency graph (in the background). We want to do + // this as early as possible, to give the DepGraph maximum time to + // load before dep_graph() is called, but it also can't happen + // until after rustc_incremental::prepare_session_directory() is + // called, which happens within passes::register_plugins(). + self.dep_graph_future().ok(); + + result }) } From 92a0cbd3c30ce26498739c8f18cba6ab0cd4e7f8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Aug 2019 17:27:35 +1000 Subject: [PATCH 5/6] Remove `Compiler::compile()`. `Compiler::compile()` is different to all the other `Compiler` methods because it lacks a `Queries` entry. It only has one call site, which is in a test that doesn't need its specific characteristics. This patch removes `Compile::compile()` and replaces the call to it in the test with a call to `Compile::codegen_and_link()`, which is similar enough for the test's purposes. --- src/librustc_interface/queries.rs | 23 +++---------------- src/test/run-make-fulldeps/issue-19371/foo.rs | 2 +- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index e8aa0e1b4533e..ca56c04bebb68 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,17 +2,17 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; -use rustc::session::config::{OutputFilenames, OutputType}; +use rustc::session::config::OutputFilenames; use rustc::util::common::{time, ErrorReported}; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; +use std::any::Any; use std::cell::{Ref, RefMut, RefCell}; +use std::mem; use std::rc::Rc; use std::sync::mpsc; -use std::any::Any; -use std::mem; use syntax::{self, ast}; /// Represent the result of a query. @@ -268,21 +268,4 @@ impl Compiler { Ok(()) }) } - - pub fn compile(&self) -> Result<()> { - self.prepare_outputs()?; - - if self.session().opts.output_types.contains_key(&OutputType::DepInfo) - && self.session().opts.output_types.len() == 1 - { - return Ok(()) - } - - self.global_ctxt()?; - - // Drop AST after creating GlobalCtxt to free memory - mem::drop(self.expansion()?.take()); - - self.codegen_and_link().map(|_| ()) - } } diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index afc92638fda97..118205671e5d8 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -62,6 +62,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { }; interface::run_compiler(config, |compiler| { - compiler.compile().ok(); + compiler.codegen_and_link().ok(); }); } From c5f5e5b5f655d20f1c3a0f3c19ae13ec19d4bb39 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 2 Sep 2019 13:14:52 +1000 Subject: [PATCH 6/6] [DRAFT] Move metadata generation before analysis. The goal of this commit is to improve the effectiveness of pipelining, because metadata generation must complete before dependent crates can begin compiling. Unfortunately it's not much of a win. The biggest speed-up I have seen is 1.07x, vs 1.79x for the original pipelining implementation. And it slightly slows down the common case when an error occurs during analysis, because metadata generation now precedes analysis. Currently three tests fail with the change, due to bounds violations. These tests are currently `git rm`'d, so that subsequent tests can run. --- src/librustc/middle/dependency_format.rs | 6 +- src/librustc_driver/lib.rs | 7 + src/librustc_interface/passes.rs | 25 +- src/librustc_interface/queries.rs | 17 ++ ...ed-types-ICE-when-projecting-out-of-err.rs | 25 -- ...ypes-ICE-when-projecting-out-of-err.stderr | 9 - .../associated-types-issue-20346.rs | 35 --- .../associated-types-issue-20346.stderr | 15 - .../ui/c-variadic/variadic-ffi-4.nll.stderr | 111 ------- src/test/ui/c-variadic/variadic-ffi-4.rs | 35 --- src/test/ui/c-variadic/variadic-ffi-4.stderr | 275 ------------------ 11 files changed, 45 insertions(+), 515 deletions(-) delete mode 100644 src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs delete mode 100644 src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr delete mode 100644 src/test/ui/associated-types/associated-types-issue-20346.rs delete mode 100644 src/test/ui/associated-types/associated-types-issue-20346.stderr delete mode 100644 src/test/ui/c-variadic/variadic-ffi-4.nll.stderr delete mode 100644 src/test/ui/c-variadic/variadic-ffi-4.rs delete mode 100644 src/test/ui/c-variadic/variadic-ffi-4.stderr diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 96b99fe4cdce2..5da903427133c 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -81,14 +81,16 @@ pub enum Linkage { Dynamic, } -pub fn calculate(tcx: TyCtxt<'_>) { +pub fn calculate(tcx: TyCtxt<'_>, abort_if_errors: bool) { let sess = &tcx.sess; let fmts = sess.crate_types.borrow().iter().map(|&ty| { let linkage = calculate_type(tcx, ty); verify_ok(tcx, &linkage); (ty, linkage) }).collect::>(); - sess.abort_if_errors(); + if abort_if_errors { + sess.abort_if_errors(); + } sess.dependency_formats.set(fmts); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 320b5b88a1d3d..891a52d443d0d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -347,6 +347,11 @@ pub fn run_compiler( return sess.compile_status(); } + // We want metadata generation to be as early as possible, i.e. before + // the analysis phases, to maximize pipelining opportunities. But wait + // until after the analysis phases to abort if there are errors. + compiler.do_metadata(/* abort_if_errors */ false)?; + if sess.opts.debugging_opts.save_analysis { let expanded_crate = &compiler.expansion()?.peek().0; let crate_name = compiler.crate_name()?.peek().clone(); @@ -375,6 +380,8 @@ pub fn run_compiler( compiler.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; + sess.abort_if_errors(); + if callbacks.after_analysis(compiler) == Compilation::Stop { return sess.compile_status(); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 200da05c57561..c43beecc960a3 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -1077,12 +1077,29 @@ fn encode_and_write_metadata( (metadata, need_metadata_module) } +/// Do metadata generation. +pub fn do_metadata<'tcx>( + tcx: TyCtxt<'tcx>, + outputs: &OutputFilenames, + abort_if_errors: bool, +) -> (middle::cstore::EncodedMetadata, bool) { + time(tcx.sess, "resolving dependency formats", || { + middle::dependency_format::calculate(tcx, abort_if_errors) + }); + + time(tcx.sess, "metadata encoding and writing", || { + encode_and_write_metadata(tcx, outputs) + }) +} + /// Runs the codegen backend, after which the AST and analysis can /// be discarded. pub fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, rx: mpsc::Receiver>, + metadata: middle::cstore::EncodedMetadata, + need_metadata_module: bool, outputs: &OutputFilenames, ) -> Box { if log_enabled!(::log::Level::Info) { @@ -1090,14 +1107,6 @@ pub fn start_codegen<'tcx>( tcx.print_debug_stats(); } - time(tcx.sess, "resolving dependency formats", || { - middle::dependency_format::calculate(tcx) - }); - - let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || { - encode_and_write_metadata(tcx, outputs) - }); - tcx.sess.profiler(|p| p.start_activity("codegen crate")); let codegen = time(tcx.sess, "codegen", move || { codegen_backend.codegen_crate(tcx, metadata, need_metadata_module, rx) diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index ca56c04bebb68..e87a187ff9e1b 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -6,6 +6,7 @@ use rustc::session::config::OutputFilenames; use rustc::util::common::{time, ErrorReported}; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; +use rustc::middle::cstore; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; use std::any::Any; @@ -83,6 +84,7 @@ pub(crate) struct Queries { codegen_channel: Query<(Steal>>, Steal>>)>, global_ctxt: Query, + do_metadata: Query<(cstore::EncodedMetadata, bool)>, codegen_and_link: Query<()>, } @@ -237,10 +239,23 @@ impl Compiler { }) } + pub fn do_metadata(&self, abort_if_errors: bool) + -> Result<&Query<(cstore::EncodedMetadata, bool)>> { + self.queries.do_metadata.compute(|| { + let outputs = self.prepare_outputs()?; + Ok(self.global_ctxt()?.peek_mut().enter(|tcx| { + passes::do_metadata(tcx, &*outputs.peek(), abort_if_errors) + })) + }) + } + pub fn codegen_and_link(&self) -> Result<&Query<()>> { self.queries.codegen_and_link.compute(|| { let rx = self.codegen_channel()?.peek().1.steal(); let outputs = self.prepare_outputs()?; + let (metadata, need_metadata_module) = + self.do_metadata(/* abort_if_errors */ true)?.take(); + let ongoing_codegen = self.global_ctxt()?.peek_mut().enter(|tcx| { tcx.analysis(LOCAL_CRATE).ok(); @@ -251,6 +266,8 @@ impl Compiler { &***self.codegen_backend(), tcx, rx, + metadata, + need_metadata_module, &*outputs.peek() )) })?; diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs deleted file mode 100644 index 707bcac78bf92..0000000000000 --- a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Test that we do not ICE when the self type is `ty::err`, but rather -// just propagate the error. - -#![crate_type = "lib"] -#![feature(lang_items)] -#![feature(no_core)] -#![no_core] - -#[lang="sized"] -pub trait Sized { - // Empty. -} - -#[lang = "add"] -trait Add { - type Output; - - fn add(self, _: RHS) -> Self::Output; -} - -fn ice(a: A) { - let r = loop {}; - r = r + a; - //~^ ERROR the trait bound `(): Add` is not satisfied -} diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr deleted file mode 100644 index 8c3463a2832e0..0000000000000 --- a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0277]: the trait bound `(): Add` is not satisfied - --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11 - | -LL | r = r + a; - | ^ the trait `Add` is not implemented for `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-types/associated-types-issue-20346.rs b/src/test/ui/associated-types/associated-types-issue-20346.rs deleted file mode 100644 index 0cce847e1be54..0000000000000 --- a/src/test/ui/associated-types/associated-types-issue-20346.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Test that we reliably check the value of the associated type. - -#![crate_type = "lib"] -#![no_implicit_prelude] - -use std::option::Option::{self, None, Some}; -use std::vec::Vec; - -trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} - -fn is_iterator_of>(_: &I) {} - -struct Adapter { - iter: I, - found_none: bool, -} - -impl Iterator for Adapter where I: Iterator> { - type Item = T; - - fn next(&mut self) -> Option { - loop {} - } -} - -fn test_adapter>>(it: I) { - is_iterator_of::, _>(&it); // Sanity check - let adapter = Adapter { iter: it, found_none: false }; - is_iterator_of::(&adapter); // OK - is_iterator_of::, _>(&adapter); //~ ERROR type mismatch -} diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr deleted file mode 100644 index 7d6c025d69d55..0000000000000 --- a/src/test/ui/associated-types/associated-types-issue-20346.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0271]: type mismatch resolving ` as Iterator>::Item == std::option::Option` - --> $DIR/associated-types-issue-20346.rs:34:5 - | -LL | fn is_iterator_of>(_: &I) {} - | ------------------------------------------------ required by `is_iterator_of` -... -LL | is_iterator_of::, _>(&adapter); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option` - | - = note: expected type `T` - found type `std::option::Option` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr deleted file mode 100644 index 4947d6e529108..0000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ /dev/null @@ -1,111 +0,0 @@ -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | --- help: add explicit lifetime `'f` to the type of `ap`: `core::ffi::VaListImpl<'f>` -LL | ap - | ^^ lifetime `'f` required - -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-4.rs:12:5 - | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaListImpl<'static>` -LL | ap - | ^^ lifetime `'static` required - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:16:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is core::ffi::VaList<'2, '_> - | has type `core::ffi::VaList<'1, '_>` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:20:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:20:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'1>` - | | - | has type `&mut core::ffi::VaListImpl<'2>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:25:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:25:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- ------- has type `core::ffi::VaListImpl<'1>` - | | - | has type `&mut core::ffi::VaListImpl<'2>` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` - -error[E0384]: cannot assign to immutable argument `ap0` - --> $DIR/variadic-ffi-4.rs:25:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | --- help: make this binding mutable: `mut ap0` -LL | ap0 = &mut ap1; - | ^^^^^^^^^^^^^^ cannot assign to immutable argument - -error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | - let's call the lifetime of this reference `'1` -LL | ap0 = &mut ap1; - | ------^^^^^^^^ - | | | - | | borrowed value does not live long enough - | assignment requires that `ap1` is borrowed for `'1` -... -LL | } - | - `ap1` dropped here while still borrowed - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:33:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'2>` - | | - | has type `&mut core::ffi::VaListImpl<'1>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:33:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `core::ffi::VaListImpl<'1>` - | | - | has type `&mut core::ffi::VaListImpl<'2>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - -error: aborting due to 11 previous errors - -Some errors have detailed explanations: E0384, E0597, E0621. -For more information about an error, try `rustc --explain E0384`. diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs deleted file mode 100644 index 4a50d352a5b20..0000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-4.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![crate_type="lib"] -#![no_std] -#![feature(c_variadic)] - -use core::ffi::{VaList, VaListImpl}; - -pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - ap //~ ERROR: explicit lifetime required -} - -pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - ap //~ ERROR: explicit lifetime required -} - -pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime -} - -pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - *ap0 = ap1; //~ ERROR: mismatched types - //~^ ERROR: mismatched types -} - -pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - ap0 = &mut ap1; - //~^ ERROR: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - //~^^ ERROR: mismatched types - //~^^^ ERROR: mismatched types - //~^^^^ ERROR: cannot infer an appropriate lifetime -} - -pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - *ap0 = ap1.clone(); //~ ERROR: mismatched types - //~^ ERROR: mismatched types -} diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr deleted file mode 100644 index 7aa510e611304..0000000000000 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ /dev/null @@ -1,275 +0,0 @@ -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | --- help: add explicit lifetime `'f` to the type of `ap`: `core::ffi::VaListImpl<'f>` -LL | ap - | ^^ lifetime `'f` required - -error[E0621]: explicit lifetime required in the type of `ap` - --> $DIR/variadic-ffi-4.rs:12:5 - | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaListImpl<'static>` -LL | ap - | ^^ lifetime `'static` required - -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:16:33 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:26... - --> $DIR/variadic-ffi-4.rs:16:26 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^ - = note: ...so that the expression is assignable: - expected core::ffi::VaList<'_, '_> - found core::ffi::VaList<'_, '_> -note: but, the lifetime must be valid for the method call at 16:13... - --> $DIR/variadic-ffi-4.rs:16:13 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...so type `core::ffi::VaList<'_, '_>` of expression is valid during the expression - --> $DIR/variadic-ffi-4.rs:16:13 - | -LL | let _ = ap.with_copy(|ap| { ap }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:20:12 - | -LL | *ap0 = ap1; - | ^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 19:1... - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 19:1 - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:20:12 - | -LL | *ap0 = ap1; - | ^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 19:1... - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 19:1 - --> $DIR/variadic-ffi-4.rs:19:1 - | -LL | / pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1; -LL | | -LL | | } - | |_^ - -error[E0490]: a value of type `core::ffi::VaListImpl<'_>` is borrowed for too long - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ - | -note: the type is valid for the anonymous lifetime #1 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: but the borrow lasts for the anonymous lifetime #3 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ lifetime mismatch - | - = note: expected type `&mut core::ffi::VaListImpl<'_>` - found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ lifetime mismatch - | - = note: expected type `&mut core::ffi::VaListImpl<'_>` - found type `&mut core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 24:1 - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ - -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ - | -note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...so that the type `core::ffi::VaListImpl<'_>` is not borrowed for too long - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ -note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 24:1... - --> $DIR/variadic-ffi-4.rs:24:1 - | -LL | / pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { -LL | | ap0 = &mut ap1; -LL | | -LL | | -LL | | -LL | | -LL | | } - | |_^ -note: ...so that reference does not outlive borrowed content - --> $DIR/variadic-ffi-4.rs:25:11 - | -LL | ap0 = &mut ap1; - | ^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:33:12 - | -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #3 defined on the function body at 32:1... - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 32:1 - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ - -error[E0308]: mismatched types - --> $DIR/variadic-ffi-4.rs:33:12 - | -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ lifetime mismatch - | - = note: expected type `core::ffi::VaListImpl<'_>` - found type `core::ffi::VaListImpl<'_>` -note: the anonymous lifetime #2 defined on the function body at 32:1... - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ -note: ...does not necessarily outlive the anonymous lifetime #3 defined on the function body at 32:1 - --> $DIR/variadic-ffi-4.rs:32:1 - | -LL | / pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { -LL | | *ap0 = ap1.clone(); -LL | | -LL | | } - | |_^ - -error: aborting due to 11 previous errors - -Some errors have detailed explanations: E0308, E0621. -For more information about an error, try `rustc --explain E0308`.