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 7 pull requests #87232

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
5e7fed1
Add a regression test for issue-63355
JohnTitor Jun 30, 2021
e32ecee
Remove unnecessary CrateNum from Cache.externs
jyn514 Jul 5, 2021
a30fa08
Remove trival `impl Clean for CrateNum`
jyn514 Jul 5, 2021
d4238ee
Add --nocapture option to rustdoc
GuillaumeGomez Jun 11, 2021
0e3fc03
Add test for rustdoc --nocapture option
GuillaumeGomez Jun 11, 2021
769602b
Add doc for --nocapture
GuillaumeGomez Jun 11, 2021
c0a94c1
Don't capture child process output at all when --no-capture is used
GuillaumeGomez Jul 9, 2021
f9f6083
Add invalid rust code for test
GuillaumeGomez Jul 9, 2021
0d3d6f0
fix typo in compile_fail doctest
RalfJung Jul 16, 2021
ce59f1a
Consider all fields when comparing DllImports, to remove nondetermini…
ricobbe Jul 12, 2021
9b874c4
Check that const parameters of trait methods have compatible types
FabianWolff Jul 3, 2021
6ffb6c4
rustc_middle: remove redundant clone
matthiaskrgr Jul 16, 2021
6ca154d
Rollup merge of #86230 - GuillaumeGomez:nocapture, r=camelid
GuillaumeGomez Jul 17, 2021
9251217
Rollup merge of #86763 - JohnTitor:test-63355, r=oli-obk
GuillaumeGomez Jul 17, 2021
821ae76
Rollup merge of #86843 - FabianWolff:issue-86820, r=lcnr
GuillaumeGomez Jul 17, 2021
8662723
Rollup merge of #86889 - jyn514:crate-cleanup, r=camelid
GuillaumeGomez Jul 17, 2021
cf296c0
Rollup merge of #87092 - ricobbe:fix-raw-dylib-multiple-definitions, …
GuillaumeGomez Jul 17, 2021
ed4b003
Rollup merge of #87183 - RalfJung:option-doctest, r=jyn514
GuillaumeGomez Jul 17, 2021
543715d
Rollup merge of #87205 - matthiaskrgr:clippy_cln, r=oli-obk
GuillaumeGomez Jul 17, 2021
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
4 changes: 1 addition & 3 deletions compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
sess,
&codegen_results,
outputs,
);

Ok(())
)
}
}

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ impl CodegenBackend for LlvmCodegenBackend {

// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs);

Ok(())
link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs)
}
}

Expand Down
114 changes: 49 additions & 65 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::Handler;
use rustc_errors::{ErrorReported, Handler};
use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_hir::def_id::CrateNum;
use rustc_middle::middle::cstore::{DllCallingConvention, DllImport};
use rustc_middle::middle::cstore::DllImport;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
Expand Down Expand Up @@ -35,7 +35,6 @@ use object::{Architecture, BinaryFormat, Endianness, FileFlags, SectionFlags, Se
use tempfile::Builder as TempFileBuilder;

use std::ffi::OsString;
use std::iter::FromIterator;
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
use std::{ascii, char, env, fmt, fs, io, mem, str};
Expand All @@ -54,7 +53,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
sess: &'a Session,
codegen_results: &CodegenResults,
outputs: &OutputFilenames,
) {
) -> Result<(), ErrorReported> {
let _timer = sess.timer("link_binary");
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
for &crate_type in sess.crate_types().iter() {
Expand Down Expand Up @@ -95,11 +94,17 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
match crate_type {
CrateType::Rlib => {
let _timer = sess.timer("link_rlib");
link_rlib::<B>(sess, codegen_results, RlibFlavor::Normal, &out_filename, &path)
.build();
link_rlib::<B>(
sess,
codegen_results,
RlibFlavor::Normal,
&out_filename,
&path,
)?
.build();
}
CrateType::Staticlib => {
link_staticlib::<B>(sess, codegen_results, &out_filename, &path);
link_staticlib::<B>(sess, codegen_results, &out_filename, &path)?;
}
_ => {
link_natively::<B>(
Expand Down Expand Up @@ -145,6 +150,8 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
}
}
});

Ok(())
}

pub fn each_linked_rlib(
Expand Down Expand Up @@ -220,7 +227,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
flavor: RlibFlavor,
out_filename: &Path,
tmpdir: &MaybeTempDir,
) -> B {
) -> Result<B, ErrorReported> {
info!("preparing rlib to {:?}", out_filename);
let mut ab = <B as ArchiveBuilder>::new(sess, out_filename, None);

Expand Down Expand Up @@ -259,7 +266,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
}

