diff options
| author | bors <bors@rust-lang.org> | 2021-07-18 08:15:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-18 08:15:17 +0000 |
| commit | 5a8a44196b3cf099f8c9b0156bd902eaec0b4e5f (patch) | |
| tree | 44c6de9143298d107532d67ee58eff441f6ded1d /compiler | |
| parent | 3ab6b60337edeb49339d173853fee1f8569421e0 (diff) | |
| parent | 810e47897aae7d19c7f0a58dc8ede07a4caae2a0 (diff) | |
| download | rust-5a8a44196b3cf099f8c9b0156bd902eaec0b4e5f.tar.gz rust-5a8a44196b3cf099f8c9b0156bd902eaec0b4e5f.zip | |
Auto merge of #87242 - JohnTitor:rollup-t9rmwpo, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #86763 (Add a regression test for issue-63355) - #86814 (Recover from a misplaced inner doc comment) - #86843 (Check that const parameters of trait methods have compatible types) - #86889 (rustdoc: Cleanup ExternalCrate) - #87092 (Remove nondeterminism in multiple-definitions test) - #87170 (Add diagnostic items for Clippy) - #87183 (fix typo in compile_fail doctest) - #87205 (rustc_middle: remove redundant clone) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/lib.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 114 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/cstore.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/closure.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/attr.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/compare_method.rs | 66 |
9 files changed, 153 insertions, 79 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index cb1cb3c74db..e32dae49131 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -221,9 +221,7 @@ impl CodegenBackend for CraneliftCodegenBackend { sess, &codegen_results, outputs, - ); - - Ok(()) + ) } } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 26fd1cfbcd0..aa4db1622b2 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -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) } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f9efa448c93..773a1c500b2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -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}; @@ -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}; @@ -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() { @@ -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>( @@ -145,6 +150,8 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( } } }); + + Ok(()) } pub fn each_linked_rlib( @@ -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); @@ -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); } @@ -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 @@ -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. @@ -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| { @@ -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 { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6877d6ef542..a4913a32e81 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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]> { diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs index 4c35b49bcef..8150e679295 100644 --- a/compiler/rustc_middle/src/middle/cstore.rs +++ b/compiler/rustc_middle/src/middle/cstore.rs @@ -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>, @@ -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>, @@ -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), diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index b0156daf17e..6b51adc6aaf 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -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 { @@ -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)] diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 8b050389078..e9f0038b2d6 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -64,7 +64,14 @@ impl<'a> Parser<'a> { } self.bump(); just_parsed_doc_comment = true; - Some(attr::mk_doc_comment(comment_kind, attr_style, data, self.prev_token.span)) + // Always make an outer attribute - this allows us to recover from a misplaced + // inner attribute. + Some(attr::mk_doc_comment( + comment_kind, + ast::AttrStyle::Outer, + data, + self.prev_token.span, + )) } else { None }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 07f22159f96..a8f969782b2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -122,10 +122,14 @@ symbols! { // nice to have. Symbols { Alignment, + Any, Arc, Argument, ArgumentV1, Arguments, + AsMut, + AsRef, + BTreeEntry, BTreeMap, BTreeSet, BinaryHeap, @@ -139,6 +143,7 @@ symbols! { Continue, Copy, Count, + Cow, Debug, DebugStruct, DebugTuple, @@ -146,12 +151,17 @@ symbols! { Decoder, Default, Deref, + DirBuilder, + DoubleEndedIterator, + Duration, Encodable, Encoder, Eq, Equal, Err, Error, + File, + FileType, FormatSpec, Formatter, From, @@ -162,11 +172,14 @@ symbols! { GlobalAlloc, Hash, HashMap, + HashMapEntry, HashSet, Hasher, Implied, Input, IntoIterator, + IoRead, + IoWrite, Is, ItemContext, Iterator, @@ -369,6 +382,8 @@ symbols! { closure, closure_to_fn_coercion, cmp, + cmp_max, + cmp_min, cmpxchg16b_target_feature, cmse_nonsecure_entry, coerce_unsized, @@ -674,6 +689,7 @@ symbols! { item, item_like_imports, iter, + iter_repeat, keyword, kind, kreg, @@ -740,6 +756,12 @@ symbols! { maybe_uninit, maybe_uninit_uninit, maybe_uninit_zeroed, + mem_discriminant, + mem_drop, + mem_forget, + mem_replace, + mem_size_of, + mem_size_of_val, mem_uninitialized, mem_zeroed, member_constraints, diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 12d0c14a3d5..d3586888155 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -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>( @@ -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, |
