Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #65451

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
48fff6f
don't assume we can *always* find a return type hint in async fn
nikomatsakis Oct 9, 2019
061b906
Return `false` from `needs_drop` for all zero-sized arrays
ecstatic-morse Oct 13, 2019
8fd16ba
Remove special case for zero-sized arrays from indirectly mut locals
ecstatic-morse Oct 13, 2019
c08a871
Add regression test for #65348
ecstatic-morse Oct 13, 2019
f81b154
Add troubleshooting section to PGO chapter in rustc book.
michaelwoerister Oct 14, 2019
7528234
Add regression test for issue #64153.
michaelwoerister Oct 14, 2019
af05b23
Fix issue #64153 by checking for .rcgu.o suffix when trying to identi…
michaelwoerister Oct 15, 2019
53187c5
Slides path lifetime to the lifetime resolver
Phosphorus15 Oct 11, 2019
1fb8cfb
Organize `never_type` tests
Centril Oct 15, 2019
d82c1c5
Avoid unused lifetime warning for lifetimes introduced when desugerin…
gilescope Oct 15, 2019
fa3a4ae
Implement AsRef<[T]> for List<T>
spastorino Oct 15, 2019
c1f51b6
Rollup merge of #64603 - gilescope:unused-lifetime-warning, r=matthew…
Centril Oct 15, 2019
fd1cf87
Rollup merge of #65235 - nikomatsakis:issue-65159-async-fn-return-ice…
Centril Oct 15, 2019
2abce06
Rollup merge of #65307 - Phosphorus15:master, r=varkor
Centril Oct 15, 2019
2feabbb
Rollup merge of #65389 - ecstatic-morse:zero-sized-array-no-drop, r=e…
Centril Oct 15, 2019
a32fd51
Rollup merge of #65402 - michaelwoerister:pgo-troubleshooting-docs, r…
Centril Oct 15, 2019
d4e2f44
Rollup merge of #65435 - michaelwoerister:fix-issue-64153, r=alexcric…
Centril Oct 15, 2019
f46d291
Rollup merge of #65438 - Centril:almost, r=varkor
Centril Oct 15, 2019
453d011
Rollup merge of #65444 - spastorino:as-ref-for-list, r=Mark-Simulacrum
Centril Oct 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/doc/rustc/src/profile-guided-optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \
cargo build --release --target=x86_64-unknown-linux-gnu
```

### Troubleshooting

- It is recommended to pass `-Cllvm-args=-pgo-warn-missing-function` during the
`-Cprofile-use` phase. LLVM by default does not warn if it cannot find
profiling data for a given function. Enabling this warning will make it
easier to spot errors in your setup.

- There is a [known issue](https://github.com/rust-lang/cargo/issues/7416) in
Cargo prior to version 1.39 that will prevent PGO from working correctly. Be
sure to use Cargo 1.39 or newer when doing PGO.

## Further Reading

`rustc`'s PGO support relies entirely on LLVM's implementation of the feature
Expand Down
12 changes: 8 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3291,10 +3291,14 @@ impl<'a> LoweringContext<'a> {
let id = self.sess.next_node_id();
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
// This is the normal case.
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),

AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
// `PassThrough` is the normal case.
// `new_error_lifetime`, which would usually be used in the case of `ReportError`,
// is unsuitable here, as these can occur from missing lifetime parameters in a
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted.
| AnonymousLifetimeMode::PassThrough
| AnonymousLifetimeMode::ReportError => self.new_implicit_lifetime(span),
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,15 +708,22 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
match param.kind {
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, &param);
let def_id = if let Region::EarlyBound(_ ,def_id , _) = reg {
def_id
} else {
bug!();
};
if let hir::ParamName::Plain(param_name) = name {
if param_name.name == kw::UnderscoreLifetime {
// Pick the elided lifetime "definition" if one exists
// and use it to make an elision scope.
self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
elision = Some(reg);
} else {
lifetimes.insert(name, reg);
}
} else {
self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
lifetimes.insert(name, reg);
}
}
Expand Down Expand Up @@ -1615,7 +1622,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
_ => None,
} {
debug!("id = {:?} span = {:?} name = {:?}", id, span, name);

if name.name == kw::UnderscoreLifetime {
continue;
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,13 @@ impl<T> Deref for List<T> {
type Target = [T];
#[inline(always)]
fn deref(&self) -> &[T] {
self.as_ref()
}
}

impl<T> AsRef<[T]> for List<T> {
#[inline(always)]
fn as_ref(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self.data.as_ptr(), self.len)
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,9 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>

ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

// Zero-length arrays never contain anything to drop.
ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false,

// Structural recursion.
ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty),

Expand Down
6 changes: 4 additions & 2 deletions src/librustc_codegen_llvm/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use std::str;

use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind};
use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
use rustc_codegen_ssa::{
METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, looks_like_rust_object_file
};
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library};
use rustc::session::Session;
use syntax::symbol::Symbol;
Expand Down Expand Up @@ -141,7 +143,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
}

// Don't include Rust objects if LTO is enabled
if lto && fname.starts_with(&obj_start) && fname.ends_with(".o") {
if lto && looks_like_rust_object_file(fname) {
return true
}

Expand Down
21 changes: 4 additions & 17 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use rustc::session::{Session, filesearch};
use rustc::session::config::{
self, RUST_CGU_EXT, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer
self, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer
};
use rustc::session::search_paths::PathKind;
use rustc::middle::dependency_format::Linkage;
Expand All @@ -15,7 +15,8 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
use syntax::symbol::Symbol;

use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo, CodegenResults};
use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo,
looks_like_rust_object_file, CodegenResults};
use super::archive::ArchiveBuilder;
use super::command::Command;
use super::linker::Linker;
Expand Down Expand Up @@ -1549,23 +1550,9 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
let canonical = f.replace("-", "_");
let canonical_name = name.replace("-", "_");

// Look for `.rcgu.o` at the end of the filename to conclude
// that this is a Rust-related object file.
fn looks_like_rust(s: &str) -> bool {
let path = Path::new(s);
let ext = path.extension().and_then(|s| s.to_str());
if ext != Some(OutputType::Object.extension()) {
return false
}
let ext2 = path.file_stem()
.and_then(|s| Path::new(s).extension())
.and_then(|s| s.to_str());
ext2 == Some(RUST_CGU_EXT)
}

let is_rust_object =
canonical.starts_with(&canonical_name) &&
looks_like_rust(&f);
looks_like_rust_object_file(&f);

// If we've been requested to skip all native object files
// (those not generated by the rust compiler) then we can skip
Expand Down
24 changes: 22 additions & 2 deletions src/librustc_codegen_ssa/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#[macro_use] extern crate rustc;
#[macro_use] extern crate syntax;

use std::path::PathBuf;
use std::path::{Path, PathBuf};
use rustc::dep_graph::WorkProduct;
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::session::config::{OutputFilenames, OutputType, RUST_CGU_EXT};
use rustc::middle::lang_items::LangItem;
use rustc::hir::def_id::CrateNum;
use rustc::ty::query::Providers;
Expand Down Expand Up @@ -62,6 +62,7 @@ pub struct ModuleCodegen<M> {
pub const METADATA_FILENAME: &str = "rust.metadata.bin";
pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";


impl<M> ModuleCodegen<M> {
pub fn into_compiled_module(self,
emit_obj: bool,
Expand Down Expand Up @@ -166,3 +167,22 @@ pub fn provide_extern(providers: &mut Providers<'_>) {
crate::back::symbol_export::provide_extern(providers);
crate::base::provide_both(providers);
}

/// Checks if the given filename ends with the `.rcgu.o` extension that `rustc`
/// uses for the object files it generates.
pub fn looks_like_rust_object_file(filename: &str) -> bool {
let path = Path::new(filename);
let ext = path.extension().and_then(|s| s.to_str());
if ext != Some(OutputType::Object.extension()) {
// The file name does not end with ".o", so it can't be an object file.
return false
}

// Strip the ".o" at the end
let ext2 = path.file_stem()
.and_then(|s| Path::new(s).extension())
.and_then(|s| s.to_str());

// Check if the "inner" extension
ext2 == Some(RUST_CGU_EXT)
}
17 changes: 4 additions & 13 deletions src/librustc_mir/dataflow/impls/indirect_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,25 +104,16 @@ impl<'tcx> TransferFunction<'_, '_, 'tcx> {
kind: mir::BorrowKind,
borrowed_place: &mir::Place<'tcx>,
) -> bool {
let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty;

// Zero-sized types cannot be mutated, since there is nothing inside to mutate.
//
// FIXME: For now, we only exempt arrays of length zero. We need to carefully
// consider the effects before extending this to all ZSTs.
if let ty::Array(_, len) = borrowed_ty.kind {
if len.try_eval_usize(self.tcx, self.param_env) == Some(0) {
return false;
}
}

match kind {
mir::BorrowKind::Mut { .. } => true,

| mir::BorrowKind::Shared
| mir::BorrowKind::Shallow
| mir::BorrowKind::Unique
=> !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP),
=> !borrowed_place
.ty(self.body, self.tcx)
.ty
.is_freeze(self.tcx, self.param_env, DUMMY_SP),
}
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
debug!("supplied_sig_of_closure: closure is async fn body");
self.deduce_future_output_from_obligations(expr_def_id)
.unwrap_or_else(|| {
// AFAIK, deducing the future output
// always succeeds *except* in error cases
// like #65159. I'd like to return Error
// here, but I can't because I can't
// easily (and locally) prove that we
// *have* reported an
// error. --nikomatsakis
astconv.ty_infer(None, decl.output.span())
})
}

_ => astconv.ty_infer(None, decl.output.span()),
Expand Down Expand Up @@ -645,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn deduce_future_output_from_obligations(
&self,
expr_def_id: DefId,
) -> Ty<'tcx> {
) -> Option<Ty<'tcx>> {
debug!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id);

let ret_coercion =
Expand Down Expand Up @@ -688,8 +698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
None
}
})
.unwrap();
});

debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
output_ty
Expand Down
20 changes: 20 additions & 0 deletions src/test/run-make-fulldeps/issue-64153/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-include ../tools.mk

# Staticlibs don't include Rust object files from upstream crates if the same
# code was already pulled into the lib via LTO. However, the bug described in
# https://github.com/rust-lang/rust/issues/64153 lead to this exclusion not
# working properly if the upstream crate was compiled with an explicit filename
# (via `-o`).
#
# This test makes sure that functions defined in the upstream crates do not
# appear twice in the final staticlib when listing all the symbols from it.

all:
$(RUSTC) --crate-type rlib upstream.rs -o $(TMPDIR)/libupstream.rlib -Ccodegen-units=1
$(RUSTC) --crate-type staticlib downstream.rs -Clto -Ccodegen-units=1 -o $(TMPDIR)/libdownstream.a
# Dump all the symbols from the staticlib into `syms`
nm $(TMPDIR)/libdownstream.a > $(TMPDIR)/syms
# Count the global instances of `issue64153_test_function`. There'll be 2
# if the `upstream` object file got erronously included twice.
grep -c -e "[[:space:]]T[[:space:]]issue64153_test_function" $(TMPDIR)/syms > $(TMPDIR)/count
[ "$$(cat $(TMPDIR)/count)" -eq "1" ]
6 changes: 6 additions & 0 deletions src/test/run-make-fulldeps/issue-64153/downstream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern crate upstream;

#[no_mangle]
pub extern "C" fn foo() {
print!("1 + 1 = {}", upstream::issue64153_test_function(1));
}
6 changes: 6 additions & 0 deletions src/test/run-make-fulldeps/issue-64153/upstream.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Make this function extern "C", public, and no-mangle, so that it gets
// exported from the downstream staticlib.
#[no_mangle]
pub extern "C" fn issue64153_test_function(x: u32) -> u32 {
x + 1
}
10 changes: 10 additions & 0 deletions src/test/ui/async-await/issues/issue-65159.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Regression test for #65159. We used to ICE.
//
// edition:2018

async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
{
Ok(())
}

fn main() { }
9 changes: 9 additions & 0 deletions src/test/ui/async-await/issues/issue-65159.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0107]: wrong number of type arguments: expected 2, found 1
--> $DIR/issue-65159.rs:5:20
|
LL | async fn copy() -> Result<()>
| ^^^^^^^^^^ expected 2 type arguments

error: aborting due to previous error

For more information about this error, try `rustc --explain E0107`.
42 changes: 42 additions & 0 deletions src/test/ui/async-await/unused-lifetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// edition:2018

// Avoid spurious warnings of unused lifetime. The below async functions
// are desugered to have an unused lifetime
// but we don't want to warn about that as there's nothing they can do about it.

#![deny(unused_lifetimes)]
#![allow(dead_code)]

pub async fn october(s: &str) {
println!("{}", s);
}

pub async fn async_fn(&mut ref s: &mut[i32]) {
println!("{:?}", s);
}

macro_rules! foo_macro {
() => {
pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {}
};
}

foo_macro!();

pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
//~^ ERROR lifetime parameter `'a` never used
println!("{}", s);
}

pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
//~^ ERROR lifetime parameter `'a` never used
//~^^ ERROR lifetime parameter `'b` never used
println!("{}", s);
}

pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
//~^ ERROR lifetime parameter `'c` never used
println!("{}", s);
}

fn main() {}
32 changes: 32 additions & 0 deletions src/test/ui/async-await/unused-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error: lifetime parameter `'a` never used
--> $DIR/unused-lifetime.rs:26:40
|
LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
| ^^
|
note: lint level defined here
--> $DIR/unused-lifetime.rs:7:9
|
LL | #![deny(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^

error: lifetime parameter `'a` never used
--> $DIR/unused-lifetime.rs:31:44
|
LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
| ^^

error: lifetime parameter `'b` never used
--> $DIR/unused-lifetime.rs:31:48
|
LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
| ^^

error: lifetime parameter `'c` never used
--> $DIR/unused-lifetime.rs:37:54
|
LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
| ^^

error: aborting due to 4 previous errors

Loading