for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
{
ab.inject_dll_import_lib(&raw_dylib_name, &raw_dylib_imports, tmpdir);
}
Expand Down Expand Up @@ -312,7 +319,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
}
}
}
return ab;
return Ok(ab);

// For rlibs we "pack" rustc metadata into a dummy object file. When rustc
// creates a dylib crate type it will pass `--whole-archive` (or the
Expand Down Expand Up @@ -454,65 +461,40 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
fn collate_raw_dylibs(
sess: &Session,
used_libraries: &[NativeLib],
) -> Vec<(String, Vec<DllImport>)> {
let mut dylib_table: FxHashMap<String, FxHashSet<DllImport>> = FxHashMap::default();
) -> Result<Vec<(String, Vec<DllImport>)>, ErrorReported> {
// Use index maps to preserve original order of imports and libraries.
let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();

for lib in used_libraries {
if lib.kind == NativeLibKind::RawDylib {
let name = lib.name.unwrap_or_else(||
bug!("`link` attribute with kind = \"raw-dylib\" and no name should have caused error earlier")
);
let name = if matches!(lib.verbatim, Some(true)) {
name.to_string()
} else {
format!("{}.dll", name)
};
dylib_table.entry(name).or_default().extend(lib.dll_imports.iter().cloned());
}
}

// Rustc already signals an error if we have two imports with the same name but different
// calling conventions (or function signatures), so we don't have pay attention to those
// when ordering.
// FIXME: when we add support for ordinals, figure out if we need to do anything if we
// have two DllImport values with the same name but different ordinals.
let mut result: Vec<(String, Vec<DllImport>)> = dylib_table
.into_iter()
.map(|(lib_name, import_table)| {
let mut imports = Vec::from_iter(import_table.into_iter());
imports.sort_unstable_by_key(|x: &DllImport| x.name.as_str());
(lib_name, imports)
})
.collect::<Vec<_>>();
result.sort_unstable_by(|a: &(String, Vec<DllImport>), b: &(String, Vec<DllImport>)| {
a.0.cmp(&b.0)
});
let result = result;

// Check for multiple imports with the same name but different calling conventions or
// (when relevant) argument list sizes. Rustc only signals an error for this if the
// declarations are at the same scope level; if one shadows the other, we only get a lint
// warning.
for (library, imports) in &result {
let mut import_table: FxHashMap<Symbol, DllCallingConvention> = FxHashMap::default();
for import in imports {
if let Some(old_convention) =
import_table.insert(import.name, import.calling_convention)
{
if import.calling_convention != old_convention {
sess.span_fatal(
import.span,
&format!(
"multiple definitions of external function `{}` from library `{}` have different calling conventions",
import.name,
library,
));
let ext = if matches!(lib.verbatim, Some(true)) { "" } else { ".dll" };
let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext);
let imports = dylib_table.entry(name.clone()).or_default();
for import in &lib.dll_imports {
if let Some(old_import) = imports.insert(import.name, import) {
// FIXME: when we add support for ordinals, figure out if we need to do anything
// if we have two DllImport values with the same name but different ordinals.
if import.calling_convention != old_import.calling_convention {
sess.span_err(
import.span,
&format!(
"multiple declarations of external function `{}` from \
library `{}` have different calling conventions",
import.name, name,
),
);
}
}
}
}
}

result
sess.compile_status()?;
Ok(dylib_table
.into_iter()
.map(|(name, imports)| {
(name, imports.into_iter().map(|(_, import)| import.clone()).collect())
})
.collect())
}

/// Create a static archive.
Expand All @@ -531,9 +513,9 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
codegen_results: &CodegenResults,
out_filename: &Path,
tempdir: &MaybeTempDir,
) {
) -> Result<(), ErrorReported> {
let mut ab =
link_rlib::<B>(sess, codegen_results, RlibFlavor::StaticlibBase, out_filename, tempdir);
link_rlib::<B>(sess, codegen_results, RlibFlavor::StaticlibBase, out_filename, tempdir)?;
let mut all_native_libs = vec![];

let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| {
Expand Down Expand Up @@ -581,6 +563,8 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
print_native_static_libs(sess, &all_native_libs);
}
}

Ok(())
}

