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
This commit is contained in:
commit
5a8a44196b
@ -221,9 +221,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
|
|||||||
sess,
|
sess,
|
||||||
&codegen_results,
|
&codegen_results,
|
||||||
outputs,
|
outputs,
|
||||||
);
|
)
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,9 +292,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
|||||||
|
|
||||||
// Run the linker on any artifacts that resulted from the LLVM run.
|
// Run the linker on any artifacts that resulted from the LLVM run.
|
||||||
// This should produce either a finished executable or library.
|
// This should produce either a finished executable or library.
|
||||||
link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs);
|
link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs)
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_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_fs_util::fix_windows_verbatim_for_gcc;
|
||||||
use rustc_hir::def_id::CrateNum;
|
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_middle::middle::dependency_format::Linkage;
|
||||||
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
|
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
|
||||||
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
|
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 tempfile::Builder as TempFileBuilder;
|
||||||
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::iter::FromIterator;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{ExitStatus, Output, Stdio};
|
use std::process::{ExitStatus, Output, Stdio};
|
||||||
use std::{ascii, char, env, fmt, fs, io, mem, str};
|
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,
|
sess: &'a Session,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
) {
|
) -> Result<(), ErrorReported> {
|
||||||
let _timer = sess.timer("link_binary");
|
let _timer = sess.timer("link_binary");
|
||||||
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
|
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
|
||||||
for &crate_type in sess.crate_types().iter() {
|
for &crate_type in sess.crate_types().iter() {
|
||||||
@ -95,11 +94,17 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
|||||||
match crate_type {
|
match crate_type {
|
||||||
CrateType::Rlib => {
|
CrateType::Rlib => {
|
||||||
let _timer = sess.timer("link_rlib");
|
let _timer = sess.timer("link_rlib");
|
||||||
link_rlib::<B>(sess, codegen_results, RlibFlavor::Normal, &out_filename, &path)
|
link_rlib::<B>(
|
||||||
.build();
|
sess,
|
||||||
|
codegen_results,
|
||||||
|
RlibFlavor::Normal,
|
||||||
|
&out_filename,
|
||||||
|
&path,
|
||||||
|
)?
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
CrateType::Staticlib => {
|
CrateType::Staticlib => {
|
||||||
link_staticlib::<B>(sess, codegen_results, &out_filename, &path);
|
link_staticlib::<B>(sess, codegen_results, &out_filename, &path)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
link_natively::<B>(
|
link_natively::<B>(
|
||||||
@ -145,6 +150,8 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn each_linked_rlib(
|
pub fn each_linked_rlib(
|
||||||
@ -220,7 +227,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
|
|||||||
flavor: RlibFlavor,
|
flavor: RlibFlavor,
|
||||||
out_filename: &Path,
|
out_filename: &Path,
|
||||||
tmpdir: &MaybeTempDir,
|
tmpdir: &MaybeTempDir,
|
||||||
) -> B {
|
) -> Result<B, ErrorReported> {
|
||||||
info!("preparing rlib to {:?}", out_filename);
|
info!("preparing rlib to {:?}", out_filename);
|
||||||
let mut ab = <B as ArchiveBuilder>::new(sess, out_filename, None);
|
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
|
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);
|
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
|
// 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
|
// 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(
|
fn collate_raw_dylibs(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
used_libraries: &[NativeLib],
|
used_libraries: &[NativeLib],
|
||||||
) -> Vec<(String, Vec<DllImport>)> {
|
) -> Result<Vec<(String, Vec<DllImport>)>, ErrorReported> {
|
||||||
let mut dylib_table: FxHashMap<String, FxHashSet<DllImport>> = FxHashMap::default();
|
// 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 {
|
for lib in used_libraries {
|
||||||
if lib.kind == NativeLibKind::RawDylib {
|
if lib.kind == NativeLibKind::RawDylib {
|
||||||
let name = lib.name.unwrap_or_else(||
|
let ext = if matches!(lib.verbatim, Some(true)) { "" } else { ".dll" };
|
||||||
bug!("`link` attribute with kind = \"raw-dylib\" and no name should have caused error earlier")
|
let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext);
|
||||||
);
|
let imports = dylib_table.entry(name.clone()).or_default();
|
||||||
let name = if matches!(lib.verbatim, Some(true)) {
|
for import in &lib.dll_imports {
|
||||||
name.to_string()
|
if let Some(old_import) = imports.insert(import.name, import) {
|
||||||
} else {
|
// FIXME: when we add support for ordinals, figure out if we need to do anything
|
||||||
format!("{}.dll", name)
|
// if we have two DllImport values with the same name but different ordinals.
|
||||||
};
|
if import.calling_convention != old_import.calling_convention {
|
||||||
dylib_table.entry(name).or_default().extend(lib.dll_imports.iter().cloned());
|
sess.span_err(
|
||||||
}
|
import.span,
|
||||||
}
|
&format!(
|
||||||
|
"multiple declarations of external function `{}` from \
|
||||||
// Rustc already signals an error if we have two imports with the same name but different
|
library `{}` have different calling conventions",
|
||||||
// calling conventions (or function signatures), so we don't have pay attention to those
|
import.name, name,
|
||||||
// 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,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sess.compile_status()?;
|
||||||
result
|
Ok(dylib_table
|
||||||
|
.into_iter()
|
||||||
|
.map(|(name, imports)| {
|
||||||
|
(name, imports.into_iter().map(|(_, import)| import.clone()).collect())
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a static archive.
|
/// Create a static archive.
|
||||||
@ -531,9 +513,9 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
|
|||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
out_filename: &Path,
|
out_filename: &Path,
|
||||||
tempdir: &MaybeTempDir,
|
tempdir: &MaybeTempDir,
|
||||||
) {
|
) -> Result<(), ErrorReported> {
|
||||||
let mut ab =
|
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 mut all_native_libs = vec![];
|
||||||
|
|
||||||
let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| {
|
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);
|
print_native_static_libs(sess, &all_native_libs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn escape_stdout_stderr_string(s: &[u8]) -> String {
|
fn escape_stdout_stderr_string(s: &[u8]) -> String {
|
||||||
|
@ -1581,7 +1581,7 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
fn encode_native_libraries(&mut self) -> Lazy<[NativeLib]> {
|
fn encode_native_libraries(&mut self) -> Lazy<[NativeLib]> {
|
||||||
empty_proc_macro!(self);
|
empty_proc_macro!(self);
|
||||||
let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
|
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]> {
|
fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> {
|
||||||
|
@ -64,7 +64,7 @@ pub enum LinkagePreference {
|
|||||||
RequireStatic,
|
RequireStatic,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
|
#[derive(Debug, Encodable, Decodable, HashStable)]
|
||||||
pub struct NativeLib {
|
pub struct NativeLib {
|
||||||
pub kind: NativeLibKind,
|
pub kind: NativeLibKind,
|
||||||
pub name: Option<Symbol>,
|
pub name: Option<Symbol>,
|
||||||
@ -75,7 +75,7 @@ pub struct NativeLib {
|
|||||||
pub dll_imports: Vec<DllImport>,
|
pub dll_imports: Vec<DllImport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable)]
|
#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
|
||||||
pub struct DllImport {
|
pub struct DllImport {
|
||||||
pub name: Symbol,
|
pub name: Symbol,
|
||||||
pub ordinal: Option<u16>,
|
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
|
/// The usize value, where present, indicates the size of the function's argument list
|
||||||
/// in bytes.
|
/// in bytes.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Encodable, Decodable, Hash, HashStable)]
|
#[derive(Clone, PartialEq, Debug, Encodable, Decodable, HashStable)]
|
||||||
pub enum DllCallingConvention {
|
pub enum DllCallingConvention {
|
||||||
C,
|
C,
|
||||||
Stdcall(usize),
|
Stdcall(usize),
|
||||||
|
@ -281,11 +281,10 @@ pub struct CaptureInfo<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
|
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(),
|
HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(),
|
||||||
_ => bug!("Capture_information should only contain upvars"),
|
_ => bug!("Capture_information should only contain upvars"),
|
||||||
};
|
};
|
||||||
let mut curr_string = name;
|
|
||||||
|
|
||||||
for (i, proj) in place.projections.iter().enumerate() {
|
for (i, proj) in place.projections.iter().enumerate() {
|
||||||
match proj.kind {
|
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)]
|
#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, TypeFoldable, Copy, HashStable)]
|
||||||
|
@ -64,7 +64,14 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
self.bump();
|
self.bump();
|
||||||
just_parsed_doc_comment = true;
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -122,10 +122,14 @@ symbols! {
|
|||||||
// nice to have.
|
// nice to have.
|
||||||
Symbols {
|
Symbols {
|
||||||
Alignment,
|
Alignment,
|
||||||
|
Any,
|
||||||
Arc,
|
Arc,
|
||||||
Argument,
|
Argument,
|
||||||
ArgumentV1,
|
ArgumentV1,
|
||||||
Arguments,
|
Arguments,
|
||||||
|
AsMut,
|
||||||
|
AsRef,
|
||||||
|
BTreeEntry,
|
||||||
BTreeMap,
|
BTreeMap,
|
||||||
BTreeSet,
|
BTreeSet,
|
||||||
BinaryHeap,
|
BinaryHeap,
|
||||||
@ -139,6 +143,7 @@ symbols! {
|
|||||||
Continue,
|
Continue,
|
||||||
Copy,
|
Copy,
|
||||||
Count,
|
Count,
|
||||||
|
Cow,
|
||||||
Debug,
|
Debug,
|
||||||
DebugStruct,
|
DebugStruct,
|
||||||
DebugTuple,
|
DebugTuple,
|
||||||
@ -146,12 +151,17 @@ symbols! {
|
|||||||
Decoder,
|
Decoder,
|
||||||
Default,
|
Default,
|
||||||
Deref,
|
Deref,
|
||||||
|
DirBuilder,
|
||||||
|
DoubleEndedIterator,
|
||||||
|
Duration,
|
||||||
Encodable,
|
Encodable,
|
||||||
Encoder,
|
Encoder,
|
||||||
Eq,
|
Eq,
|
||||||
Equal,
|
Equal,
|
||||||
Err,
|
Err,
|
||||||
Error,
|
Error,
|
||||||
|
File,
|
||||||
|
FileType,
|
||||||
FormatSpec,
|
FormatSpec,
|
||||||
Formatter,
|
Formatter,
|
||||||
From,
|
From,
|
||||||
@ -162,11 +172,14 @@ symbols! {
|
|||||||
GlobalAlloc,
|
GlobalAlloc,
|
||||||
Hash,
|
Hash,
|
||||||
HashMap,
|
HashMap,
|
||||||
|
HashMapEntry,
|
||||||
HashSet,
|
HashSet,
|
||||||
Hasher,
|
Hasher,
|
||||||
Implied,
|
Implied,
|
||||||
Input,
|
Input,
|
||||||
IntoIterator,
|
IntoIterator,
|
||||||
|
IoRead,
|
||||||
|
IoWrite,
|
||||||
Is,
|
Is,
|
||||||
ItemContext,
|
ItemContext,
|
||||||
Iterator,
|
Iterator,
|
||||||
@ -369,6 +382,8 @@ symbols! {
|
|||||||
closure,
|
closure,
|
||||||
closure_to_fn_coercion,
|
closure_to_fn_coercion,
|
||||||
cmp,
|
cmp,
|
||||||
|
cmp_max,
|
||||||
|
cmp_min,
|
||||||
cmpxchg16b_target_feature,
|
cmpxchg16b_target_feature,
|
||||||
cmse_nonsecure_entry,
|
cmse_nonsecure_entry,
|
||||||
coerce_unsized,
|
coerce_unsized,
|
||||||
@ -674,6 +689,7 @@ symbols! {
|
|||||||
item,
|
item,
|
||||||
item_like_imports,
|
item_like_imports,
|
||||||
iter,
|
iter,
|
||||||
|
iter_repeat,
|
||||||
keyword,
|
keyword,
|
||||||
kind,
|
kind,
|
||||||
kreg,
|
kreg,
|
||||||
@ -740,6 +756,12 @@ symbols! {
|
|||||||
maybe_uninit,
|
maybe_uninit,
|
||||||
maybe_uninit_uninit,
|
maybe_uninit_uninit,
|
||||||
maybe_uninit_zeroed,
|
maybe_uninit_zeroed,
|
||||||
|
mem_discriminant,
|
||||||
|
mem_drop,
|
||||||
|
mem_forget,
|
||||||
|
mem_replace,
|
||||||
|
mem_size_of,
|
||||||
|
mem_size_of_val,
|
||||||
mem_uninitialized,
|
mem_uninitialized,
|
||||||
mem_zeroed,
|
mem_zeroed,
|
||||||
member_constraints,
|
member_constraints,
|
||||||
|
@ -66,6 +66,10 @@ crate fn compare_impl_method<'tcx>(
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Err(ErrorReported) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare_predicate_entailment<'tcx>(
|
fn compare_predicate_entailment<'tcx>(
|
||||||
@ -929,6 +933,68 @@ fn compare_synthetic_generics<'tcx>(
|
|||||||
if error_found { Err(ErrorReported) } else { Ok(()) }
|
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>(
|
crate fn compare_const_impl<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_c: &ty::AssocItem,
|
impl_c: &ty::AssocItem,
|
||||||
|
@ -177,6 +177,7 @@ where
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Cow")]
|
||||||
pub enum Cow<'a, B: ?Sized + 'a>
|
pub enum Cow<'a, B: ?Sized + 'a>
|
||||||
where
|
where
|
||||||
B: ToOwned,
|
B: ToOwned,
|
||||||
|
@ -14,6 +14,7 @@ use Entry::*;
|
|||||||
///
|
///
|
||||||
/// [`entry`]: BTreeMap::entry
|
/// [`entry`]: BTreeMap::entry
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
|
||||||
pub enum Entry<'a, K: 'a, V: 'a> {
|
pub enum Entry<'a, K: 'a, V: 'a> {
|
||||||
/// A vacant entry.
|
/// A vacant entry.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -108,6 +108,7 @@ use crate::intrinsics;
|
|||||||
// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
|
// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
|
||||||
// but we would likely want to indicate as such in documentation).
|
// but we would likely want to indicate as such in documentation).
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Any")]
|
||||||
pub trait Any: 'static {
|
pub trait Any: 'static {
|
||||||
/// Gets the `TypeId` of `self`.
|
/// Gets the `TypeId` of `self`.
|
||||||
///
|
///
|
||||||
|
@ -1104,6 +1104,7 @@ pub macro PartialOrd($item:item) {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
|
||||||
pub fn min<T: Ord>(v1: T, v2: T) -> T {
|
pub fn min<T: Ord>(v1: T, v2: T) -> T {
|
||||||
v1.min(v2)
|
v1.min(v2)
|
||||||
}
|
}
|
||||||
@ -1166,6 +1167,7 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
|
||||||
pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
||||||
v1.max(v2)
|
v1.max(v2)
|
||||||
}
|
}
|
||||||
|
@ -152,6 +152,7 @@ pub const fn identity<T>(x: T) -> T {
|
|||||||
/// is_hello(s);
|
/// is_hello(s);
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")]
|
||||||
pub trait AsRef<T: ?Sized> {
|
pub trait AsRef<T: ?Sized> {
|
||||||
/// Performs the conversion.
|
/// Performs the conversion.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -193,6 +194,7 @@ pub trait AsRef<T: ?Sized> {
|
|||||||
///
|
///
|
||||||
/// [`Box<T>`]: ../../std/boxed/struct.Box.html
|
/// [`Box<T>`]: ../../std/boxed/struct.Box.html
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
|
||||||
pub trait AsMut<T: ?Sized> {
|
pub trait AsMut<T: ?Sized> {
|
||||||
/// Performs the conversion.
|
/// Performs the conversion.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -51,6 +51,7 @@ use crate::iter::{FusedIterator, TrustedLen};
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "iter_repeat")]
|
||||||
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
|
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
|
||||||
Repeat { element: elt }
|
Repeat { element: elt }
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ use crate::ops::{ControlFlow, Try};
|
|||||||
/// assert_eq!(None, iter.next_back());
|
/// assert_eq!(None, iter.next_back());
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")]
|
||||||
pub trait DoubleEndedIterator: Iterator {
|
pub trait DoubleEndedIterator: Iterator {
|
||||||
/// Removes and returns an element from the end of the iterator.
|
/// Removes and returns an element from the end of the iterator.
|
||||||
///
|
///
|
||||||
|
@ -140,6 +140,7 @@ pub use crate::intrinsics::transmute;
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
|
#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_forget")]
|
||||||
pub const fn forget<T>(t: T) {
|
pub const fn forget<T>(t: T) {
|
||||||
let _ = ManuallyDrop::new(t);
|
let _ = ManuallyDrop::new(t);
|
||||||
}
|
}
|
||||||
@ -298,6 +299,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_promotable]
|
#[rustc_promotable]
|
||||||
#[rustc_const_stable(feature = "const_size_of", since = "1.24.0")]
|
#[rustc_const_stable(feature = "const_size_of", since = "1.24.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")]
|
||||||
pub const fn size_of<T>() -> usize {
|
pub const fn size_of<T>() -> usize {
|
||||||
intrinsics::size_of::<T>()
|
intrinsics::size_of::<T>()
|
||||||
}
|
}
|
||||||
@ -324,6 +326,7 @@ pub const fn size_of<T>() -> usize {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
|
#[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")]
|
||||||
pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
|
||||||
// SAFETY: `val` is a reference, so it's a valid raw pointer
|
// SAFETY: `val` is a reference, so it's a valid raw pointer
|
||||||
unsafe { intrinsics::size_of_val(val) }
|
unsafe { intrinsics::size_of_val(val) }
|
||||||
@ -814,6 +817,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")]
|
||||||
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
||||||
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
||||||
// such that the old value is not duplicated. Nothing is dropped and
|
// such that the old value is not duplicated. Nothing is dropped and
|
||||||
@ -888,6 +892,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
|||||||
/// [`RefCell`]: crate::cell::RefCell
|
/// [`RefCell`]: crate::cell::RefCell
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_drop")]
|
||||||
pub fn drop<T>(_x: T) {}
|
pub fn drop<T>(_x: T) {}
|
||||||
|
|
||||||
/// Interprets `src` as having type `&U`, and then reads `src` without moving
|
/// Interprets `src` as having type `&U`, and then reads `src` without moving
|
||||||
@ -1015,6 +1020,7 @@ impl<T> fmt::Debug for Discriminant<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "discriminant_value", since = "1.21.0")]
|
#[stable(feature = "discriminant_value", since = "1.21.0")]
|
||||||
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
|
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")]
|
||||||
pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
|
pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
|
||||||
Discriminant(intrinsics::discriminant_value(v))
|
Discriminant(intrinsics::discriminant_value(v))
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@
|
|||||||
//! // must have the same concrete type.
|
//! // must have the same concrete type.
|
||||||
//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
|
//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
|
||||||
//! // Explicit returns to illustrate return types not matching
|
//! // Explicit returns to illustrate return types not matching
|
||||||
//! match x {
|
//! match do_insert {
|
||||||
//! true => return (0..4).chain(once(42)).chain(4..8),
|
//! true => return (0..4).chain(once(42)).chain(4..8),
|
||||||
//! false => return (0..4).chain(empty()).chain(4..8),
|
//! false => return (0..4).chain(empty()).chain(4..8),
|
||||||
//! }
|
//! }
|
||||||
|
@ -61,6 +61,7 @@ const MICROS_PER_SEC: u64 = 1_000_000;
|
|||||||
/// crate to do so.
|
/// crate to do so.
|
||||||
#[stable(feature = "duration", since = "1.3.0")]
|
#[stable(feature = "duration", since = "1.3.0")]
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Duration")]
|
||||||
pub struct Duration {
|
pub struct Duration {
|
||||||
secs: u64,
|
secs: u64,
|
||||||
nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
|
nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
|
||||||
|
@ -1829,6 +1829,7 @@ impl<K, V, S> Debug for RawEntryBuilder<'_, K, V, S> {
|
|||||||
///
|
///
|
||||||
/// [`entry`]: HashMap::entry
|
/// [`entry`]: HashMap::entry
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "HashMapEntry")]
|
||||||
pub enum Entry<'a, K: 'a, V: 'a> {
|
pub enum Entry<'a, K: 'a, V: 'a> {
|
||||||
/// An occupied entry.
|
/// An occupied entry.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -88,6 +88,7 @@ use crate::time::SystemTime;
|
|||||||
/// [`BufReader<R>`]: io::BufReader
|
/// [`BufReader<R>`]: io::BufReader
|
||||||
/// [`sync_all`]: File::sync_all
|
/// [`sync_all`]: File::sync_all
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "File")]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
inner: fs_imp::File,
|
inner: fs_imp::File,
|
||||||
}
|
}
|
||||||
@ -183,12 +184,14 @@ pub struct Permissions(fs_imp::FilePermissions);
|
|||||||
/// It is returned by [`Metadata::file_type`] method.
|
/// It is returned by [`Metadata::file_type`] method.
|
||||||
#[stable(feature = "file_type", since = "1.1.0")]
|
#[stable(feature = "file_type", since = "1.1.0")]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]
|
||||||
pub struct FileType(fs_imp::FileType);
|
pub struct FileType(fs_imp::FileType);
|
||||||
|
|
||||||
/// A builder used to create directories in various manners.
|
/// A builder used to create directories in various manners.
|
||||||
///
|
///
|
||||||
/// This builder also supports platform-specific options.
|
/// This builder also supports platform-specific options.
|
||||||
#[stable(feature = "dir_builder", since = "1.6.0")]
|
#[stable(feature = "dir_builder", since = "1.6.0")]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DirBuilder {
|
pub struct DirBuilder {
|
||||||
inner: fs_imp::DirBuilder,
|
inner: fs_imp::DirBuilder,
|
||||||
|
@ -514,6 +514,7 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
|
|||||||
/// [`File`]: crate::fs::File
|
/// [`File`]: crate::fs::File
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(notable_trait)]
|
#[doc(notable_trait)]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "IoRead")]
|
||||||
pub trait Read {
|
pub trait Read {
|
||||||
/// Pull some bytes from this source into the specified buffer, returning
|
/// Pull some bytes from this source into the specified buffer, returning
|
||||||
/// how many bytes were read.
|
/// how many bytes were read.
|
||||||
@ -1361,6 +1362,7 @@ impl Initializer {
|
|||||||
/// [`write_all`]: Write::write_all
|
/// [`write_all`]: Write::write_all
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[doc(notable_trait)]
|
#[doc(notable_trait)]
|
||||||
|
#[cfg_attr(not(test), rustc_diagnostic_item = "IoWrite")]
|
||||||
pub trait Write {
|
pub trait Write {
|
||||||
/// Write a buffer into this writer, returning how many bytes were written.
|
/// Write a buffer into this writer, returning how many bytes were written.
|
||||||
///
|
///
|
||||||
|
@ -14,7 +14,7 @@ use rustc_attr as attr;
|
|||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||||
use rustc_middle::middle::resolve_lifetime as rl;
|
use rustc_middle::middle::resolve_lifetime as rl;
|
||||||
@ -85,12 +85,6 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clean<ExternalCrate> for CrateNum {
|
|
||||||
fn clean(&self, _cx: &mut DocContext<'_>) -> ExternalCrate {
|
|
||||||
ExternalCrate { crate_num: *self }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clean<Item> for doctree::Module<'_> {
|
impl Clean<Item> for doctree::Module<'_> {
|
||||||
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
|
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
|
||||||
let mut items: Vec<Item> = vec![];
|
let mut items: Vec<Item> = vec![];
|
||||||
|
@ -118,7 +118,7 @@ crate struct Crate {
|
|||||||
crate name: Symbol,
|
crate name: Symbol,
|
||||||
crate src: FileName,
|
crate src: FileName,
|
||||||
crate module: Item,
|
crate module: Item,
|
||||||
crate externs: Vec<(CrateNum, ExternalCrate)>,
|
crate externs: Vec<ExternalCrate>,
|
||||||
crate primitives: ThinVec<(DefId, PrimitiveType)>,
|
crate primitives: ThinVec<(DefId, PrimitiveType)>,
|
||||||
// These are later on moved into `CACHEKEY`, leaving the map empty.
|
// These are later on moved into `CACHEKEY`, leaving the map empty.
|
||||||
// Only here so that they can be filtered through the rustdoc passes.
|
// Only here so that they can be filtered through the rustdoc passes.
|
||||||
@ -133,14 +133,14 @@ crate struct TraitWithExtraInfo {
|
|||||||
crate is_notable: bool,
|
crate is_notable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
crate struct ExternalCrate {
|
crate struct ExternalCrate {
|
||||||
crate crate_num: CrateNum,
|
crate crate_num: CrateNum,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternalCrate {
|
impl ExternalCrate {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn def_id(&self) -> DefId {
|
crate fn def_id(&self) -> DefId {
|
||||||
DefId { krate: self.crate_num, index: CRATE_DEF_INDEX }
|
DefId { krate: self.crate_num, index: CRATE_DEF_INDEX }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::clean::auto_trait::AutoTraitFinder;
|
use crate::clean::auto_trait::AutoTraitFinder;
|
||||||
use crate::clean::blanket_impl::BlanketImplFinder;
|
use crate::clean::blanket_impl::BlanketImplFinder;
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
inline, Clean, Crate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime,
|
inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item,
|
||||||
Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
|
ItemKind, Lifetime, Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type,
|
||||||
Visibility,
|
TypeBinding, Visibility,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::formats::item_type::ItemType;
|
use crate::formats::item_type::ItemType;
|
||||||
@ -35,11 +35,11 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
|
|||||||
|
|
||||||
let mut externs = Vec::new();
|
let mut externs = Vec::new();
|
||||||
for &cnum in cx.tcx.crates(()).iter() {
|
for &cnum in cx.tcx.crates(()).iter() {
|
||||||
externs.push((cnum, cnum.clean(cx)));
|
externs.push(ExternalCrate { crate_num: cnum });
|
||||||
// Analyze doc-reachability for extern items
|
// Analyze doc-reachability for extern items
|
||||||
LibEmbargoVisitor::new(cx).visit_lib(cnum);
|
LibEmbargoVisitor::new(cx).visit_lib(cnum);
|
||||||
}
|
}
|
||||||
externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
externs.sort_unstable_by_key(|e| e.crate_num);
|
||||||
|
|
||||||
// Clean the crate, translating the entire librustc_ast AST to one that is
|
// Clean the crate, translating the entire librustc_ast AST to one that is
|
||||||
// understood by rustdoc.
|
// understood by rustdoc.
|
||||||
@ -61,7 +61,7 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_crate = LOCAL_CRATE.clean(cx);
|
let local_crate = ExternalCrate { crate_num: LOCAL_CRATE };
|
||||||
let src = local_crate.src(cx.tcx);
|
let src = local_crate.src(cx.tcx);
|
||||||
let name = local_crate.name(cx.tcx);
|
let name = local_crate.name(cx.tcx);
|
||||||
let primitives = local_crate.primitives(cx.tcx);
|
let primitives = local_crate.primitives(cx.tcx);
|
||||||
|
@ -151,19 +151,18 @@ impl Cache {
|
|||||||
|
|
||||||
// Cache where all our extern crates are located
|
// Cache where all our extern crates are located
|
||||||
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
|
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
|
||||||
for &(n, ref e) in &krate.externs {
|
for &e in &krate.externs {
|
||||||
let name = e.name(tcx);
|
let name = e.name(tcx);
|
||||||
let extern_url = extern_html_root_urls.get(&*name.as_str()).map(|u| &**u);
|
let extern_url = extern_html_root_urls.get(&*name.as_str()).map(|u| &**u);
|
||||||
let did = DefId { krate: n, index: CRATE_DEF_INDEX };
|
self.extern_locations.insert(e.crate_num, e.location(extern_url, &dst, tcx));
|
||||||
self.extern_locations.insert(n, e.location(extern_url, &dst, tcx));
|
self.external_paths.insert(e.def_id(), (vec![name.to_string()], ItemType::Module));
|
||||||
self.external_paths.insert(did, (vec![name.to_string()], ItemType::Module));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache where all known primitives have their documentation located.
|
// Cache where all known primitives have their documentation located.
|
||||||
//
|
//
|
||||||
// Favor linking to as local extern as possible, so iterate all crates in
|
// Favor linking to as local extern as possible, so iterate all crates in
|
||||||
// reverse topological order.
|
// reverse topological order.
|
||||||
for &(_, ref e) in krate.externs.iter().rev() {
|
for &e in krate.externs.iter().rev() {
|
||||||
for &(def_id, prim) in &e.primitives(tcx) {
|
for &(def_id, prim) in &e.primitives(tcx) {
|
||||||
self.primitive_locations.insert(prim, def_id);
|
self.primitive_locations.insert(prim, def_id);
|
||||||
}
|
}
|
||||||
|
25
src/test/ui/const-generics/issue-86820.rs
Normal file
25
src/test/ui/const-generics/issue-86820.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Regression test for the ICE described in #86820.
|
||||||
|
|
||||||
|
#![allow(unused,dead_code)]
|
||||||
|
use std::ops::BitAnd;
|
||||||
|
|
||||||
|
const C: fn() = || is_set();
|
||||||
|
fn is_set() {
|
||||||
|
0xffu8.bit::<0>();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bits {
|
||||||
|
fn bit<const I : u8>(self) -> bool;
|
||||||
|
//~^ NOTE: the const parameter `I` has type `usize`, but the declaration in trait `Bits::bit` has type `u8`
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bits for u8 {
|
||||||
|
fn bit<const I : usize>(self) -> bool {
|
||||||
|
//~^ ERROR: method `bit` has an incompatible const parameter type for trait [E0053]
|
||||||
|
let i = 1 << I;
|
||||||
|
let mask = u8::from(i);
|
||||||
|
mask & self == mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/ui/const-generics/issue-86820.stderr
Normal file
15
src/test/ui/const-generics/issue-86820.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0053]: method `bit` has an incompatible const parameter type for trait
|
||||||
|
--> $DIR/issue-86820.rs:17:18
|
||||||
|
|
|
||||||
|
LL | fn bit<const I : usize>(self) -> bool {
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: the const parameter `I` has type `usize`, but the declaration in trait `Bits::bit` has type `u8`
|
||||||
|
--> $DIR/issue-86820.rs:12:18
|
||||||
|
|
|
||||||
|
LL | fn bit<const I : u8>(self) -> bool;
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0053`.
|
11
src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs
Normal file
11
src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// aux-build:test-macros.rs
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate test_macros;
|
||||||
|
|
||||||
|
//! Inner doc comment
|
||||||
|
//~^ ERROR expected outer doc comment
|
||||||
|
#[derive(Empty)]
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
|
fn main() {}
|
11
src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr
Normal file
11
src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0753]: expected outer doc comment
|
||||||
|
--> $DIR/issue-86781-bad-inner-doc.rs:6:1
|
||||||
|
|
|
||||||
|
LL | //! Inner doc comment
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0753`.
|
19
src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs
Normal file
19
src/test/ui/rfc-2627-raw-dylib/multiple-declarations.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// only-i686-pc-windows-msvc
|
||||||
|
// compile-flags: --crate-type lib --emit link
|
||||||
|
#![allow(clashing_extern_declarations)]
|
||||||
|
#![feature(raw_dylib)]
|
||||||
|
//~^ WARN the feature `raw_dylib` is incomplete
|
||||||
|
#[link(name = "foo", kind = "raw-dylib")]
|
||||||
|
extern "C" {
|
||||||
|
fn f(x: i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lib_main() {
|
||||||
|
#[link(name = "foo", kind = "raw-dylib")]
|
||||||
|
extern "stdcall" {
|
||||||
|
fn f(x: i32);
|
||||||
|
//~^ ERROR multiple declarations of external function `f` from library `foo.dll` have different calling conventions
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { f(42); }
|
||||||
|
}
|
17
src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr
Normal file
17
src/test/ui/rfc-2627-raw-dylib/multiple-declarations.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/multiple-declarations.rs:4:12
|
||||||
|
|
|
||||||
|
LL | #![feature(raw_dylib)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
= note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
|
||||||
|
|
||||||
|
error: multiple declarations of external function `f` from library `foo.dll` have different calling conventions
|
||||||
|
--> $DIR/multiple-declarations.rs:14:9
|
||||||
|
|
|
||||||
|
LL | fn f(x: i32);
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
50
src/test/ui/type-alias-impl-trait/issue-63355.rs
Normal file
50
src/test/ui/type-alias-impl-trait/issue-63355.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#![feature(min_type_alias_impl_trait)]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
pub trait Foo {}
|
||||||
|
|
||||||
|
pub trait Bar {
|
||||||
|
type Foo: Foo;
|
||||||
|
|
||||||
|
fn foo() -> Self::Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Baz {
|
||||||
|
type Foo: Foo;
|
||||||
|
type Bar: Bar<Foo = Self::Foo>;
|
||||||
|
|
||||||
|
fn foo() -> Self::Foo;
|
||||||
|
fn bar() -> Self::Bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for () {}
|
||||||
|
|
||||||
|
impl Bar for () {
|
||||||
|
type Foo = FooImpl;
|
||||||
|
|
||||||
|
fn foo() -> Self::Foo {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(#86731): The below is illegal use of `min_type_alias_impl_trait`
|
||||||
|
// but the compiler doesn't report it, we should fix it.
|
||||||
|
pub type FooImpl = impl Foo;
|
||||||
|
pub type BarImpl = impl Bar<Foo = FooImpl>;
|
||||||
|
//~^ ERROR: type mismatch resolving `<() as Bar>::Foo == ()`
|
||||||
|
|
||||||
|
impl Baz for () {
|
||||||
|
type Foo = FooImpl;
|
||||||
|
type Bar = BarImpl;
|
||||||
|
|
||||||
|
fn foo() -> Self::Foo {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() -> Self::Bar {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
14
src/test/ui/type-alias-impl-trait/issue-63355.stderr
Normal file
14
src/test/ui/type-alias-impl-trait/issue-63355.stderr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
error[E0271]: type mismatch resolving `<() as Bar>::Foo == ()`
|
||||||
|
--> $DIR/issue-63355.rs:34:20
|
||||||
|
|
|
||||||
|
LL | pub type FooImpl = impl Foo;
|
||||||
|
| -------- the found opaque type
|
||||||
|
LL | pub type BarImpl = impl Bar<Foo = FooImpl>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
|
||||||
|
|
|
||||||
|
= note: expected unit type `()`
|
||||||
|
found opaque type `impl Foo`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0271`.
|
Loading…
x
Reference in New Issue
Block a user