fn escape_stdout_stderr_string(s: &[u8]) -> String {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ impl EncodeContext<'a, 'tcx> {
fn encode_native_libraries(&mut self) -> Lazy<[NativeLib]> {
empty_proc_macro!(self);
let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
self.lazy(used_libraries.iter().cloned())
self.lazy(used_libraries.iter())
}

fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub enum LinkagePreference {
RequireStatic,
}

#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
#[derive(Debug, Encodable, Decodable, HashStable)]
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
Expand All @@ -75,7 +75,7 @@ pub struct NativeLib {
pub dll_imports: Vec<DllImport>,
}

#[derive(Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable)]
#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
pub struct DllImport {
pub name: Symbol,
pub ordinal: Option<u16>,
Expand All @@ -92,7 +92,7 @@ pub struct DllImport {
///
/// The usize value, where present, indicates the size of the function's argument list
/// in bytes.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable)]
#[derive(Clone, PartialEq, Debug, Encodable, Decodable, HashStable)]
pub enum DllCallingConvention {
C,
Stdcall(usize),
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/ty/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,10 @@ pub struct CaptureInfo<'tcx> {
}

pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
let name = match place.base {
let mut curr_string: String = match place.base {
HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(),
_ => bug!("Capture_information should only contain upvars"),
};
let mut curr_string = name;

for (i, proj) in place.projections.iter().enumerate() {
match proj.kind {
Expand Down Expand Up @@ -314,7 +313,7 @@ pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) ->
}
}

curr_string.to_string()
curr_string
}

#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, TypeFoldable, Copy, HashStable)]
Expand Down
66 changes: 66 additions & 0 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ crate fn compare_impl_method<'tcx>(
{
return;
}

if let Err(ErrorReported) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) {
return;
}
}

fn compare_predicate_entailment<'tcx>(
Expand Down Expand Up @@ -929,6 +933,68 @@ fn compare_synthetic_generics<'tcx>(
if error_found { Err(ErrorReported) } else { Ok(()) }
}

fn compare_const_param_types<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
trait_item_span: Option<Span>,
) -> Result<(), ErrorReported> {
let const_params_of = |def_id| {
tcx.generics_of(def_id).params.iter().filter_map(|param| match param.kind {
GenericParamDefKind::Const { .. } => Some(param.def_id),
_ => None,
})
};
let const_params_impl = const_params_of(impl_m.def_id);
let const_params_trait = const_params_of(trait_m.def_id);

for (const_param_impl, const_param_trait) in iter::zip(const_params_impl, const_params_trait) {
let impl_ty = tcx.type_of(const_param_impl);
let trait_ty = tcx.type_of(const_param_trait);
if impl_ty != trait_ty {
let (impl_span, impl_ident) = match tcx.hir().get_if_local(const_param_impl) {
Some(hir::Node::GenericParam(hir::GenericParam { span, name, .. })) => (
span,
match name {
hir::ParamName::Plain(ident) => Some(ident),
_ => None,
},
),
other => bug!(
"expected GenericParam, found {:?}",
other.map_or_else(|| "nothing".to_string(), |n| format!("{:?}", n))
),
};
let trait_span = match tcx.hir().get_if_local(const_param_trait) {
Some(hir::Node::GenericParam(hir::GenericParam { span, .. })) => Some(span),
_ => None,
};
let mut err = struct_span_err!(
tcx.sess,
*impl_span,
E0053,
"method `{}` has an incompatible const parameter type for trait",
trait_m.ident
);
err.span_note(
trait_span.map_or_else(|| trait_item_span.unwrap_or(*impl_span), |span| *span),
&format!(
"the const parameter{} has type `{}`, but the declaration \
in trait `{}` has type `{}`",
&impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{}`", ident)),
impl_ty,
tcx.def_path_str(trait_m.def_id),
trait_ty
),
);
err.emit();
return Err(ErrorReported);
}
}

Ok(())
}

crate fn compare_const_impl<'tcx>(
tcx: TyCtxt<'tcx>,
impl_c: &ty::AssocItem,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
//! // must have the same concrete type.
//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
//! // Explicit returns to illustrate return types not matching
//! match x {
//! match do_insert {
//! true => return (0..4).chain(once(42)).chain(4..8),
//! false => return (0..4).chain(empty()).chain(4..8),
//! }
Expand Down
7 changes: 7 additions & 0 deletions src/doc/rustdoc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,10 @@ This flag is **deprecated** and **has no effect**.
Rustdoc only supports Rust source code and Markdown input formats. If the
file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
Otherwise, it assumes that the input file is Rust.

## `--nocapture`

When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be
captured by rustdoc. Instead, the output will be directed to your terminal,
as if you had run the test executable manually. This is especially useful
for debugging your tests!
Loading