"markup5ever_rcdom",
"matches",
"tendril",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
"toml",
"unicode-width",
"unicode-xid",
- "url 2.1.1",
+ "url 2.2.2",
"walkdir",
"winapi 0.3.9",
]
"serde_json",
"tar",
"toml",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
"serde_json",
"toml",
"unicode-normalization",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
"percent-encoding 2.1.0",
"serde",
"serde_json",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
[[package]]
name = "filetime"
-version = "0.2.12"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
+checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"libc",
- "redox_syscall 0.1.57",
+ "redox_syscall",
"winapi 0.3.9",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+[[package]]
+name = "form_urlencoded"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+dependencies = [
+ "matches",
+ "percent-encoding 2.1.0",
+]
+
[[package]]
name = "fortanix-sgx-abi"
version = "0.3.3"
"log",
"openssl-probe",
"openssl-sys",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
"curl",
"git2",
"log",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
"serde",
"serde_json",
"serde_repr",
- "url 2.1.1",
+ "url 2.2.2",
]
[[package]]
[[package]]
name = "measureme"
-version = "9.1.0"
+version = "9.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a98e07fe802486895addb2b5467f33f205e82c426bfaf350f5d8109b137767c"
+checksum = "49cf14eb7d2eea897d9949b68f19e165638755e3a1a3c0941b6b6c3e00141f2c"
dependencies = [
"log",
- "memmap",
+ "memmap2",
"parking_lot",
"perf-event-open-sys",
"rustc-hash",
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
-[[package]]
-name = "memmap"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
[[package]]
name = "memmap2"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897"
dependencies = [
- "socket2 0.3.16",
+ "socket2 0.3.19",
"winapi 0.3.9",
]
"cfg-if 1.0.0",
"instant",
"libc",
- "redox_syscall 0.2.5",
+ "redox_syscall",
"smallvec",
"winapi 0.3.9",
]
"num_cpus",
]
-[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
[[package]]
name = "redox_syscall"
version = "0.2.5"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom 0.2.0",
- "redox_syscall 0.2.5",
+ "redox_syscall",
]
[[package]]
"tokio",
"tokio-util",
"toml",
- "url 2.1.1",
+ "url 2.2.2",
"walkdir",
]
"serde_json",
"smallvec",
"syn",
- "url 2.1.1",
+ "url 2.2.2",
"winapi 0.3.9",
]
[[package]]
name = "socket2"
-version = "0.3.16"
+version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"libc",
- "redox_syscall 0.1.57",
"winapi 0.3.9",
]
[[package]]
name = "tar"
-version = "0.4.29"
+version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8a4c1d0bee3230179544336c15eefb563cf0302955d962e456542323e8c2e8a"
+checksum = "c0bcfbd6a598361fda270d82469fff3d65089dc33e175c9a131f7b4cd395f228"
dependencies = [
"filetime",
"libc",
- "redox_syscall 0.1.57",
"xattr",
]
"cfg-if 1.0.0",
"libc",
"rand 0.8.3",
- "redox_syscall 0.2.5",
+ "redox_syscall",
"remove_dir_all",
"winapi 0.3.9",
]
[[package]]
name = "url"
-version = "2.1.1"
+version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
+ "form_urlencoded",
"idna 0.2.0",
"matches",
"percent-encoding 2.1.0",
[[package]]
name = "version_check"
-version = "0.9.1"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "vte"
param_mode: ParamMode,
mut itctx: ImplTraitContext<'_, 'hir>,
) -> hir::QPath<'hir> {
+ debug!("lower_qpath(id: {:?}, qself: {:?}, p: {:?})", id, qself, p);
let qself_position = qself.as_ref().map(|q| q.position);
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
itctx: ImplTraitContext<'_, 'hir>,
explicit_owner: Option<NodeId>,
) -> hir::PathSegment<'hir> {
+ debug!(
+ "path_span: {:?}, lower_path_segment(segment: {:?}, expected_lifetimes: {:?})",
+ path_span, segment, expected_lifetimes
+ );
let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
let msg = "parenthesized type parameters may only be used with a `Fn` trait";
match **generic_args {
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro;
+use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::symbol::sym;
mod asm;
}
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
- register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
+ register(
+ sym::quote,
+ SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client, krate: LOCAL_CRATE })),
+ );
}
let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.source_map().lookup_char_pos(topmost.lo());
- base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name.to_string())))
+ base::MacEager::expr(
+ cx.expr_str(topmost, Symbol::intern(&loc.file.name.prefer_remapped().to_string_lossy())),
+ )
}
pub fn expand_stringify(
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
let const_loc = self.tcx.const_caller_location((
- rustc_span::symbol::Symbol::intern(&caller.file.name.to_string()),
+ rustc_span::symbol::Symbol::intern(
+ &caller.file.name.prefer_remapped().to_string_lossy(),
+ ),
caller.line as u32,
caller.col_display as u32 + 1,
));
) -> FileId {
match &file.name {
FileName::Real(path) => {
- let (dir_path, file_name) = split_path_dir_and_file(path.stable_name());
+ let (dir_path, file_name) = split_path_dir_and_file(path.remapped_path_if_available());
let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str());
let file_name = osstr_as_utf8_bytes(file_name);
filename => {
let dir_id = line_program.default_directory();
let dummy_file_name = LineString::new(
- filename.to_string().into_bytes(),
+ filename.prefer_remapped().to_string().into_bytes(),
line_program.encoding(),
line_strings,
);
// FIXME: how to get version when building out of tree?
// Normally this would use option_env!("CFG_VERSION").
let producer = format!("cg_clif (rustc {})", "unknown version");
- let comp_dir = tcx.sess.working_dir.0.to_string_lossy().into_owned();
+ let comp_dir = tcx.sess.working_dir.to_string_lossy(false).into_owned();
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
Some(path) => {
let name = path.to_string_lossy().into_owned();
metadata_module,
metadata,
windows_subsystem,
- linker_info: LinkerInfo::new(tcx),
+ linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
crate_info: CrateInfo::new(tcx),
},
work_products,
) -> Result<(), ErrorReported> {
use rustc_codegen_ssa::back::link::link_binary;
- let target_cpu = crate::target_triple(sess).to_string();
link_binary::<crate::archive::ArArchiveBuilder<'_>>(
sess,
&codegen_results,
outputs,
&codegen_results.crate_name.as_str(),
- &target_cpu,
);
Ok(())
use cstr::cstr;
use rustc_codegen_ssa::traits::*;
-use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::HasTyCtxt;
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::OptLevel;
use rustc_session::Session;
}
}
-pub fn provide_both(providers: &mut Providers) {
- providers.wasm_import_module_map = |tcx, cnum| {
- // Build up a map from DefId to a `NativeLib` structure, where
- // `NativeLib` internally contains information about
- // `#[link(wasm_import_module = "...")]` for example.
- let native_libs = tcx.native_libraries(cnum);
-
- let def_id_to_native_lib = native_libs
- .iter()
- .filter_map(|lib| lib.foreign_module.map(|id| (id, lib)))
- .collect::<FxHashMap<_, _>>();
-
- let mut ret = FxHashMap::default();
- for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
- let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
- let module = match module {
- Some(s) => s,
- None => continue,
- };
- ret.extend(lib.foreign_items.iter().map(|id| {
- assert_eq!(id.krate, cnum);
- (*id, module.to_string())
- }));
- }
-
- ret
- };
-}
-
fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<CString> {
tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap())
}
}
pub fn file_metadata(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
- debug!("file_metadata: file_name: {}", source_file.name);
+ debug!("file_metadata: file_name: {:?}", source_file.name);
let hash = Some(&source_file.src_hash);
- let file_name = Some(source_file.name.to_string());
+ let file_name = Some(source_file.name.prefer_remapped().to_string());
let directory = if source_file.is_real_file() && !source_file.is_imported() {
- Some(cx.sess().working_dir.0.to_string_lossy().to_string())
+ Some(cx.sess().working_dir.to_string_lossy(false).to_string())
} else {
// If the path comes from an upstream crate we assume it has been made
// independent of the compiler's working directory one way or another.
let producer = format!("clang LLVM ({})", rustc_producer);
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
- let work_dir = tcx.sess.working_dir.0.to_string_lossy();
+ let work_dir = tcx.sess.working_dir.to_string_lossy(false);
let flags = "\0";
let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory;
let split_name = if tcx.sess.target_can_use_split_dwarf() {
Box::new(metadata::LlvmMetadataLoader)
}
- fn provide(&self, providers: &mut ty::query::Providers) {
- attributes::provide_both(providers);
- }
-
- fn provide_extern(&self, providers: &mut ty::query::Providers) {
- attributes::provide_both(providers);
- }
+ fn provide(&self, _providers: &mut ty::query::Providers) {}
+ fn provide_extern(&self, _providers: &mut ty::query::Providers) {}
fn codegen_crate<'tcx>(
&self,
Box::new(rustc_codegen_ssa::base::codegen_crate(
LlvmCodegenBackend(()),
tcx,
+ crate::llvm_util::target_cpu(tcx.sess).to_string(),
metadata,
need_metadata_module,
))
// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
- let target_cpu = crate::llvm_util::target_cpu(sess);
link_binary::<LlvmArchiveBuilder<'_>>(
sess,
&codegen_results,
outputs,
&codegen_results.crate_name.as_str(),
- target_cpu,
);
Ok(())
codegen_results: &CodegenResults,
outputs: &OutputFilenames,
crate_name: &str,
- target_cpu: &str,
) {
let _timer = sess.timer("link_binary");
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
&out_filename,
codegen_results,
path.as_ref(),
- target_cpu,
);
}
}
out_filename: &Path,
codegen_results: &CodegenResults,
tmpdir: &Path,
- target_cpu: &str,
) {
info!("preparing {:?} to {:?}", crate_type, out_filename);
let (linker_path, flavor) = linker_and_flavor(sess);
tmpdir,
out_filename,
codegen_results,
- target_cpu,
);
linker::disable_localization(&mut cmd);
tmpdir: &Path,
out_filename: &Path,
codegen_results: &CodegenResults,
- target_cpu: &str,
) -> Command {
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback);
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
// to the linker args construction.
assert!(base_cmd.get_args().is_empty() || sess.target.vendor == "uwp");
- let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor, target_cpu);
+ let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor);
let link_output_kind = link_output_kind(sess, crate_type);
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
/// need out of the shared crate context before we get rid of it.
#[derive(Encodable, Decodable)]
pub struct LinkerInfo {
+ target_cpu: String,
exports: FxHashMap<CrateType, Vec<String>>,
}
impl LinkerInfo {
- pub fn new(tcx: TyCtxt<'_>) -> LinkerInfo {
+ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> LinkerInfo {
LinkerInfo {
+ target_cpu,
exports: tcx
.sess
.crate_types()
cmd: Command,
sess: &'a Session,
flavor: LinkerFlavor,
- target_cpu: &'a str,
) -> Box<dyn Linker + 'a> {
match flavor {
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess, info: self }) as Box<dyn Linker>
}
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess, info: self }) as Box<dyn Linker>,
- LinkerFlavor::Gcc => Box::new(GccLinker {
- cmd,
- sess,
- info: self,
- hinted_static: false,
- is_ld: false,
- target_cpu,
- }) as Box<dyn Linker>,
+ LinkerFlavor::Gcc => {
+ Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: false })
+ as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64)
- | LinkerFlavor::Ld => Box::new(GccLinker {
- cmd,
- sess,
- info: self,
- hinted_static: false,
- is_ld: true,
- target_cpu,
- }) as Box<dyn Linker>,
+ | LinkerFlavor::Ld => {
+ Box::new(GccLinker { cmd, sess, info: self, hinted_static: false, is_ld: true })
+ as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Wasm) => {
Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
}
- LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
+ LinkerFlavor::PtxLinker => {
+ Box::new(PtxLinker { cmd, sess, info: self }) as Box<dyn Linker>
+ }
}
}
}
hinted_static: bool, // Keeps track of the current hinting mode.
// Link as ld
is_ld: bool,
- target_cpu: &'a str,
}
impl<'a> GccLinker<'a> {
};
self.linker_arg(&format!("-plugin-opt={}", opt_level));
- let target_cpu = self.target_cpu;
- self.linker_arg(&format!("-plugin-opt=mcpu={}", target_cpu));
+ self.linker_arg(&format!("-plugin-opt=mcpu={}", self.info.target_cpu));
}
fn build_dylib(&mut self, out_filename: &Path) {
pub struct PtxLinker<'a> {
cmd: Command,
sess: &'a Session,
+ info: &'a LinkerInfo,
}
impl<'a> Linker for PtxLinker<'a> {
fn finalize(&mut self) {
// Provide the linker with fallback to internal `target-cpu`.
- self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu {
- Some(ref s) => s,
- None => &self.sess.target.cpu,
- });
+ self.cmd.arg("--fallback-arch").arg(&self.info.target_cpu);
}
fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
+ providers.wasm_import_module_map = wasm_import_module_map;
}
pub fn provide_extern(providers: &mut Providers) {
providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider;
+ providers.wasm_import_module_map = wasm_import_module_map;
}
fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel {
ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
}
}
+
+fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> {
+ // Build up a map from DefId to a `NativeLib` structure, where
+ // `NativeLib` internally contains information about
+ // `#[link(wasm_import_module = "...")]` for example.
+ let native_libs = tcx.native_libraries(cnum);
+
+ let def_id_to_native_lib = native_libs
+ .iter()
+ .filter_map(|lib| lib.foreign_module.map(|id| (id, lib)))
+ .collect::<FxHashMap<_, _>>();
+
+ let mut ret = FxHashMap::default();
+ for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
+ let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
+ let module = match module {
+ Some(s) => s,
+ None => continue,
+ };
+ ret.extend(lib.foreign_items.iter().map(|id| {
+ assert_eq!(id.krate, cnum);
+ (*id, module.to_string())
+ }));
+ }
+
+ ret
+}
pub fn start_async_codegen<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
+ target_cpu: String,
metadata: EncodedMetadata,
total_cgus: usize,
) -> OngoingCodegen<B> {
subsystem.to_string()
});
- let linker_info = LinkerInfo::new(tcx);
+ let linker_info = LinkerInfo::new(tcx, target_cpu);
let crate_info = CrateInfo::new(tcx);
let regular_config =
pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'tcx>,
+ target_cpu: String,
metadata: EncodedMetadata,
need_metadata_module: bool,
) -> OngoingCodegen<B> {
// Skip crate items and just output metadata in -Z no-codegen mode.
if tcx.sess.opts.debugging_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() {
- let ongoing_codegen = start_async_codegen(backend, tcx, metadata, 1);
+ let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu, metadata, 1);
ongoing_codegen.codegen_finished(tcx);
}
}
- let ongoing_codegen = start_async_codegen(backend.clone(), tcx, metadata, codegen_units.len());
+ let ongoing_codegen =
+ start_async_codegen(backend.clone(), tcx, target_cpu, metadata, codegen_units.len());
let ongoing_codegen = AbortCodegenOnDrop::<B>(Some(ongoing_codegen));
// Codegen an allocator shim, if necessary.
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
let const_loc = tcx.const_caller_location((
- Symbol::intern(&caller.file.name.to_string()),
+ Symbol::intern(&caller.file.name.prefer_remapped().to_string_lossy()),
caller.line as u32,
caller.col_display as u32 + 1,
));
use rustc_session::getopts;
use rustc_session::lint::{Lint, LintId};
use rustc_session::{config, DiagnosticOutput, Session};
-use rustc_session::{early_error, early_warn};
+use rustc_session::{early_error, early_error_no_abort, early_warn};
use rustc_span::source_map::{FileLoader, FileName};
use rustc_span::symbol::sym;
Registry::new(&rustc_error_codes::DIAGNOSTICS)
}
+/// This is the primary entry point for rustc.
pub struct RunCompiler<'a, 'b> {
at_args: &'a [String],
callbacks: &'b mut (dyn Callbacks + Send),
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
Self { at_args, callbacks, file_loader: None, emitter: None, make_codegen_backend: None }
}
+
+ /// Set a custom codegen backend.
+ ///
/// Used by cg_clif.
pub fn set_make_codegen_backend(
&mut self,
self.make_codegen_backend = make_codegen_backend;
self
}
+
+ /// Emit diagnostics to the specified location.
+ ///
/// Used by RLS.
pub fn set_emitter(&mut self, emitter: Option<Box<dyn Write + Send>>) -> &mut Self {
self.emitter = emitter;
self
}
+
+ /// Load files from sources other than the file system.
+ ///
/// Used by RLS.
pub fn set_file_loader(
&mut self,
self.file_loader = file_loader;
self
}
+
+ /// Parse args and run the compiler.
pub fn run(self) -> interface::Result<()> {
run_compiler(
self.at_args,
)
}
}
-// Parse args and run the compiler. This is the primary entry point for rustc.
-// The FileLoader provides a way to load files from sources other than the file system.
fn run_compiler(
at_args: &[String],
callbacks: &mut (dyn Callbacks + Send),
};
let sopts = config::build_session_options(&matches);
- let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
-
- // We wrap `make_codegen_backend` in another `Option` such that `dummy_config` can take
- // ownership of it when necessary, while also allowing the non-dummy config to take ownership
- // when `dummy_config` is not used.
- let mut make_codegen_backend = Some(make_codegen_backend);
-
- let mut dummy_config = |sopts, cfg, diagnostic_output| {
- let mut config = interface::Config {
- opts: sopts,
- crate_cfg: cfg,
- input: Input::File(PathBuf::new()),
- input_path: None,
- output_file: None,
- output_dir: None,
- file_loader: None,
- diagnostic_output,
- stderr: None,
- lint_caps: Default::default(),
- parse_sess_created: None,
- register_lints: None,
- override_queries: None,
- make_codegen_backend: make_codegen_backend.take().unwrap(),
- registry: diagnostics_registry(),
- };
- callbacks.config(&mut config);
- config
- };
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(diagnostics_registry(), code, sopts.error_format);
return Ok(());
}
+ let cfg = interface::parse_cfgspecs(matches.opt_strs("cfg"));
let (odir, ofile) = make_output(&matches);
- let (input, input_file_path, input_err) = match make_input(&matches.free) {
- Some(v) => v,
- None => match matches.free.len() {
+ let mut config = interface::Config {
+ opts: sopts,
+ crate_cfg: cfg,
+ input: Input::File(PathBuf::new()),
+ input_path: None,
+ output_file: ofile,
+ output_dir: odir,
+ file_loader,
+ diagnostic_output,
+ stderr: None,
+ lint_caps: Default::default(),
+ parse_sess_created: None,
+ register_lints: None,
+ override_queries: None,
+ make_codegen_backend,
+ registry: diagnostics_registry(),
+ };
+
+ match make_input(config.opts.error_format, &matches.free) {
+ Err(ErrorReported) => return Err(ErrorReported),
+ Ok(Some((input, input_file_path))) => {
+ config.input = input;
+ config.input_path = input_file_path;
+
+ callbacks.config(&mut config);
+ }
+ Ok(None) => match matches.free.len() {
0 => {
- let config = dummy_config(sopts, cfg, diagnostic_output);
+ callbacks.config(&mut config);
interface::run_compiler(config, |compiler| {
let sopts = &compiler.session().opts;
if sopts.describe_lints {
&***compiler.codegen_backend(),
compiler.session(),
None,
- &odir,
- &ofile,
+ &compiler.output_dir(),
+ &compiler.output_file(),
);
if should_stop == Compilation::Stop {
}
1 => panic!("make_input should have provided valid inputs"),
_ => early_error(
- sopts.error_format,
+ config.opts.error_format,
&format!(
"multiple input filenames provided (first two filenames are `{}` and `{}`)",
matches.free[0], matches.free[1],
},
};
- if let Some(err) = input_err {
- // Immediately stop compilation if there was an issue reading
- // the input (for example if the input stream is not UTF-8).
- interface::run_compiler(dummy_config(sopts, cfg, diagnostic_output), |compiler| {
- compiler.session().err(&err.to_string());
- });
- return Err(ErrorReported);
- }
-
- let mut config = interface::Config {
- opts: sopts,
- crate_cfg: cfg,
- input,
- input_path: input_file_path,
- output_file: ofile,
- output_dir: odir,
- file_loader,
- diagnostic_output,
- stderr: None,
- lint_caps: Default::default(),
- parse_sess_created: None,
- register_lints: None,
- override_queries: None,
- make_codegen_backend: make_codegen_backend.unwrap(),
- registry: diagnostics_registry(),
- };
-
- callbacks.config(&mut config);
-
interface::run_compiler(config, |compiler| {
let sess = compiler.session();
let should_stop = RustcDefaultCalls::print_crate_info(
RustcDefaultCalls::list_metadata(
sess,
&*compiler.codegen_backend().metadata_loader(),
- &matches,
compiler.input(),
)
})
return early_exit();
}
- if sess.opts.debugging_opts.save_analysis {
- let crate_name = queries.crate_name()?.peek().clone();
- queries.global_ctxt()?.peek_mut().enter(|tcx| {
- let result = tcx.analysis(LOCAL_CRATE);
-
+ queries.global_ctxt()?.peek_mut().enter(|tcx| {
+ let result = tcx.analysis(LOCAL_CRATE);
+ if sess.opts.debugging_opts.save_analysis {
+ let crate_name = queries.crate_name()?.peek().clone();
sess.time("save_analysis", || {
save::process_crate(
tcx,
),
)
});
-
- result
- })?;
- }
-
- queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
+ }
+ result
+ })?;
if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
return early_exit();
}
// Extract input (string or file and optional path) from matches.
-fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option<io::Error>)> {
+fn make_input(
+ error_format: ErrorOutputType,
+ free_matches: &[String],
+) -> Result<Option<(Input, Option<PathBuf>)>, ErrorReported> {
if free_matches.len() == 1 {
let ifile = &free_matches[0];
if ifile == "-" {
let mut src = String::new();
- let err = if io::stdin().read_to_string(&mut src).is_err() {
- Some(io::Error::new(
- io::ErrorKind::InvalidData,
+ if io::stdin().read_to_string(&mut src).is_err() {
+ // Immediately stop compilation if there was an issue reading
+ // the input (for example if the input stream is not UTF-8).
+ early_error_no_abort(
+ error_format,
"couldn't read from stdin, as it did not contain valid UTF-8",
- ))
- } else {
- None
- };
+ );
+ return Err(ErrorReported);
+ }
if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect(
"when UNSTABLE_RUSTDOC_TEST_PATH is set \
let line = isize::from_str_radix(&line, 10)
.expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
- return Some((Input::Str { name: file_name, input: src }, None, err));
+ Ok(Some((Input::Str { name: file_name, input: src }, None)))
+ } else {
+ Ok(Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None)))
}
- Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None, err))
} else {
- Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)), None))
+ Ok(Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)))))
}
} else {
- None
+ Ok(None)
}
}
}
impl RustcDefaultCalls {
- fn process_rlink(sess: &Session, compiler: &interface::Compiler) -> Result<(), ErrorReported> {
- if let Input::File(file) = compiler.input() {
- // FIXME: #![crate_type] and #![crate_name] support not implemented yet
- let attrs = vec![];
- sess.init_crate_types(collect_crate_types(sess, &attrs));
- let outputs = compiler.build_output_filenames(&sess, &attrs);
- let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
- sess.fatal(&format!("failed to read rlink file: {}", err));
- });
- let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| {
- sess.fatal(&format!("failed to decode rlink: {}", err));
- });
- compiler.codegen_backend().link(&sess, codegen_results, &outputs)
- } else {
- sess.fatal("rlink must be a file")
- }
- }
-
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
if sess.opts.debugging_opts.link_only {
- let result = RustcDefaultCalls::process_rlink(sess, compiler);
- abort_on_err(result, sess);
+ if let Input::File(file) = compiler.input() {
+ // FIXME: #![crate_type] and #![crate_name] support not implemented yet
+ sess.init_crate_types(collect_crate_types(sess, &[]));
+ let outputs = compiler.build_output_filenames(&sess, &[]);
+ let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
+ sess.fatal(&format!("failed to read rlink file: {}", err));
+ });
+ let codegen_results: CodegenResults =
+ json::decode(&rlink_data).unwrap_or_else(|err| {
+ sess.fatal(&format!("failed to decode rlink: {}", err));
+ });
+ let result = compiler.codegen_backend().link(&sess, codegen_results, &outputs);
+ abort_on_err(result, sess);
+ } else {
+ sess.fatal("rlink must be a file")
+ }
Compilation::Stop
} else {
Compilation::Continue
pub fn list_metadata(
sess: &Session,
metadata_loader: &dyn MetadataLoader,
- matches: &getopts::Matches,
input: &Input,
) -> Compilation {
- let r = matches.opt_strs("Z");
- if r.iter().any(|s| *s == "ls") {
+ if sess.opts.debugging_opts.ls {
match *input {
Input::File(ref ifile) => {
let path = &(*ifile);
}
// owned: line source, line index, annotations
type Owned = (String, usize, Vec<crate::snippet::Annotation>);
- let origin = primary_lo.file.name.to_string();
+ let filename = primary_lo.file.name.prefer_local();
+ let origin = filename.to_string_lossy();
let annotated_files: Vec<Owned> = annotated_files
.into_iter()
.flat_map(|annotated_file| {
// are some which do actually involve macros.
ExpnKind::Inlined | ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
- ExpnKind::Macro(macro_kind, _) => Some(macro_kind),
+ ExpnKind::Macro { kind: macro_kind, name: _, proc_macro: _ } => {
+ Some(macro_kind)
+ }
}
});
new_labels
.push((trace.call_site, "in the inlined copy of this code".to_string()));
} else if always_backtrace {
+ let proc_macro = if let ExpnKind::Macro { kind: _, name: _, proc_macro: true } =
+ trace.kind
+ {
+ "procedural macro "
+ } else {
+ ""
+ };
+
new_labels.push((
trace.def_site,
format!(
- "in this expansion of `{}`{}",
+ "in this expansion of {}`{}`{}",
+ proc_macro,
trace.kind.descr(),
if macro_backtrace.len() > 1 {
// if macro_backtrace.len() == 1 it'll be
// and it needs an "in this macro invocation" label to match that.
let redundant_span = trace.call_site.contains(sp);
- if !redundant_span && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
+ if !redundant_span
+ && matches!(
+ trace.kind,
+ ExpnKind::Macro { kind: MacroKind::Bang, name: _, proc_macro: _ }
+ )
|| always_backtrace
{
new_labels.push((
buffer_msg_line_offset,
&format!(
"{}:{}:{}",
- loc.file.name,
+ loc.file.name.prefer_local(),
sm.doctest_offset_line(&loc.file.name, loc.line),
loc.col.0 + 1,
),
0,
&format!(
"{}:{}:{}: ",
- loc.file.name,
+ loc.file.name.prefer_local(),
sm.doctest_offset_line(&loc.file.name, loc.line),
loc.col.0 + 1,
),
};
format!(
"{}:{}{}",
- annotated_file.file.name,
+ annotated_file.file.name.prefer_local(),
sm.doctest_offset_line(&annotated_file.file.name, first_line.line_index),
col
)
} else {
- annotated_file.file.name.to_string()
+ format!("{}", annotated_file.file.name.prefer_local())
};
buffer.append(buffer_msg_line_offset + 1, &loc, Style::LineAndColumn);
for _ in 0..max_line_num_len {
});
DiagnosticSpan {
- file_name: start.file.name.to_string(),
+ file_name: start.file.name.prefer_local().to_string(),
byte_start: start.file.original_relative_byte_pos(span.lo()).0,
byte_end: start.file.original_relative_byte_pos(span.hi()).0,
line_start: start.line,
use rustc_lint_defs::BuiltinLintDiagnostics;
use rustc_parse::{self, nt_to_tokenstream, parser, MACRO_ARGUMENTS};
use rustc_session::{parse::ParseSess, Limit, Session};
-use rustc_span::def_id::DefId;
+use rustc_span::def_id::{CrateNum, DefId};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind};
use rustc_span::source_map::SourceMap;
descr: Symbol,
macro_def_id: Option<DefId>,
) -> ExpnData {
+ use SyntaxExtensionKind::*;
+ let proc_macro = match self.kind {
+ // User-defined proc macro
+ Bang(..) | Attr(..) | Derive(..) => true,
+ // Consider everthing else to be not a proc
+ // macro for diagnostic purposes
+ LegacyBang(..) | LegacyAttr(..) | NonMacroAttr { .. } | LegacyDerive(..) => false,
+ };
ExpnData::new(
- ExpnKind::Macro(self.macro_kind(), descr),
+ ExpnKind::Macro { kind: self.macro_kind(), name: descr, proc_macro },
parent,
call_site,
self.span,
fn take_derive_resolutions(&mut self, expn_id: ExpnId) -> Option<DeriveResolutions>;
/// Path resolution logic for `#[cfg_accessible(path)]`.
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
+
+ /// Decodes the proc-macro quoted span in the specified crate, with the specified id.
+ /// No caching is performed.
+ fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
}
#[derive(Clone, Default)]
// after macro expansion (that is, they are unhygienic).
if !path.is_absolute() {
let callsite = span.source_callsite();
- let mut result = match self.source_map().span_to_unmapped_path(callsite) {
- FileName::Real(name) => name.into_local_path(),
+ let mut result = match self.source_map().span_to_filename(callsite) {
+ FileName::Real(name) => name
+ .into_local_path()
+ .expect("attempting to resolve a file path in an external file"),
FileName::DocTest(path, _) => path,
other => {
return Err(self.struct_span_err(
span,
- &format!("cannot resolve relative path in non-file source `{}`", other),
+ &format!(
+ "cannot resolve relative path in non-file source `{}`",
+ other.prefer_local()
+ ),
));
}
};
// FIXME: Avoid visiting the crate as a `Mod` item,
// make crate a first class expansion target instead.
pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
- let file_path = match self.cx.source_map().span_to_unmapped_path(krate.span) {
- FileName::Real(name) => name.into_local_path(),
- other => PathBuf::from(other.to_string()),
+ let file_path = match self.cx.source_map().span_to_filename(krate.span) {
+ FileName::Real(name) => name
+ .into_local_path()
+ .expect("attempting to resolve a file path in an external file"),
+ other => PathBuf::from(other.prefer_local().to_string()),
};
let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();
self.cx.root_path = dir_path.clone();
use rustc_errors::ErrorReported;
use rustc_parse::nt_to_tokenstream;
use rustc_parse::parser::ForceCollect;
+use rustc_span::def_id::CrateNum;
use rustc_span::{Span, DUMMY_SP};
const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread;
pub struct BangProcMacro {
pub client: pm::bridge::client::Client<fn(pm::TokenStream) -> pm::TokenStream>,
+ pub krate: CrateNum,
}
impl base::ProcMacro for BangProcMacro {
span: Span,
input: TokenStream,
) -> Result<TokenStream, ErrorReported> {
- let server = proc_macro_server::Rustc::new(ecx);
+ let server = proc_macro_server::Rustc::new(ecx, self.krate);
self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace).map_err(|e| {
let mut err = ecx.struct_span_err(span, "proc macro panicked");
if let Some(s) = e.as_str() {
pub struct AttrProcMacro {
pub client: pm::bridge::client::Client<fn(pm::TokenStream, pm::TokenStream) -> pm::TokenStream>,
+ pub krate: CrateNum,
}
impl base::AttrProcMacro for AttrProcMacro {
annotation: TokenStream,
annotated: TokenStream,
) -> Result<TokenStream, ErrorReported> {
- let server = proc_macro_server::Rustc::new(ecx);
+ let server = proc_macro_server::Rustc::new(ecx, self.krate);
self.client
.run(&EXEC_STRATEGY, server, annotation, annotated, ecx.ecfg.proc_macro_backtrace)
.map_err(|e| {
pub struct ProcMacroDerive {
pub client: pm::bridge::client::Client<fn(pm::TokenStream) -> pm::TokenStream>,
+ pub krate: CrateNum,
}
impl MultiItemModifier for ProcMacroDerive {
nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
};
- let server = proc_macro_server::Rustc::new(ecx);
+ let server = proc_macro_server::Rustc::new(ecx, self.krate);
let stream =
match self.client.run(&EXEC_STRATEGY, server, input, ecx.ecfg.proc_macro_backtrace) {
Ok(stream) => stream,
-use crate::base::ExtCtxt;
+use crate::base::{ExtCtxt, ResolverExpand};
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, CanSynthesizeMissingTokens};
use rustc_ast::tokenstream::{DelimSpan, Spacing::*, TokenStream, TreeAndSpacing};
use rustc_ast_pretty::pprust;
+use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::Diagnostic;
use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str};
use rustc_session::parse::ParseSess;
+use rustc_span::def_id::CrateNum;
+use rustc_span::hygiene::ExpnId;
use rustc_span::hygiene::ExpnKind;
use rustc_span::symbol::{self, kw, sym, Symbol};
use rustc_span::{BytePos, FileName, MultiSpan, Pos, RealFileName, SourceFile, Span};
}
pub(crate) struct Rustc<'a> {
+ resolver: &'a dyn ResolverExpand,
sess: &'a ParseSess,
def_site: Span,
call_site: Span,
mixed_site: Span,
span_debug: bool,
+ krate: CrateNum,
+ expn_id: ExpnId,
+ rebased_spans: FxHashMap<usize, Span>,
}
impl<'a> Rustc<'a> {
- pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
+ pub fn new(cx: &'a ExtCtxt<'_>, krate: CrateNum) -> Self {
let expn_data = cx.current_expansion.id.expn_data();
+ let def_site = cx.with_def_site_ctxt(expn_data.def_site);
+ let call_site = cx.with_call_site_ctxt(expn_data.call_site);
+ let mixed_site = cx.with_mixed_site_ctxt(expn_data.call_site);
+ let sess = cx.parse_sess();
Rustc {
- sess: &cx.sess.parse_sess,
- def_site: cx.with_def_site_ctxt(expn_data.def_site),
- call_site: cx.with_call_site_ctxt(expn_data.call_site),
- mixed_site: cx.with_mixed_site_ctxt(expn_data.call_site),
+ resolver: cx.resolver,
+ sess,
+ def_site,
+ call_site,
+ mixed_site,
span_debug: cx.ecfg.span_debug,
+ krate,
+ expn_id: cx.current_expansion.id,
+ rebased_spans: FxHashMap::default(),
}
}
match file.name {
FileName::Real(ref name) => name
.local_path()
+ .expect("attempting to get a file path in an imported file in `proc_macro::SourceFile::path`")
.to_str()
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
.to_string(),
- _ => file.name.to_string(),
+ _ => file.name.prefer_local().to_string(),
}
}
fn is_real(&mut self, file: &Self::SourceFile) -> bool {
fn source_text(&mut self, span: Self::Span) -> Option<String> {
self.sess.source_map().span_to_snippet(span).ok()
}
+ /// Saves the provided span into the metadata of
+ /// *the crate we are currently compiling*, which must
+ /// be a proc-macro crate. This id can be passed to
+ /// `recover_proc_macro_span` when our current crate
+ /// is *run* as a proc-macro.
+ ///
+ /// Let's suppose that we have two crates - `my_client`
+ /// and `my_proc_macro`. The `my_proc_macro` crate
+ /// contains a procedural macro `my_macro`, which
+ /// is implemented as: `quote! { "hello" }`
+ ///
+ /// When we *compile* `my_proc_macro`, we will execute
+ /// the `quote` proc-macro. This will save the span of
+ /// "hello" into the metadata of `my_proc_macro`. As a result,
+ /// the body of `my_proc_macro` (after expansion) will end
+ /// up containg a call that looks like this:
+ /// `proc_macro::Ident::new("hello", proc_macro::Span::recover_proc_macro_span(0))`
+ ///
+ /// where `0` is the id returned by this function.
+ /// When `my_proc_macro` *executes* (during the compilation of `my_client`),
+ /// the call to `recover_proc_macro_span` will load the corresponding
+ /// span from the metadata of `my_proc_macro` (which we have access to,
+ /// since we've loaded `my_proc_macro` from disk in order to execute it).
+ /// In this way, we have obtained a span pointing into `my_proc_macro`
+ fn save_span(&mut self, mut span: Self::Span) -> usize {
+ // Throw away the `SyntaxContext`, since we currently
+ // skip serializing `SyntaxContext`s for proc-macro crates
+ span = span.with_ctxt(rustc_span::SyntaxContext::root());
+ self.sess.save_proc_macro_span(span)
+ }
+ fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
+ let resolver = self.resolver;
+ let krate = self.krate;
+ let expn_id = self.expn_id;
+ *self.rebased_spans.entry(id).or_insert_with(|| {
+ let raw_span = resolver.get_proc_macro_quoted_span(krate, id);
+ // Ignore the deserialized `SyntaxContext` entirely.
+ // FIXME: Preserve the macro backtrace from the serialized span
+ // For example, if a proc-macro crate has code like
+ // `macro_one!() -> macro_two!() -> quote!()`, we might
+ // want to 'concatenate' this backtrace with the backtrace from
+ // our current call site.
+ raw_span.with_def_site_ctxt(expn_id)
+ })
+ }
}
// See issue #74616 for details
rustc: &mut Rustc<'_>,
) -> Option<(rustc_span::symbol::Ident, bool)> {
if let NtIdent(ident, is_raw) = nt {
- if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
+ if let ExpnKind::Macro { name: macro_name, .. } = orig_span.ctxt().outer_expn_data().kind {
let source_map = rustc.sess.source_map();
let filename = source_map.span_to_filename(orig_span);
- if let FileName::Real(RealFileName::Named(path)) = filename {
+ if let FileName::Real(RealFileName::LocalPath(path)) = filename {
let matches_prefix = |prefix, filename| {
// Check for a path that ends with 'prefix*/src/<filename>'
let mut iter = path.components().rev();
if macro_name == sym::tuple_from_req && matches_prefix("actix-web", "extract.rs") {
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$T") {
- if let FileName::Real(RealFileName::Named(macro_path)) =
+ if let FileName::Real(RealFileName::LocalPath(macro_path)) =
source_map.span_to_filename(rustc.def_site)
{
if macro_path.to_string_lossy().contains("pin-project-internal-0.") {
/// Allows using non lexical lifetimes (RFC 2094).
(active, nll, "1.0.0", Some(43234), None),
- /// Allows the definition of `const` functions with some advanced features.
- (active, const_fn, "1.2.0", Some(57563), None),
-
/// Allows associated type defaults.
(active, associated_type_defaults, "1.2.0", Some(29661), None),
(removed, main, "1.53.0", Some(29634), None, None),
(removed, pub_macro_rules, "1.53.0", Some(78855), None,
Some("removed due to being incomplete, in particular it does not work across crates")),
+ /// Allows the definition of `const` functions with some advanced features.
+ (removed, const_fn, "1.54.0", Some(57563), None,
+ Some("split into finer-grained feature gates")),
// -------------------------------------------------------------------------
// feature-group-end: removed features
//! Code to save/load the dep-graph from files.
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::definitions::Definitions;
+use rustc_hir::definitions::DefPathTable;
use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
use rustc_middle::ty::query::OnDiskCache;
use rustc_serialize::opaque::Decoder;
/// creating an empty cache if it could not be loaded.
pub fn load_query_result_cache<'a>(
sess: &'a Session,
- definitions: &Definitions,
+ def_path_table: &DefPathTable,
) -> Option<OnDiskCache<'a>> {
if sess.opts.incremental.is_none() {
return None;
sess.is_nightly_build(),
) {
LoadResult::Ok { data: (bytes, start_pos) } => {
- Some(OnDiskCache::new(sess, bytes, start_pos, definitions))
+ Some(OnDiskCache::new(sess, bytes, start_pos, def_path_table))
}
_ => Some(OnDiskCache::new_empty(sess.source_map())),
}
match (&terr, expected == found) {
(TypeError::Sorts(values), extra) => {
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
- (true, ty::Opaque(def_id, _)) => format!(
- " (opaque type at {})",
- self.tcx
+ (true, ty::Opaque(def_id, _)) => {
+ let pos = self
+ .tcx
.sess
.source_map()
- .mk_substr_filename(self.tcx.def_span(*def_id)),
- ),
+ .lookup_char_pos(self.tcx.def_span(*def_id).lo());
+ format!(
+ " (opaque type at <{}:{}:{}>)",
+ pos.file.name.prefer_local(),
+ pos.line,
+ pos.col.to_usize() + 1,
+ )
+ }
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
(false, _) => "".to_string(),
};
use rustc_errors::{ErrorReported, PResult};
use rustc_expand::base::ExtCtxt;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
-use rustc_hir::definitions::Definitions;
use rustc_hir::Crate;
use rustc_lint::LintStore;
use rustc_metadata::creader::CStore;
use rustc_session::search_paths::PathKind;
use rustc_session::Session;
use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{FileName, RealFileName};
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
use tracing::{info, warn};
use std::lazy::SyncLazy;
use std::path::PathBuf;
use std::rc::Rc;
-use std::{env, fs, iter, mem};
+use std::{env, fs, iter};
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
let krate = sess.time("parse_crate", || match input {
check_output(output_paths, check)
}
-fn escape_dep_filename(filename: &FileName) -> String {
+fn escape_dep_filename(filename: &String) -> String {
// Apparently clang and gcc *only* escape spaces:
// http://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4
- filename.to_string().replace(" ", "\\ ")
+ filename.replace(" ", "\\ ")
}
// Makefile comments only need escaping newlines and `\`.
.iter()
.filter(|fmap| fmap.is_real_file())
.filter(|fmap| !fmap.is_imported())
- .map(|fmap| escape_dep_filename(&fmap.unmapped_path.as_ref().unwrap_or(&fmap.name)))
+ .map(|fmap| escape_dep_filename(&fmap.name.prefer_local().to_string()))
.collect();
if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
for cnum in resolver.cstore().crates_untracked() {
let source = resolver.cstore().crate_source_untracked(cnum);
if let Some((path, _)) = source.dylib {
- let file_name = FileName::Real(RealFileName::Named(path));
- files.push(escape_dep_filename(&file_name));
+ files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = source.rlib {
- let file_name = FileName::Real(RealFileName::Named(path));
- files.push(escape_dep_filename(&file_name));
+ files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = source.rmeta {
- let file_name = FileName::Real(RealFileName::Named(path));
- files.push(escape_dep_filename(&file_name));
+ files.push(escape_dep_filename(&path.display().to_string()));
}
}
});
lint_store: Lrc<LintStore>,
krate: &'tcx Crate<'tcx>,
dep_graph: DepGraph,
- mut resolver_outputs: ResolverOutputs,
+ resolver_outputs: ResolverOutputs,
outputs: OutputFilenames,
crate_name: &str,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
) -> QueryContext<'tcx> {
let sess = &compiler.session();
- let defs: &'tcx Definitions = arena.alloc(mem::replace(
- &mut resolver_outputs.definitions,
- Definitions::new(crate_name, sess.local_crate_disambiguator()),
- ));
- let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess, defs);
+ let def_path_table = resolver_outputs.definitions.def_path_table();
+ let query_result_on_disk_cache =
+ rustc_incremental::load_query_result_cache(sess, def_path_table);
let codegen_backend = compiler.codegen_backend();
let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
arena,
resolver_outputs,
krate,
- defs,
dep_graph,
query_result_on_disk_cache,
queries.as_dyn(),
tracked!(profile_emit, Some(PathBuf::from("abc")));
tracked!(relax_elf_relocations, Some(true));
tracked!(relro_level, Some(RelroLevel::Full));
+ tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
tracked!(report_delayed_bugs, true);
tracked!(sanitizer, SanitizerSet::ADDRESS);
tracked!(sanitizer_memory_track_origins, 2);
if last.ident.name == sym::LintPass {
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
let call_site = expn_data.call_site;
- if expn_data.kind != ExpnKind::Macro(MacroKind::Bang, sym::impl_lint_pass)
- && call_site.ctxt().outer_expn_data().kind
- != ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass)
- {
+ if !matches!(
+ expn_data.kind,
+ ExpnKind::Macro {
+ kind: MacroKind::Bang,
+ name: sym::impl_lint_pass,
+ proc_macro: _
+ }
+ ) && !matches!(
+ call_site.ctxt().outer_expn_data().kind,
+ ExpnKind::Macro {
+ kind: MacroKind::Bang,
+ name: sym::declare_lint_pass,
+ proc_macro: _
+ }
+ ) {
cx.struct_span_lint(
LINT_PASS_IMPL_WITHOUT_MACRO,
lint_pass.path.span,
}
}
- let macro_symbol = if let hygiene::ExpnKind::Macro(_, symbol) = expn.kind {
- symbol
- } else {
- Symbol::intern("panic")
- };
+ let macro_symbol =
+ if let hygiene::ExpnKind::Macro { kind: _, name: symbol, proc_macro: _ } = expn.kind {
+ symbol
+ } else {
+ Symbol::intern("panic")
+ };
(expn.call_site, panic_macro, macro_symbol.as_str())
}
.decode((self, sess))
}
- fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
- let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
+ fn load_proc_macro(&self, def_id: DefId, sess: &Session) -> SyntaxExtension {
+ let (name, kind, helper_attrs) = match *self.raw_proc_macro(def_id.index) {
ProcMacro::CustomDerive { trait_name, attributes, client } => {
let helper_attrs =
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
(
trait_name,
- SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive { client })),
+ SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
+ client,
+ krate: def_id.krate,
+ })),
helper_attrs,
)
}
- ProcMacro::Attr { name, client } => {
- (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
- }
- ProcMacro::Bang { name, client } => {
- (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
- }
+ ProcMacro::Attr { name, client } => (
+ name,
+ SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client, krate: def_id.krate })),
+ Vec::new(),
+ ),
+ ProcMacro::Bang { name, client } => (
+ name,
+ SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client, krate: def_id.krate })),
+ Vec::new(),
+ ),
};
- let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
+ let attrs: Vec<_> = self.get_item_attrs(def_id.index, sess).collect();
SyntaxExtension::new(
sess,
kind,
- self.get_span(id, sess),
+ self.get_span(def_id.index, sess),
helper_attrs,
self.root.edition,
Symbol::intern(name),
}
}
+ fn get_proc_macro_quoted_span(&self, index: usize, sess: &Session) -> Span {
+ self.root
+ .tables
+ .proc_macro_quoted_spans
+ .get(self, index)
+ .unwrap_or_else(|| panic!("Missing proc macro quoted span: {:?}", index))
+ .decode((self, sess))
+ }
+
fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> Lrc<FxHashMap<DefId, ForeignModule>> {
if self.root.is_proc_macro_crate() {
// Proc macro crates do not have any *target* foreign modules.
if let Some(virtual_dir) = virtual_rust_source_base_dir {
if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
if let rustc_span::FileName::Real(old_name) = name {
- if let rustc_span::RealFileName::Named(one_path) = old_name {
- if let Ok(rest) = one_path.strip_prefix(virtual_dir) {
- let virtual_name = one_path.clone();
+ if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
+ old_name
+ {
+ if let Ok(rest) = virtual_name.strip_prefix(virtual_dir) {
+ let virtual_name = virtual_name.clone();
// The std library crates are in
// `$sysroot/lib/rustlib/src/rust/library`, whereas other crates
virtual_name.display(),
new_path.display(),
);
- let new_name = rustc_span::RealFileName::Devirtualized {
- local_path: new_path,
+ let new_name = rustc_span::RealFileName::Remapped {
+ local_path: Some(new_path),
virtual_name,
};
*old_name = new_name;
// containing the information we need.
let rustc_span::SourceFile {
mut name,
- name_was_remapped,
src_hash,
start_pos,
end_pos,
..
} = source_file_to_import;
+ // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
+ // during rust bootstrapping by `remap-debuginfo = true`, and the user
+ // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
+ // then we change `name` to a similar state as if the rust was bootstrapped
+ // with `remap-debuginfo = true`.
+ // This is useful for testing so that tests about the effects of
+ // `try_to_translate_virtual_to_real` don't have to worry about how the
+ // compiler is bootstrapped.
+ if let Some(virtual_dir) =
+ &sess.opts.debugging_opts.simulate_remapped_rust_src_base
+ {
+ if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
+ if let rustc_span::FileName::Real(ref mut old_name) = name {
+ if let rustc_span::RealFileName::LocalPath(local) = old_name {
+ if let Ok(rest) = local.strip_prefix(real_dir) {
+ *old_name = rustc_span::RealFileName::Remapped {
+ local_path: None,
+ virtual_name: virtual_dir.join(rest),
+ };
+ }
+ }
+ }
+ }
+ }
+
// If this file's path has been remapped to `/rustc/$hash`,
// we might be able to reverse that (also see comments above,
// on `try_to_translate_virtual_to_real`).
- // FIXME(eddyb) we could check `name_was_remapped` here,
- // but in practice it seems to be always `false`.
try_to_translate_virtual_to_real(&mut name);
let source_length = (end_pos - start_pos).to_usize();
let local_version = sess.source_map().new_imported_source_file(
name,
- name_was_remapped,
src_hash,
name_hash,
source_length,
let data = self.get_crate_data(id.krate);
if data.root.is_proc_macro_crate() {
- return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
+ return LoadedMacro::ProcMacro(data.load_proc_macro(id, sess));
}
let span = data.get_span(id.index, sess);
pub fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
}
+
+ pub fn get_proc_macro_quoted_span_untracked(
+ &self,
+ cnum: CrateNum,
+ id: usize,
+ sess: &Session,
+ ) -> Span {
+ self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
+ }
}
impl CrateStore for CStore {
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_serialize::{opaque, Encodable, Encoder};
use rustc_session::config::CrateType;
-use rustc_span::hygiene::{ExpnDataEncodeMode, HygieneEncodeContext, MacroKind};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
+use rustc_span::{
+ hygiene::{ExpnDataEncodeMode, HygieneEncodeContext, MacroKind},
+ RealFileName,
+};
use rustc_target::abi::VariantIdx;
use std::hash::Hash;
use std::num::NonZeroUsize;
let source_map = self.tcx.sess.source_map();
let all_source_files = source_map.files();
- let (working_dir, _cwd_remapped) = self.tcx.sess.working_dir.clone();
// By replacing the `Option` with `None`, we ensure that we can't
// accidentally serialize any more `Span`s after the source map encoding
// is done.
})
.map(|(_, source_file)| {
let mut adapted = match source_file.name {
- // This path of this SourceFile has been modified by
- // path-remapping, so we use it verbatim (and avoid
- // cloning the whole map in the process).
- _ if source_file.name_was_remapped => source_file.clone(),
-
- // Otherwise expand all paths to absolute paths because
- // any relative paths are potentially relative to a
- // wrong directory.
- FileName::Real(ref name) => {
- let name = name.stable_name();
+ FileName::Real(ref realname) => {
let mut adapted = (**source_file).clone();
- adapted.name = Path::new(&working_dir).join(name).into();
+ adapted.name = FileName::Real(match realname {
+ RealFileName::LocalPath(path_to_file) => {
+ // Prepend path of working directory onto potentially
+ // relative paths, because they could become relative
+ // to a wrong directory.
+ let working_dir = &self.tcx.sess.working_dir;
+ match working_dir {
+ RealFileName::LocalPath(absolute) => {
+ // If working_dir has not been remapped, then we emit a
+ // LocalPath variant as it's likely to be a valid path
+ RealFileName::LocalPath(
+ Path::new(absolute).join(path_to_file),
+ )
+ }
+ RealFileName::Remapped { local_path: _, virtual_name } => {
+ // If working_dir has been remapped, then we emit
+ // Remapped variant as the expanded path won't be valid
+ RealFileName::Remapped {
+ local_path: None,
+ virtual_name: Path::new(virtual_name)
+ .join(path_to_file),
+ }
+ }
+ }
+ }
+ RealFileName::Remapped { local_path: _, virtual_name } => {
+ RealFileName::Remapped {
+ // We do not want any local path to be exported into metadata
+ local_path: None,
+ virtual_name: virtual_name.clone(),
+ }
+ }
+ });
adapted.name_hash = {
let mut hasher: StableHasher = StableHasher::new();
adapted.name.hash(&mut hasher);
let proc_macro_decls_static = tcx.proc_macro_decls_static(LOCAL_CRATE).unwrap().index;
let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).copied();
let macros = self.lazy(hir.krate().proc_macros.iter().map(|p| p.owner.local_def_index));
+ let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans();
+ for (i, span) in spans.into_iter().enumerate() {
+ let span = self.lazy(span);
+ self.tables.proc_macro_quoted_spans.set(i, span);
+ }
record!(self.tables.def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod);
record!(self.tables.span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
/// Define `LazyTables` and `TableBuilders` at the same time.
macro_rules! define_tables {
- ($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
+ ($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
#[derive(MetadataEncodable, MetadataDecodable)]
crate struct LazyTables<'tcx> {
- $($name: Lazy!(Table<DefIndex, $T>)),+
+ $($name: Lazy!(Table<$IDX, $T>)),+
}
#[derive(Default)]
struct TableBuilders<'tcx> {
- $($name: TableBuilder<DefIndex, $T>),+
+ $($name: TableBuilder<$IDX, $T>),+
}
impl TableBuilders<'tcx> {
// definitions from any given crate.
def_keys: Table<DefIndex, Lazy<DefKey>>,
def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>,
+ proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
}
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
span,
"inconsistent DepNode at `{:?}` for `{}`: \
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
- self.source_map.span_to_string(span),
+ self.source_map.span_to_diagnostic_string(span),
node_str,
self.definitions
.def_path(self.current_dep_node_owner)
let SourceFile {
name: _, // We hash the smaller name_hash instead of this
name_hash,
- name_was_remapped,
- unmapped_path: _,
cnum,
// Do not hash the source as it is not encoded
src: _,
} = *self;
(name_hash as u64).hash_stable(hcx, hasher);
- name_was_remapped.hash_stable(hcx, hasher);
src_hash.hash_stable(hcx, hasher);
false
}
ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
- ExpnKind::Macro(MacroKind::Bang, _) => {
+ ExpnKind::Macro { kind: MacroKind::Bang, name: _, proc_macro: _ } => {
// Dummy span for the `def_site` means it's an external macro.
expn_data.def_site.is_dummy() || sess.source_map().is_imported(expn_data.def_site)
}
Free(DefId, /* lifetime decl */ DefId),
}
+/// This is used in diagnostics to improve suggestions for missing generic arguments.
+/// It gives information on the type of lifetimes that are in scope for a particular `PathSegment`,
+/// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g.
+#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
+pub enum LifetimeScopeForPath {
+ // Contains all lifetime names that are in scope and could possibly be used in generics
+ // arguments of path.
+ NonElided(Vec<String>),
+
+ // Information that allows us to suggest args of the form `<'_>` in case
+ // no generic arguments were provided for a path.
+ Elided,
+}
+
/// A set containing, at most, one known element.
/// If two distinct values are inserted into a set, then it
/// becomes `Many`, which can be used to detect ambiguities.
/// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
/// `id`.
- pub fn eval_stability(self, def_id: DefId, id: Option<HirId>, span: Span) -> EvalResult {
+ pub fn eval_stability(
+ self,
+ def_id: DefId,
+ id: Option<HirId>,
+ span: Span,
+ method_span: Option<Span>,
+ ) -> EvalResult {
// Deprecated attributes apply in-crate and cross-crate.
if let Some(id) = id {
if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
let path = &with_no_trimmed_paths(|| self.def_path_str(def_id));
let kind = self.def_kind(def_id).descr(def_id);
let (message, lint) = deprecation_message(&depr_entry.attr, kind, path);
+ let span = method_span.unwrap_or(span);
late_report_deprecation(
self,
&message,
///
/// This function will also check if the item is deprecated.
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
- pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
- self.check_optional_stability(def_id, id, span, |span, def_id| {
+ pub fn check_stability(
+ self,
+ def_id: DefId,
+ id: Option<HirId>,
+ span: Span,
+ method_span: Option<Span>,
+ ) {
+ self.check_optional_stability(def_id, id, span, method_span, |span, def_id| {
// The API could be uncallable for other reasons, for example when a private module
// was referenced.
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
def_id: DefId,
id: Option<HirId>,
span: Span,
+ method_span: Option<Span>,
unmarked: impl FnOnce(Span, DefId),
) {
let soft_handler = |lint, span, msg: &_| {
lint.build(msg).emit()
})
};
- match self.eval_stability(def_id, id, span) {
+ match self.eval_stability(def_id, id, span, method_span) {
EvalResult::Allow => {}
EvalResult::Deny { feature, reason, issue, is_soft } => {
report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler)
)
} else {
let span = tcx.hir().span(hir_id);
- format!("[closure@{}]", tcx.sess.source_map().span_to_string(span))
+ format!(
+ "[closure@{}]",
+ tcx.sess.source_map().span_to_diagnostic_string(span)
+ )
};
let mut struct_fmt = fmt.debug_struct(&name);
desc { "looking up late bound vars" }
}
+ query lifetime_scope_map(_: LocalDefId) -> Option<FxHashMap<ItemLocalId, LifetimeScopeForPath>> {
+ desc { "finds the lifetime scope for an HirId of a PathSegment" }
+ }
+
query visibility(def_id: DefId) -> ty::Visibility {
eval_always
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
use crate::middle;
use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
-use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
+use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
export_map: ExportMap<LocalDefId>,
pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
- pub(crate) definitions: &'tcx Definitions,
+ pub(crate) definitions: Definitions,
/// This provides access to the incremental compilation on-disk cache for query results.
/// Do not access this directly. It is only meant to be used by
arena: &'tcx WorkerLocal<Arena<'tcx>>,
resolutions: ty::ResolverOutputs,
krate: &'tcx hir::Crate<'tcx>,
- definitions: &'tcx Definitions,
dep_graph: DepGraph,
on_disk_cache: Option<query::OnDiskCache<'tcx>>,
queries: &'tcx dyn query::QueryEngine<'tcx>,
glob_map: resolutions.glob_map,
extern_prelude: resolutions.extern_prelude,
untracked_crate: krate,
- definitions,
+ definitions: resolutions.definitions,
on_disk_cache,
queries,
query_caches: query::QueryCaches::default(),
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
let krate = self.gcx.untracked_crate;
- StableHashingContext::new(self.sess, krate, self.definitions, &*self.cstore)
+ StableHashingContext::new(self.sess, krate, &self.definitions, &*self.cstore)
}
#[inline(always)]
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
let krate = self.gcx.untracked_crate;
- StableHashingContext::ignore_spans(self.sess, krate, self.definitions, &*self.cstore)
+ StableHashingContext::ignore_spans(self.sess, krate, &self.definitions, &*self.cstore)
}
pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
.iter(),
)
}
+
+ pub fn lifetime_scope(self, id: HirId) -> Option<LifetimeScopeForPath> {
+ self.lifetime_scope_map(id.owner).and_then(|mut map| map.remove(&id.local_id))
+ }
}
impl TyCtxtAt<'tcx> {
)
}),
IntMismatch(ref values) => {
- write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
+ let expected = match values.expected {
+ ty::IntVarValue::IntType(ty) => ty.name_str(),
+ ty::IntVarValue::UintType(ty) => ty.name_str(),
+ };
+ let found = match values.found {
+ ty::IntVarValue::IntType(ty) => ty.name_str(),
+ ty::IntVarValue::UintType(ty) => ty.name_str(),
+ };
+ write!(f, "expected `{}`, found `{}`", expected, found)
}
FloatMismatch(ref values) => {
- write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
+ write!(
+ f,
+ "expected `{}`, found `{}`",
+ values.expected.name_str(),
+ values.found.name_str()
+ )
}
VariadicMismatch(ref values) => write!(
f,
if let Some(did) = did.as_local() {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
let span = self.tcx().hir().span(hir_id);
- p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
+ p!(write(
+ "@{}",
+ // This may end up in stderr diagnostics but it may also be emitted
+ // into MIR. Hence we use the remapped path if available
+ self.tcx().sess.source_map().span_to_embeddable_string(span)
+ ));
} else {
p!(write("@"), print_def_path(did, substs));
}
p!("@", print_def_path(did.to_def_id(), substs));
} else {
let span = self.tcx().hir().span(hir_id);
- p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
+ p!(write(
+ "@{}",
+ // This may end up in stderr diagnostics but it may also be emitted
+ // into MIR. Hence we use the remapped path if available
+ self.tcx().sess.source_map().span_to_embeddable_string(span)
+ ));
}
} else {
p!(write("@"), print_def_path(did, substs));
if !self.empty_path {
write!(self, "::")?;
}
- write!(self, "<impl at {}>", self.tcx.sess.source_map().span_to_string(span))?;
+ write!(
+ self,
+ "<impl at {}>",
+ // This may end up in stderr diagnostics but it may also be emitted
+ // into MIR. Hence we use the remapped path if available
+ self.tcx.sess.source_map().span_to_embeddable_string(span)
+ )?;
self.empty_path = false;
return Ok(self);
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::AccessLevels;
use crate::middle::region;
-use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
+use crate::middle::resolve_lifetime::{
+ LifetimeScopeForPath, ObjectLifetimeDefault, Region, ResolveLifetimes,
+};
use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
-use rustc_hir::definitions::DefPathHash;
-use rustc_hir::definitions::Definitions;
+use rustc_hir::definitions::{DefPathHash, DefPathTable};
use rustc_index::vec::{Idx, IndexVec};
use rustc_query_system::dep_graph::DepContext;
use rustc_query_system::query::QueryContext;
pub index: u32,
}
-fn make_local_def_path_hash_map(definitions: &Definitions) -> UnhashMap<DefPathHash, LocalDefId> {
- UnhashMap::from_iter(
- definitions
- .def_path_table()
- .all_def_path_hashes_and_def_ids(LOCAL_CRATE)
- .map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
- )
-}
-
impl<'sess> OnDiskCache<'sess> {
/// Creates a new `OnDiskCache` instance from the serialized data in `data`.
pub fn new(
sess: &'sess Session,
data: Vec<u8>,
start_pos: usize,
- definitions: &Definitions,
+ def_path_table: &DefPathTable,
) -> Self {
debug_assert!(sess.opts.incremental.is_some());
hygiene_context: Default::default(),
foreign_def_path_hashes: footer.foreign_def_path_hashes,
latest_foreign_def_path_hashes: Default::default(),
- local_def_path_hash_to_def_id: make_local_def_path_hash_map(definitions),
+ local_def_path_hash_to_def_id: UnhashMap::from_iter(
+ def_path_table
+ .all_def_path_hashes_and_def_ids(LOCAL_CRATE)
+ .map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
+ ),
def_path_hash_to_def_id_cache: Default::default(),
}
}
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{
hir::place::PlaceBase,
- mir::{self, ClearCrossCrate, Local, LocalDecl, LocalInfo, Location},
+ mir::{self, ClearCrossCrate, Local, LocalDecl, LocalInfo, LocalKind, Location},
};
use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, Symbol};
match label {
Some((true, err_help_span, suggested_code)) => {
- err.span_suggestion(
- err_help_span,
- &format!(
- "consider changing this to be a mutable {}",
- pointer_desc
- ),
- suggested_code,
- Applicability::MachineApplicable,
- );
+ let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
+ if !is_trait_sig {
+ err.span_suggestion(
+ err_help_span,
+ &format!(
+ "consider changing this to be a mutable {}",
+ pointer_desc
+ ),
+ suggested_code,
+ Applicability::MachineApplicable,
+ );
+ } else if let Some(x) = local_trait {
+ err.span_suggestion(
+ x,
+ &format!(
+ "consider changing that to be a mutable {}",
+ pointer_desc
+ ),
+ suggested_code,
+ Applicability::MachineApplicable,
+ );
+ }
}
Some((false, err_label_span, message)) => {
err.span_label(err_label_span, &message);
err.buffer(&mut self.errors_buffer);
}
+ /// User cannot make signature of a trait mutable without changing the
+ /// trait. So we find if this error belongs to a trait and if so we move
+ /// suggestion to the trait or disable it if it is out of scope of this crate
+ fn is_error_in_trait(&self, local: Local) -> (bool, Option<Span>) {
+ if self.body.local_kind(local) != LocalKind::Arg {
+ return (false, None);
+ }
+ let hir_map = self.infcx.tcx.hir();
+ let my_def = self.body.source.def_id();
+ let my_hir = hir_map.local_def_id_to_hir_id(my_def.as_local().unwrap());
+ let td = if let Some(a) =
+ self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
+ {
+ a
+ } else {
+ return (false, None);
+ };
+ (
+ true,
+ td.as_local().and_then(|tld| {
+ let h = hir_map.local_def_id_to_hir_id(tld);
+ match hir_map.find(h) {
+ Some(Node::Item(hir::Item {
+ kind: hir::ItemKind::Trait(_, _, _, _, items),
+ ..
+ })) => {
+ let mut f_in_trait_opt = None;
+ for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
+ let hi = fi.hir_id();
+ if !matches!(k, hir::AssocItemKind::Fn { .. }) {
+ continue;
+ }
+ if hir_map.name(hi) != hir_map.name(my_hir) {
+ continue;
+ }
+ f_in_trait_opt = Some(hi);
+ break;
+ }
+ f_in_trait_opt.and_then(|f_in_trait| match hir_map.find(f_in_trait) {
+ Some(Node::TraitItem(hir::TraitItem {
+ kind:
+ hir::TraitItemKind::Fn(
+ hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
+ _,
+ ),
+ ..
+ })) => {
+ let hir::Ty { span, .. } = inputs[local.index() - 1];
+ Some(span)
+ }
+ _ => None,
+ })
+ }
+ _ => None,
+ }
+ }),
+ )
+ }
+
// point to span of upvar making closure call require mutable borrow
fn show_mutating_upvar(
&self,
for constraint in &constraints {
let OutlivesConstraint { sup, sub, locations, category } = constraint;
let (name, arg) = match locations {
- Locations::All(span) => ("All", tcx.sess.source_map().span_to_string(*span)),
+ Locations::All(span) => {
+ ("All", tcx.sess.source_map().span_to_embeddable_string(*span))
+ }
Locations::Single(loc) => ("Single", format!("{:?}", loc)),
};
with_msg(&format!("{:?}: {:?} due to {:?} at {}({})", sup, sub, category, name, arg))?;
}
if !self.span.is_dummy() {
let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo());
- write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?;
+ write!(
+ f,
+ " at {}:{}:{}",
+ lo.file.name.prefer_local(),
+ lo.line,
+ lo.col.to_usize() + 1
+ )?;
}
Ok(())
})
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
(
- Symbol::intern(&caller.file.name.to_string()),
+ Symbol::intern(&caller.file.name.prefer_remapped().to_string_lossy()),
u32::try_from(caller.line).unwrap(),
u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),
)
// if we applied optimizations, we potentially have some cfg to cleanup to
// make it easier for further passes
if should_simplify {
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
simplify_locals(body, tcx);
}
}
if expn_data.is_root() {
break;
}
- if let ExpnKind::Macro(..) = expn_data.kind {
+ if let ExpnKind::Macro { .. } = expn_data.kind {
body_span = expn_data.call_site;
} else {
break;
debug!(
"instrumenting {:?}, fn sig span: {}, body span: {}",
def_id,
- source_map.span_to_string(fn_sig_span),
- source_map.span_to_string(body_span)
+ source_map.span_to_diagnostic_string(fn_sig_span),
+ source_map.span_to_diagnostic_string(body_span)
);
let mut graphviz_data = debug::GraphvizData::new();
let tcx = self.tcx;
let source_map = tcx.sess.source_map();
let body_span = self.body_span;
- let file_name = Symbol::intern(&self.source_file.name.to_string());
+ let file_name = Symbol::intern(&self.source_file.name.prefer_remapped().to_string_lossy());
let mut bcb_counters = IndexVec::from_elem_n(None, self.basic_coverage_blocks.num_nodes());
for covspan in coverage_spans {
"Calling make_code_region(file_name={}, source_file={:?}, span={}, body_span={})",
file_name,
self.source_file,
- source_map.span_to_string(span),
- source_map.span_to_string(body_span)
+ source_map.span_to_diagnostic_string(span),
+ source_map.span_to_diagnostic_string(body_span)
);
inject_statement(
self.current_macro_or_none
.borrow_mut()
.get_or_insert_with(|| {
- if let ExpnKind::Macro(MacroKind::Bang, current_macro) =
- self.expn_span.ctxt().outer_expn_data().kind
+ if let ExpnKind::Macro {
+ kind: MacroKind::Bang,
+ name: current_macro,
+ proc_macro: _,
+ } = self.expn_span.ctxt().outer_expn_data().kind
{
return Some(current_macro);
}
if has_opts_to_apply {
let mut opt_applier = OptApplier { tcx, duplicates };
opt_applier.visit_body(body);
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
}
}
}
// Since this optimization adds new basic blocks and invalidates others,
// clean up the cfg to make it nicer for other passes
if should_cleanup {
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
}
}
}
// Make sure we remove dead blocks to remove
// unrelated code from the resume part of the function
- simplify::remove_dead_blocks(tcx, &mut body);
+ simplify::remove_dead_blocks(&mut body);
dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(()));
// Make sure we remove dead blocks to remove
// unrelated code from the drop part of the function
- simplify::remove_dead_blocks(tcx, body);
+ simplify::remove_dead_blocks(body);
dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(()));
}
if inline(tcx, body) {
debug!("running simplify cfg on {:?}", body.source);
CfgSimplifier::new(body).simplify();
- remove_dead_blocks(tcx, body);
+ remove_dead_blocks(body);
}
}
}
}
if should_cleanup {
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
}
}
}
}
}
- simplify::remove_dead_blocks(tcx, body)
+ simplify::remove_dead_blocks(body)
}
}
// if we applied optimizations, we potentially have some cfg to cleanup to
// make it easier for further passes
if should_simplify {
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
}
}
}
use crate::transform::MirPass;
use rustc_index::vec::{Idx, IndexVec};
-use rustc_middle::mir::coverage::*;
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
}
}
-pub fn simplify_cfg(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) {
+pub fn simplify_cfg(body: &mut Body<'_>) {
CfgSimplifier::new(body).simplify();
- remove_dead_blocks(tcx, body);
+ remove_dead_blocks(body);
// FIXME: Should probably be moved into some kind of pass manager
body.basic_blocks_mut().raw.shrink_to_fit();
Cow::Borrowed(&self.label)
}
- fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+ fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body.source);
- simplify_cfg(tcx, body);
+ simplify_cfg(body);
}
}
}
}
-pub fn remove_dead_blocks(tcx: TyCtxt<'tcx>, body: &mut Body<'_>) {
+pub fn remove_dead_blocks(body: &mut Body<'_>) {
let reachable = traversal::reachable_as_bitset(body);
let num_blocks = body.basic_blocks().len();
if num_blocks == reachable.count() {
}
used_blocks += 1;
}
-
- if tcx.sess.instrument_coverage() {
- save_unreachable_coverage(basic_blocks, used_blocks);
- }
-
basic_blocks.raw.truncate(used_blocks);
for block in basic_blocks {
}
}
-fn save_unreachable_coverage(
- basic_blocks: &mut IndexVec<BasicBlock, BasicBlockData<'_>>,
- first_dead_block: usize,
-) {
- // retain coverage info for dead blocks, so coverage reports will still
- // report `0` executions for the uncovered code regions.
- let mut dropped_coverage = Vec::new();
- for dead_block in first_dead_block..basic_blocks.len() {
- for statement in basic_blocks[BasicBlock::new(dead_block)].statements.iter() {
- if let StatementKind::Coverage(coverage) = &statement.kind {
- if let Some(code_region) = &coverage.code_region {
- dropped_coverage.push((statement.source_info, code_region.clone()));
- }
- }
- }
- }
- for (source_info, code_region) in dropped_coverage {
- basic_blocks[START_BLOCK].statements.push(Statement {
- source_info,
- kind: StatementKind::Coverage(box Coverage {
- kind: CoverageKind::Unreachable,
- code_region: Some(code_region),
- }),
- })
- }
-}
pub struct SimplifyLocals;
impl<'tcx> MirPass<'tcx> for SimplifyLocals {
if did_remove_blocks {
// We have dead blocks now, so remove those.
- simplify::remove_dead_blocks(tcx, body);
+ simplify::remove_dead_blocks(body);
}
}
}
}
if replaced {
- simplify::remove_dead_blocks(tcx, body);
+ simplify::remove_dead_blocks(body);
}
}
}
ty::Tuple(tys) if tys.is_empty() => {}
_ => {
self.push("mir::Constant");
- self.push(&format!("+ span: {}", self.tcx.sess.source_map().span_to_string(*span)));
+ self.push(&format!(
+ "+ span: {}",
+ self.tcx.sess.source_map().span_to_embeddable_string(*span)
+ ));
if let Some(user_ty) = user_ty {
self.push(&format!("+ user_ty: {:?}", user_ty));
}
}
fn comment(tcx: TyCtxt<'_>, SourceInfo { span, scope }: SourceInfo) -> String {
- format!("scope {} at {}", scope.index(), tcx.sess.source_map().span_to_string(span))
+ format!("scope {} at {}", scope.index(), tcx.sess.source_map().span_to_embeddable_string(span))
}
/// Prints local variables in a scope tree.
"{0:1$} // at {2}",
indented_header,
ALIGN,
- tcx.sess.source_map().span_to_string(span),
+ tcx.sess.source_map().span_to_embeddable_string(span),
)?;
} else {
writeln!(w, "{}", indented_header)?;
"| {:?}: {:?} at {}",
index.index(),
annotation.user_ty,
- tcx.sess.source_map().span_to_string(annotation.span)
+ tcx.sess.source_map().span_to_embeddable_string(annotation.span)
)?;
}
if !body.user_type_annotations.is_empty() {
) -> String {
let source_map = tcx.sess.source_map();
let mut text = Vec::new();
- text.push(format!("{}: {}:", spanview_id, &source_map.span_to_string(span)));
+ text.push(format!("{}: {}:", spanview_id, &source_map.span_to_embeddable_string(span)));
for statement in statements {
let source_range = source_range_no_file(tcx, &statement.source_info.span);
text.push(format!(
override_span: Option<Span>,
) -> Result<(TokenStream, Vec<lexer::UnmatchedBrace>), Vec<Diagnostic>> {
let src = source_file.src.as_ref().unwrap_or_else(|| {
- sess.span_diagnostic
- .bug(&format!("cannot lex `source_file` without source: {}", source_file.name));
+ sess.span_diagnostic.bug(&format!(
+ "cannot lex `source_file` without source: {}",
+ source_file.name.prefer_local()
+ ));
});
let (token_trees, unmatched_braces) =
Ok(a_var)
}
+ fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
+ if let Err(mut err) = self.expect(&token::Colon) {
+ let sm = self.sess.source_map();
+ let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start());
+ let semi_typo = self.token.kind == token::Semi
+ && self.look_ahead(1, |t| {
+ t.is_path_start()
+ // We check that we are in a situation like `foo; bar` to avoid bad suggestions
+ // when there's no type and `;` was used instead of a comma.
+ && match (sm.lookup_line(self.token.span.hi()), sm.lookup_line(t.span.lo())) {
+ (Ok(l), Ok(r)) => l.line == r.line,
+ _ => true,
+ }
+ });
+ if eq_typo || semi_typo {
+ self.bump();
+ // Gracefully handle small typos.
+ err.span_suggestion_short(
+ self.prev_token.span,
+ "field names and their types are separated with `:`",
+ ":".to_string(),
+ Applicability::MachineApplicable,
+ );
+ err.emit();
+ } else {
+ return Err(err);
+ }
+ }
+ Ok(())
+ }
+
/// Parses a structure field.
fn parse_name_and_ty(
&mut self,
attrs: Vec<Attribute>,
) -> PResult<'a, FieldDef> {
let name = self.parse_field_ident(adt_ty, lo)?;
- self.expect(&token::Colon)?;
+ self.expect_field_ty_separator()?;
let ty = self.parse_ty()?;
+ if self.token.kind == token::Eq {
+ self.bump();
+ let const_expr = self.parse_anon_const_expr()?;
+ let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
+ self.struct_span_err(sp, "default values on `struct` fields aren't supported")
+ .span_suggestion(
+ sp,
+ "remove this unsupported default value",
+ String::new(),
+ Applicability::MachineApplicable,
+ )
+ .emit();
+ }
Ok(FieldDef {
span: lo.to(self.prev_token.span),
ident: Some(name),
fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
let sm = tcx.sess.source_map();
match lnk {
- UpvarNode(s) => format!("Upvar node [{}]", sm.span_to_string(s)),
- ExprNode(s) => format!("Expr node [{}]", sm.span_to_string(s)),
- VarDefNode(s) => format!("Var def node [{}]", sm.span_to_string(s)),
+ UpvarNode(s) => format!("Upvar node [{}]", sm.span_to_diagnostic_string(s)),
+ ExprNode(s) => format!("Expr node [{}]", sm.span_to_diagnostic_string(s)),
+ VarDefNode(s) => format!("Var def node [{}]", sm.span_to_diagnostic_string(s)),
ClosureNode => "Closure node".to_owned(),
ExitNode => "Exit node".to_owned(),
}
debug!(
"visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})",
owner_id,
- self.tcx.sess.source_map().span_to_string(body.value.span),
+ self.tcx.sess.source_map().span_to_diagnostic_string(body.value.span),
body_id,
self.cx.parent
);
None => return,
};
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
- self.tcx.check_stability(def_id, Some(item.hir_id()), item.span);
+ self.tcx.check_stability(def_id, Some(item.hir_id()), item.span, None);
}
// For implementations of traits, check the stability of each item
.map(|item| item.def_id);
if let Some(def_id) = trait_item_def_id {
// Pass `None` to skip deprecation warnings.
- self.tcx.check_stability(def_id, None, impl_item.span);
+ self.tcx.check_stability(def_id, None, impl_item.span, None);
}
}
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
- self.tcx.check_stability(def_id, Some(id), path.span)
+ self.tcx.check_stability(def_id, Some(id), path.span, None)
}
intravisit::walk_path(self, path)
}
use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot};
use rustc_ast::walk_list;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefIdMap;
+use rustc_hir::def_id::{DefIdMap, LocalDefId};
use rustc_hir::hir_id::ItemLocalId;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
-use rustc_span::def_id::{DefId, LocalDefId};
+use rustc_span::def_id::DefId;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use std::borrow::Cow;
// - trait refs
// - bound types (like `T` in `for<'a> T<'a>: Foo`)
late_bound_vars: HirIdMap<Vec<ty::BoundVariableKind>>,
+
+ // maps `PathSegment` `HirId`s to lifetime scopes.
+ scope_for_path: Option<FxHashMap<LocalDefId, FxHashMap<ItemLocalId, LifetimeScopeForPath>>>,
}
crate struct LifetimeContext<'a, 'tcx> {
/// it should be shifted by the number of `Binder`s in between the
/// declaration `Binder` and the location it's referenced from.
Binder {
- lifetimes: FxHashMap<hir::ParamName, Region>,
+ /// We use an IndexMap here because we want these lifetimes in order
+ /// for diagnostics.
+ lifetimes: FxIndexMap<hir::ParamName, Region>,
/// if we extend this scope with another scope, what is the next index
/// we should use for an early-bound region?
}
},
late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
+ lifetime_scope_map: |tcx, id| {
+ let item_id = item_for(tcx, id);
+ do_resolve(tcx, item_id, false, true).scope_for_path.unwrap().remove(&id)
+ },
..*providers
};
tcx: TyCtxt<'_>,
local_def_id: LocalDefId,
) -> ResolveLifetimes {
- do_resolve(tcx, local_def_id, true)
+ convert_named_region_map(do_resolve(tcx, local_def_id, true, false))
}
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
/// `named_region_map`, `is_late_bound_map`, etc.
#[tracing::instrument(level = "debug", skip(tcx))]
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
- do_resolve(tcx, local_def_id, false)
+ convert_named_region_map(do_resolve(tcx, local_def_id, false, false))
}
fn do_resolve(
tcx: TyCtxt<'_>,
local_def_id: LocalDefId,
trait_definition_only: bool,
-) -> ResolveLifetimes {
+ with_scope_for_path: bool,
+) -> NamedRegionMap {
let item = tcx.hir().expect_item(tcx.hir().local_def_id_to_hir_id(local_def_id));
let mut named_region_map = NamedRegionMap {
defs: Default::default(),
late_bound: Default::default(),
late_bound_vars: Default::default(),
+ scope_for_path: with_scope_for_path.then(|| Default::default()),
};
let mut visitor = LifetimeContext {
tcx,
};
visitor.visit_item(item);
+ named_region_map
+}
+
+fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes {
let mut rl = ResolveLifetimes::default();
for (hir_id, v) in named_region_map.defs {
}
}
+#[tracing::instrument(level = "debug")]
+fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath {
+ let mut available_lifetimes = vec![];
+ loop {
+ match scope {
+ Scope::Binder { lifetimes, s, .. } => {
+ available_lifetimes.extend(lifetimes.keys().filter_map(|p| match p {
+ hir::ParamName::Plain(ident) => Some(ident.name.to_string()),
+ _ => None,
+ }));
+ scope = s;
+ }
+ Scope::Body { s, .. } => {
+ scope = s;
+ }
+ Scope::Elision { elide, s } => {
+ if let Elide::Exact(_) = elide {
+ return LifetimeScopeForPath::Elided;
+ } else {
+ scope = s;
+ }
+ }
+ Scope::ObjectLifetimeDefault { s, .. } => {
+ scope = s;
+ }
+ Scope::Root => {
+ return LifetimeScopeForPath::NonElided(available_lifetimes);
+ }
+ Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } => {
+ scope = s;
+ }
+ }
+ }
+}
+
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
/// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
fn poly_trait_ref_binder_info(&mut self) -> (Vec<ty::BoundVariableKind>, BinderScopeType) {
self.map.late_bound_vars.insert(hir_id, vec![]);
let scope = Scope::Binder {
hir_id,
- lifetimes: FxHashMap::default(),
+ lifetimes: FxIndexMap::default(),
next_early_index: self.next_early_index(),
s: self.scope,
track_lifetime_uses: true,
// We need to add *all* deps, since opaque tys may want them from *us*
for (&owner, defs) in resolved_lifetimes.defs.iter() {
defs.iter().for_each(|(&local_id, region)| {
- self.map
- .defs
- .insert(hir::HirId { owner, local_id }, region.clone());
+ self.map.defs.insert(hir::HirId { owner, local_id }, *region);
});
}
for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
};
self.missing_named_lifetime_spots
.push(MissingLifetimeSpot::HigherRanked { span, span_type });
- let (lifetimes, binders): (FxHashMap<hir::ParamName, Region>, Vec<_>) = c
+ let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) = c
.generic_params
.iter()
.filter_map(|param| match param.kind {
debug!(?index);
let mut elision = None;
- let mut lifetimes = FxHashMap::default();
+ let mut lifetimes = FxIndexMap::default();
let mut non_lifetime_count = 0;
for param in generics.params {
match param.kind {
let mut index = self.next_early_index();
let mut non_lifetime_count = 0;
debug!("visit_ty: index = {}", index);
- let lifetimes: FxHashMap<hir::ParamName, Region> = generics
+ let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
.params
.iter()
.filter_map(|param| match param.kind {
self.resolve_lifetime_ref(lifetime_ref);
}
+ fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) {
+ let scope = self.scope;
+ if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
+ // We add lifetime scope information for `Ident`s in associated type bindings and use
+ // the `HirId` of the type binding as the key in `LifetimeMap`
+ let lifetime_scope = get_lifetime_scopes_for_path(scope);
+ let map = scope_for_path.entry(type_binding.hir_id.owner).or_default();
+ map.insert(type_binding.hir_id.local_id, lifetime_scope);
+ }
+ hir::intravisit::walk_assoc_type_binding(self, type_binding);
+ }
+
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
for (i, segment) in path.segments.iter().enumerate() {
let depth = path.segments.len() - i - 1;
if let Some(ref args) = segment.args {
self.visit_segment_args(path.res, depth, args);
}
+
+ let scope = self.scope;
+ if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
+ // Add lifetime scope information to path segment. Note we cannot call `visit_path_segment`
+ // here because that call would yield to resolution problems due to `walk_path_segment`
+ // being called, which processes the path segments generic args, which we have already
+ // processed using `visit_segment_args`.
+ let lifetime_scope = get_lifetime_scopes_for_path(scope);
+ if let Some(hir_id) = segment.hir_id {
+ let map = scope_for_path.entry(hir_id.owner).or_default();
+ map.insert(hir_id.local_id, lifetime_scope);
+ }
+ }
}
}
+ fn visit_path_segment(&mut self, path_span: Span, path_segment: &'tcx hir::PathSegment<'tcx>) {
+ let scope = self.scope;
+ if let Some(scope_for_path) = self.map.scope_for_path.as_mut() {
+ let lifetime_scope = get_lifetime_scopes_for_path(scope);
+ if let Some(hir_id) = path_segment.hir_id {
+ let map = scope_for_path.entry(hir_id.owner).or_default();
+ map.insert(hir_id.local_id, lifetime_scope);
+ }
+ }
+
+ intravisit::walk_path_segment(self, path_span, path_segment);
+ }
+
fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
let output = match fd.output {
hir::FnRetTy::DefaultReturn(_) => None,
ref bound_generic_params,
..
}) => {
- let (lifetimes, binders): (FxHashMap<hir::ParamName, Region>, Vec<_>) =
+ let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) =
bound_generic_params
.iter()
.filter_map(|param| match param.kind {
self.map.late_bound_vars.insert(*hir_id, binders);
let scope = Scope::Binder {
hir_id: *hir_id,
- lifetimes: FxHashMap::default(),
+ lifetimes: FxIndexMap::default(),
s: self.scope,
next_early_index: self.next_early_index(),
track_lifetime_uses: true,
let (mut binders, scope_type) = self.poly_trait_ref_binder_info();
let initial_bound_vars = binders.len() as u32;
- let mut lifetimes: FxHashMap<hir::ParamName, Region> = FxHashMap::default();
+ let mut lifetimes: FxIndexMap<hir::ParamName, Region> = FxIndexMap::default();
let binders_iter = trait_ref
.bound_generic_params
.iter()
let mut non_lifetime_count = 0;
let mut named_late_bound_vars = 0;
- let lifetimes: FxHashMap<hir::ParamName, Region> = generics
+ let lifetimes: FxIndexMap<hir::ParamName, Region> = generics
.params
.iter()
.filter_map(|param| match param.kind {
}
};
+ // If we specifically need the `scope_for_path` map, then we're in the
+ // diagnostic pass and we don't want to emit more errors.
+ if self.map.scope_for_path.is_some() {
+ self.tcx.sess.delay_span_bug(
+ rustc_span::DUMMY_SP,
+ "Encountered unexpected errors during diagnostics related part",
+ );
+ return;
+ }
+
let mut spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect();
spans.sort();
let mut spans_dedup = spans.clone();
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
debug!(
node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
- span = ?self.tcx.sess.source_map().span_to_string(lifetime_ref.span)
+ span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
);
self.map.defs.insert(lifetime_ref.hir_id, def);
let expn_data = expn_id.expn_data();
match expn_data.kind {
ExpnKind::Root
- | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
- Scope::DeriveHelpersCompat
- }
+ | ExpnKind::Macro {
+ kind: MacroKind::Bang | MacroKind::Derive,
+ name: _,
+ proc_macro: _,
+ } => Scope::DeriveHelpersCompat,
_ => Scope::DeriveHelpers(expn_data.parent),
}
}
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
use rustc_feature::is_builtin_attr_name;
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
-use rustc_hir::def_id;
+use rustc_hir::def_id::{self, CrateNum};
use rustc_hir::PrimTy;
use rustc_middle::middle::stability;
use rustc_middle::ty;
let expn_data = expn_id.expn_data();
match expn_data.kind {
ExpnKind::Root
- | ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
+ | ExpnKind::Macro {
+ name: _,
+ kind: MacroKind::Bang | MacroKind::Derive,
+ proc_macro: _,
+ } => {
break;
}
_ => expn_id = expn_data.parent,
.emit();
Ok(false)
}
+
+ fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
+ self.crate_loader.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.session)
+ }
}
impl<'a> Resolver<'a> {
};
let data = CompilationOptions {
- directory: self.tcx.sess.working_dir.0.clone(),
+ directory: self.tcx.sess.working_dir.remapped_path_if_available().into(),
program,
arguments,
output: self.save_ctxt.compilation_output(crate_name),
name: String::new(),
qualname,
span,
- value: filename.to_string(),
+ value: filename.prefer_remapped().to_string(),
children,
parent: None,
decl_id: None,
let end = sm.lookup_char_pos(span.hi());
SpanData {
- file_name: start.file.name.to_string().into(),
+ file_name: start.file.name.prefer_remapped().to_string().into(),
byte_start: span.lo().0,
byte_end: span.hi().0,
line_start: Row::new_one_indexed(start.line as u32),
name: item.ident.to_string(),
qualname,
span: self.span_from_span(item.ident.span),
- value: filename.to_string(),
+ value: filename.prefer_remapped().to_string(),
parent: None,
children: m
.item_ids
let callee = span.source_callee()?;
let mac_name = match callee.kind {
- ExpnKind::Macro(kind, name) => match kind {
+ ExpnKind::Macro { kind, name, proc_macro: _ } => match kind {
MacroKind::Bang => name,
// Ignore attribute macros, their spans are usually mangled
pub fn make_filename_string(&self, file: &SourceFile) -> String {
match &file.name {
- FileName::Real(name) if !file.name_was_remapped => {
- let path = name.local_path();
+ FileName::Real(RealFileName::LocalPath(path)) => {
if path.is_absolute() {
self.sess
.source_map()
.display()
.to_string()
} else {
- self.sess.working_dir.0.join(&path).display().to_string()
+ self.sess
+ .working_dir
+ .remapped_path_if_available()
+ .join(&path)
+ .display()
+ .to_string()
}
}
- // If the file name is already remapped, we assume the user
- // configured it the way they wanted to, so use that directly
- filename => filename.to_string(),
+ filename => filename.prefer_remapped().to_string(),
}
}
true
}
- crate fn parse_linker_flavor(slote: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
+ crate fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
match v.and_then(LinkerFlavor::from_str) {
- Some(lf) => *slote = Some(lf),
+ Some(lf) => *slot = Some(lf),
_ => return false,
}
true
"whether ELF relocations can be relaxed"),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
"choose which RELRO level to use"),
+ simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
+ "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
+ to rust's source base directory. only meant for testing purposes"),
report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
"immediately print bugs registered with `delay_span_bug` (default: no)"),
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
pub type_ascription_path_suggestions: Lock<FxHashSet<Span>>,
/// Whether cfg(version) should treat the current release as incomplete
pub assume_incomplete_release: bool,
+ /// Spans passed to `proc_macro::quote_span`. Each span has a numerical
+ /// identifier represented by its position in the vector.
+ pub proc_macro_quoted_spans: Lock<Vec<Span>>,
}
impl ParseSess {
env_depinfo: Default::default(),
type_ascription_path_suggestions: Default::default(),
assume_incomplete_release: false,
+ proc_macro_quoted_spans: Default::default(),
}
}
);
}
}
+
+ pub fn save_proc_macro_span(&self, span: Span) -> usize {
+ let mut spans = self.proc_macro_quoted_spans.lock();
+ spans.push(span);
+ return spans.len() - 1;
+ }
+
+ pub fn proc_macro_quoted_spans(&self) -> Vec<Span> {
+ self.proc_macro_quoted_spans.lock().clone()
+ }
}
use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_lint_defs::FutureBreakage;
pub use rustc_span::crate_disambiguator::CrateDisambiguator;
-use rustc_span::edition::Edition;
use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
+use rustc_span::{edition::Edition, RealFileName};
use rustc_span::{sym, SourceFileHashAlgorithm, Symbol};
use rustc_target::asm::InlineAsmArch;
use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel};
/// The name of the root source file of the crate, in the local file system.
/// `None` means that there is no source file.
pub local_crate_source_file: Option<PathBuf>,
- /// The directory the compiler has been executed in plus a flag indicating
- /// if the value stored here has been affected by path remapping.
- pub working_dir: (PathBuf, bool),
+ /// The directory the compiler has been executed in
+ pub working_dir: RealFileName,
/// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
/// (sub)diagnostics that have been set once, but should not be set again,
let working_dir = env::current_dir().unwrap_or_else(|e| {
parse_sess.span_diagnostic.fatal(&format!("Current directory is invalid: {}", e)).raise()
});
- let working_dir = file_path_mapping.map_prefix(working_dir);
+ let (path, remapped) = file_path_mapping.map_prefix(working_dir.clone());
+ let working_dir = if remapped {
+ RealFileName::Remapped { local_path: Some(working_dir), virtual_name: path }
+ } else {
+ RealFileName::LocalPath(path)
+ };
let cgu_reuse_tracker = if sopts.debugging_opts.query_dep_graph {
CguReuseTracker::new()
InvalidBecauseOfErrors { session_directory: PathBuf },
}
-pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
+pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) {
let emitter: Box<dyn Emitter + sync::Send> = match output {
config::ErrorOutputType::HumanReadable(kind) => {
let (short, color_config) = kind.unzip();
};
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
handler.struct_fatal(msg).emit();
+}
+
+pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
+ early_error_no_abort(output, msg);
rustc_errors::FatalError.raise();
}
let expn_data = self.expn_data();
// Stop going up the backtrace once include! is encountered
if expn_data.is_root()
- || expn_data.kind == ExpnKind::Macro(MacroKind::Bang, sym::include)
+ || matches!(
+ expn_data.kind,
+ ExpnKind::Macro { kind: MacroKind::Bang, name: sym::include, proc_macro: _ }
+ )
{
break;
}
/// No expansion, aka root expansion. Only `ExpnId::root()` has this kind.
Root,
/// Expansion produced by a macro.
- Macro(MacroKind, Symbol),
+ Macro {
+ kind: MacroKind,
+ name: Symbol,
+ /// If `true`, this macro is a procedural macro. This
+ /// flag is only used for diagnostic purposes
+ proc_macro: bool,
+ },
/// Transform done by the compiler on the AST.
AstPass(AstPass),
/// Desugaring done by the compiler during HIR lowering.
pub fn descr(&self) -> String {
match *self {
ExpnKind::Root => kw::PathRoot.to_string(),
- ExpnKind::Macro(macro_kind, name) => match macro_kind {
+ ExpnKind::Macro { kind, name, proc_macro: _ } => match kind {
MacroKind::Bang => format!("{}!", name),
MacroKind::Attr => format!("#[{}]", name),
MacroKind::Derive => format!("#[derive({})]", name),
// deserialization.
scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
-// FIXME: Perhaps this should not implement Rustc{Decodable, Encodable}
-//
// FIXME: We should use this enum or something like it to get rid of the
// use of magic `/rust/1.x/...` paths across the board.
-#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
-#[derive(HashStable_Generic, Decodable, Encodable)]
+#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd)]
+#[derive(HashStable_Generic, Decodable)]
pub enum RealFileName {
- Named(PathBuf),
- /// For de-virtualized paths (namely paths into libstd that have been mapped
- /// to the appropriate spot on the local host's file system),
- Devirtualized {
- /// `local_path` is the (host-dependent) local path to the file.
- local_path: PathBuf,
+ LocalPath(PathBuf),
+ /// For remapped paths (namely paths into libstd that have been mapped
+ /// to the appropriate spot on the local host's file system, and local file
+ /// system paths that have been remapped with `FilePathMapping`),
+ Remapped {
+ /// `local_path` is the (host-dependent) local path to the file. This is
+ /// None if the file was imported from another crate
+ local_path: Option<PathBuf>,
/// `virtual_name` is the stable path rustc will store internally within
/// build artifacts.
virtual_name: PathBuf,
},
}
+impl Hash for RealFileName {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ // To prevent #70924 from happening again we should only hash the
+ // remapped (virtualized) path if that exists. This is because
+ // virtualized paths to sysroot crates (/rust/$hash or /rust/$version)
+ // remain stable even if the corresponding local_path changes
+ self.remapped_path_if_available().hash(state)
+ }
+}
+
+// This is functionally identical to #[derive(Encodable)], with the exception of
+// an added assert statement
+impl<S: Encoder> Encodable<S> for RealFileName {
+ fn encode(&self, encoder: &mut S) -> Result<(), S::Error> {
+ encoder.emit_enum("RealFileName", |encoder| match *self {
+ RealFileName::LocalPath(ref local_path) => {
+ encoder.emit_enum_variant("LocalPath", 0, 1, |encoder| {
+ Ok({
+ encoder.emit_enum_variant_arg(0, |encoder| local_path.encode(encoder))?;
+ })
+ })
+ }
+
+ RealFileName::Remapped { ref local_path, ref virtual_name } => encoder
+ .emit_enum_variant("Remapped", 1, 2, |encoder| {
+ // For privacy and build reproducibility, we must not embed host-dependant path in artifacts
+ // if they have been remapped by --remap-path-prefix
+ assert!(local_path.is_none());
+ Ok({
+ encoder.emit_enum_variant_arg(0, |encoder| local_path.encode(encoder))?;
+ encoder.emit_enum_variant_arg(1, |encoder| virtual_name.encode(encoder))?;
+ })
+ }),
+ })
+ }
+}
+
impl RealFileName {
- /// Returns the path suitable for reading from the file system on the local host.
- /// Avoid embedding this in build artifacts; see `stable_name()` for that.
- pub fn local_path(&self) -> &Path {
+ /// Returns the path suitable for reading from the file system on the local host,
+ /// if this information exists.
+ /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that.
+ pub fn local_path(&self) -> Option<&Path> {
+ match self {
+ RealFileName::LocalPath(p) => Some(p),
+ RealFileName::Remapped { local_path: p, virtual_name: _ } => {
+ p.as_ref().map(PathBuf::as_path)
+ }
+ }
+ }
+
+ /// Returns the path suitable for reading from the file system on the local host,
+ /// if this information exists.
+ /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that.
+ pub fn into_local_path(self) -> Option<PathBuf> {
match self {
- RealFileName::Named(p)
- | RealFileName::Devirtualized { local_path: p, virtual_name: _ } => &p,
+ RealFileName::LocalPath(p) => Some(p),
+ RealFileName::Remapped { local_path: p, virtual_name: _ } => p,
}
}
- /// Returns the path suitable for reading from the file system on the local host.
- /// Avoid embedding this in build artifacts; see `stable_name()` for that.
- pub fn into_local_path(self) -> PathBuf {
+ /// Returns the path suitable for embedding into build artifacts. This would still
+ /// be a local path if it has not been remapped. A remapped path will not correspond
+ /// to a valid file system path: see `local_path_if_available()` for something that
+ /// is more likely to return paths into the local host file system.
+ pub fn remapped_path_if_available(&self) -> &Path {
match self {
- RealFileName::Named(p)
- | RealFileName::Devirtualized { local_path: p, virtual_name: _ } => p,
+ RealFileName::LocalPath(p)
+ | RealFileName::Remapped { local_path: _, virtual_name: p } => &p,
}
}
- /// Returns the path suitable for embedding into build artifacts. Note that
- /// a virtualized path will not correspond to a valid file system path; see
- /// `local_path()` for something that is more likely to return paths into the
- /// local host file system.
- pub fn stable_name(&self) -> &Path {
+ /// Returns the path suitable for reading from the file system on the local host,
+ /// if this information exists. Otherwise returns the remapped name.
+ /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that.
+ pub fn local_path_if_available(&self) -> &Path {
match self {
- RealFileName::Named(p)
- | RealFileName::Devirtualized { local_path: _, virtual_name: p } => &p,
+ RealFileName::LocalPath(path)
+ | RealFileName::Remapped { local_path: None, virtual_name: path }
+ | RealFileName::Remapped { local_path: Some(path), virtual_name: _ } => path,
+ }
+ }
+
+ pub fn to_string_lossy(&self, prefer_local: bool) -> Cow<'_, str> {
+ if prefer_local {
+ self.local_path_if_available().to_string_lossy()
+ } else {
+ self.remapped_path_if_available().to_string_lossy()
}
}
}
InlineAsm(u64),
}
-impl std::fmt::Display for FileName {
+impl From<PathBuf> for FileName {
+ fn from(p: PathBuf) -> Self {
+ assert!(!p.to_string_lossy().ends_with('>'));
+ FileName::Real(RealFileName::LocalPath(p))
+ }
+}
+
+pub struct FileNameDisplay<'a> {
+ inner: &'a FileName,
+ prefer_local: bool,
+}
+
+impl fmt::Display for FileNameDisplay<'_> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use FileName::*;
- match *self {
- Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()),
- // FIXME: might be nice to display both components of Devirtualized.
- // But for now (to backport fix for issue #70924), best to not
- // perturb diagnostics so its obvious test suite still works.
- Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => {
- write!(fmt, "{}", local_path.display())
+ match *self.inner {
+ Real(ref name) => {
+ write!(fmt, "{}", name.to_string_lossy(self.prefer_local))
}
QuoteExpansion(_) => write!(fmt, "<quote expansion>"),
MacroExpansion(_) => write!(fmt, "<macro expansion>"),
}
}
-impl From<PathBuf> for FileName {
- fn from(p: PathBuf) -> Self {
- assert!(!p.to_string_lossy().ends_with('>'));
- FileName::Real(RealFileName::Named(p))
+impl FileNameDisplay<'_> {
+ pub fn to_string_lossy(&self) -> Cow<'_, str> {
+ match self.inner {
+ FileName::Real(ref inner) => inner.to_string_lossy(self.prefer_local),
+ _ => Cow::from(format!("{}", self)),
+ }
}
}
}
}
+ pub fn prefer_remapped(&self) -> FileNameDisplay<'_> {
+ FileNameDisplay { inner: self, prefer_local: false }
+ }
+
+ // This may include transient local filesystem information.
+ // Must not be embedded in build outputs.
+ pub fn prefer_local(&self) -> FileNameDisplay<'_> {
+ FileNameDisplay { inner: self, prefer_local: true }
+ }
+
pub fn macro_expansion_source_code(src: &str) -> FileName {
let mut hasher = StableHasher::new();
src.hash(&mut hasher);
/// Returns `true` if `span` originates in a derive-macro's expansion.
pub fn in_derive_expansion(self) -> bool {
- matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
+ matches!(
+ self.ctxt().outer_expn_data().kind,
+ ExpnKind::Macro { kind: MacroKind::Derive, name: _, proc_macro: _ }
+ )
}
#[inline]
f: &mut fmt::Formatter<'_>,
source_map: &SourceMap,
) -> fmt::Result {
- write!(f, "{} ({:?})", source_map.span_to_string(span), span.ctxt())
+ write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(span), span.ctxt())
}
pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// originate from files has names between angle brackets by convention
/// (e.g., `<anon>`).
pub name: FileName,
- /// `true` if the `name` field above has been modified by `--remap-path-prefix`.
- pub name_was_remapped: bool,
- /// The unmapped path of the file that the source came from.
- /// Set to `None` if the `SourceFile` was imported from an external crate.
- pub unmapped_path: Option<FileName>,
/// The complete source code.
pub src: Option<Lrc<String>>,
/// The source code's hash.
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SourceFile", 8, |s| {
s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
- s.emit_struct_field("name_was_remapped", 1, |s| self.name_was_remapped.encode(s))?;
s.emit_struct_field("src_hash", 2, |s| self.src_hash.encode(s))?;
s.emit_struct_field("start_pos", 3, |s| self.start_pos.encode(s))?;
s.emit_struct_field("end_pos", 4, |s| self.end_pos.encode(s))?;
fn decode(d: &mut D) -> Result<SourceFile, D::Error> {
d.read_struct("SourceFile", 8, |d| {
let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?;
- let name_was_remapped: bool =
- d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?;
let src_hash: SourceFileHash =
d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?;
let start_pos: BytePos =
let cnum: CrateNum = d.read_struct_field("cnum", 10, |d| Decodable::decode(d))?;
Ok(SourceFile {
name,
- name_was_remapped,
- unmapped_path: None,
start_pos,
end_pos,
src: None,
impl fmt::Debug for SourceFile {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(fmt, "SourceFile({})", self.name)
+ write!(fmt, "SourceFile({:?})", self.name)
}
}
impl SourceFile {
pub fn new(
name: FileName,
- name_was_remapped: bool,
- unmapped_path: FileName,
mut src: String,
start_pos: BytePos,
hash_kind: SourceFileHashAlgorithm,
SourceFile {
name,
- name_was_remapped,
- unmapped_path: Some(unmapped_path),
src: Some(Lrc::new(src)),
src_hash,
external_src: Lock::new(ExternalSource::Unneeded),
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock};
-use std::cmp;
-use std::convert::TryFrom;
use std::hash::Hash;
use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;
+use std::{clone::Clone, cmp};
+use std::{convert::TryFrom, unreachable};
use std::fs;
use std::io;
// StableSourceFileId, perhaps built atop source_file.name_hash.
impl StableSourceFileId {
pub fn new(source_file: &SourceFile) -> StableSourceFileId {
- StableSourceFileId::new_from_pieces(
- &source_file.name,
- source_file.name_was_remapped,
- source_file.unmapped_path.as_ref(),
- )
+ StableSourceFileId::new_from_name(&source_file.name)
}
- fn new_from_pieces(
- name: &FileName,
- name_was_remapped: bool,
- unmapped_path: Option<&FileName>,
- ) -> StableSourceFileId {
+ fn new_from_name(name: &FileName) -> StableSourceFileId {
let mut hasher = StableHasher::new();
- if let FileName::Real(real_name) = name {
- // rust-lang/rust#70924: Use the stable (virtualized) name when
- // available. (We do not want artifacts from transient file system
- // paths for libstd to leak into our build artifacts.)
- real_name.stable_name().hash(&mut hasher)
- } else {
- name.hash(&mut hasher);
- }
- name_was_remapped.hash(&mut hasher);
- unmapped_path.hash(&mut hasher);
+ name.hash(&mut hasher);
StableSourceFileId(hasher.finish())
}
fn try_new_source_file(
&self,
- mut filename: FileName,
+ filename: FileName,
src: String,
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
- // The path is used to determine the directory for loading submodules and
- // include files, so it must be before remapping.
// Note that filename may not be a valid path, eg it may be `<anon>` etc,
// but this is okay because the directory determined by `path.pop()` will
// be empty, so the working directory will be used.
- let unmapped_path = filename.clone();
-
- let was_remapped;
- if let FileName::Real(real_filename) = &mut filename {
- match real_filename {
- RealFileName::Named(path_to_be_remapped)
- | RealFileName::Devirtualized {
- local_path: path_to_be_remapped,
- virtual_name: _,
- } => {
- let mapped = self.path_mapping.map_prefix(path_to_be_remapped.clone());
- was_remapped = mapped.1;
- *path_to_be_remapped = mapped.0;
- }
- }
- } else {
- was_remapped = false;
- }
+ let (filename, _) = self.path_mapping.map_filename_prefix(&filename);
- let file_id =
- StableSourceFileId::new_from_pieces(&filename, was_remapped, Some(&unmapped_path));
+ let file_id = StableSourceFileId::new_from_name(&filename);
let lrc_sf = match self.source_file_by_stable_id(file_id) {
Some(lrc_sf) => lrc_sf,
let source_file = Lrc::new(SourceFile::new(
filename,
- was_remapped,
- unmapped_path,
src,
Pos::from_usize(start_pos),
self.hash_kind,
pub fn new_imported_source_file(
&self,
filename: FileName,
- name_was_remapped: bool,
src_hash: SourceFileHash,
name_hash: u128,
source_len: usize,
let source_file = Lrc::new(SourceFile {
name: filename,
- name_was_remapped,
- unmapped_path: None,
src: None,
src_hash,
external_src: Lock::new(ExternalSource::Foreign {
source_file
}
- pub fn mk_substr_filename(&self, sp: Span) -> String {
- let pos = self.lookup_char_pos(sp.lo());
- format!("<{}:{}:{}>", pos.file.name, pos.line, pos.col.to_usize() + 1)
- }
-
// If there is a doctest offset, applies it to the line.
pub fn doctest_offset_line(&self, file: &FileName, orig: usize) -> usize {
match file {
}
}
- pub fn span_to_string(&self, sp: Span) -> String {
+ fn span_to_string(&self, sp: Span, prefer_local: bool) -> String {
if self.files.borrow().source_files.is_empty() && sp.is_dummy() {
return "no-location".to_string();
}
let hi = self.lookup_char_pos(sp.hi());
format!(
"{}:{}:{}: {}:{}",
- lo.file.name,
+ if prefer_local { lo.file.name.prefer_local() } else { lo.file.name.prefer_remapped() },
lo.line,
lo.col.to_usize() + 1,
hi.line,
)
}
- pub fn span_to_filename(&self, sp: Span) -> FileName {
- self.lookup_char_pos(sp.lo()).file.name.clone()
+ /// Format the span location suitable for embedding in build artifacts
+ pub fn span_to_embeddable_string(&self, sp: Span) -> String {
+ self.span_to_string(sp, false)
+ }
+
+ /// Format the span location to be printed in diagnostics. Must not be emitted
+ /// to build artifacts as this may leak local file paths. Use span_to_embeddable_string
+ /// for string suitable for embedding.
+ pub fn span_to_diagnostic_string(&self, sp: Span) -> String {
+ self.span_to_string(sp, true)
}
- pub fn span_to_unmapped_path(&self, sp: Span) -> FileName {
- self.lookup_char_pos(sp.lo())
- .file
- .unmapped_path
- .clone()
- .expect("`SourceMap::span_to_unmapped_path` called for imported `SourceFile`?")
+ pub fn span_to_filename(&self, sp: Span) -> FileName {
+ self.lookup_char_pos(sp.lo()).file.name.clone()
}
pub fn is_multiline(&self, sp: Span) -> bool {
}
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
source_file.add_external_src(|| match source_file.name {
- FileName::Real(ref name) => self.file_loader.read_file(name.local_path()).ok(),
+ FileName::Real(ref name) => {
+ if let Some(local_path) = name.local_path() {
+ self.file_loader.read_file(local_path).ok()
+ } else {
+ None
+ }
+ }
_ => None,
})
}
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
match file {
FileName::Real(realfile) => {
- let path = realfile.local_path();
- let (path, mapped) = self.map_prefix(path.to_path_buf());
- (FileName::Real(RealFileName::Named(path)), mapped)
+ if let RealFileName::LocalPath(local_path) = realfile {
+ let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
+ let realfile = if mapped {
+ RealFileName::Remapped {
+ local_path: Some(local_path.clone()),
+ virtual_name: mapped_path,
+ }
+ } else {
+ realfile.clone()
+ };
+ (FileName::Real(realfile), mapped)
+ } else {
+ unreachable!("attempted to remap an already remapped filename");
+ }
}
other => (other.clone(), false),
}
fn t9() {
let sm = init_source_map();
let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
- let sstr = sm.span_to_string(span);
+ let sstr = sm.span_to_diagnostic_string(span);
assert_eq!(sstr, "blork.rs:2:1: 2:12");
}
let SourceFile {
name,
- name_was_remapped,
src_hash,
start_pos,
end_pos,
let imported_src_file = sm.new_imported_source_file(
name,
- name_was_remapped,
src_hash,
name_hash,
(end_pos - start_pos).to_usize(),
GenericArgCountResult, GenericArgPosition,
};
use crate::errors::AssocTypeBindingNotAllowed;
-use crate::structured_errors::{StructuredDiagnostic, WrongNumberOfGenericArgs};
+use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
has_self: bool,
infer_args: bool,
) -> GenericArgCountResult {
+ debug!(
+ "check_generic_arg_count(span: {:?}, def_id: {:?}, seg: {:?}, gen_params: {:?}, gen_args: {:?})",
+ span, def_id, seg, gen_params, gen_args
+ );
+
let default_counts = gen_params.own_defaults();
let param_counts = gen_params.own_counts();
let named_type_param_count = param_counts.types - has_self as usize;
let mut invalid_args = vec![];
- let mut check_generics =
- |kind, expected_min, expected_max, provided, params_offset, args_offset, silent| {
+ let mut check_lifetime_args = |min_expected_args: usize,
+ max_expected_args: usize,
+ provided_args: usize,
+ late_bounds_ignore: bool|
+ -> bool {
+ if (min_expected_args..=max_expected_args).contains(&provided_args) {
+ return true;
+ }
+
+ if late_bounds_ignore {
+ return true;
+ }
+
+ if provided_args > max_expected_args {
+ invalid_args.extend(
+ gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()),
+ );
+ };
+
+ let gen_args_info = if provided_args > min_expected_args {
+ invalid_args.extend(
+ gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()),
+ );
+ let num_redundant_args = provided_args - min_expected_args;
+ GenericArgsInfo::ExcessLifetimes { num_redundant_args }
+ } else {
+ let num_missing_args = min_expected_args - provided_args;
+ GenericArgsInfo::MissingLifetimes { num_missing_args }
+ };
+
+ WrongNumberOfGenericArgs::new(
+ tcx,
+ gen_args_info,
+ seg,
+ gen_params,
+ has_self as usize,
+ gen_args,
+ def_id,
+ )
+ .diagnostic()
+ .emit();
+
+ false
+ };
+
+ let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes };
+ let max_expected_lifetime_args = param_counts.lifetimes;
+ let num_provided_lifetime_args = arg_counts.lifetimes;
+
+ let lifetimes_correct = check_lifetime_args(
+ min_expected_lifetime_args,
+ max_expected_lifetime_args,
+ num_provided_lifetime_args,
+ explicit_late_bound == ExplicitLateBound::Yes,
+ );
+
+ let mut check_types_and_consts =
+ |expected_min, expected_max, provided, params_offset, args_offset| {
+ debug!(
+ "check_types_and_consts(expected_min: {:?}, expected_max: {:?}, \
+ provided: {:?}, params_offset: {:?}, args_offset: {:?}",
+ expected_min, expected_max, provided, params_offset, args_offset
+ );
if (expected_min..=expected_max).contains(&provided) {
return true;
}
- if silent {
- return true;
- }
+ let num_default_params = expected_max - expected_min;
- if provided > expected_max {
+ let gen_args_info = if provided > expected_max {
invalid_args.extend(
gen_args.args[args_offset + expected_max..args_offset + provided]
.iter()
.map(|arg| arg.span()),
);
+ let num_redundant_args = provided - expected_max;
+
+ GenericArgsInfo::ExcessTypesOrConsts {
+ num_redundant_args,
+ num_default_params,
+ args_offset,
+ }
+ } else {
+ let num_missing_args = expected_max - provided;
+
+ GenericArgsInfo::MissingTypesOrConsts {
+ num_missing_args,
+ num_default_params,
+ args_offset,
+ }
};
- WrongNumberOfGenericArgs {
+ debug!("gen_args_info: {:?}", gen_args_info);
+
+ WrongNumberOfGenericArgs::new(
tcx,
- kind,
- expected_min,
- expected_max,
- provided,
- params_offset,
- args_offset,
- path_segment: seg,
+ gen_args_info,
+ seg,
gen_params,
+ params_offset,
gen_args,
def_id,
- span,
- }
+ )
.diagnostic()
.emit();
false
};
- let lifetimes_correct = check_generics(
- "lifetime",
- if infer_lifetimes { 0 } else { param_counts.lifetimes },
- param_counts.lifetimes,
- arg_counts.lifetimes,
- has_self as usize,
- 0,
- explicit_late_bound == ExplicitLateBound::Yes,
- );
-
let args_correct = {
- let kind = if param_counts.consts + arg_counts.consts == 0 {
- "type"
- } else if named_type_param_count + arg_counts.types == 0 {
- "const"
- } else {
- "generic"
- };
-
let expected_min = if infer_args {
0
} else {
- default_counts.types
- default_counts.consts
};
+ debug!("expected_min: {:?}", expected_min);
+ debug!("arg_counts.lifetimes: {:?}", arg_counts.lifetimes);
- check_generics(
- kind,
+ check_types_and_consts(
expected_min,
param_counts.consts + named_type_param_count,
arg_counts.consts + arg_counts.types,
param_counts.lifetimes + has_self as usize,
arg_counts.lifetimes,
- false,
)
};
#[derive(Debug)]
struct ConvertedBinding<'a, 'tcx> {
+ hir_id: hir::HirId,
item_name: Ident,
kind: ConvertedBindingKind<'a, 'tcx>,
gen_args: &'a GenericArgs<'a>,
param.def_id,
Some(arg.id()),
arg.span(),
+ None,
|_, _| {
// Default generic parameters may not be marked
// with stability attributes, i.e. when the
}
};
ConvertedBinding {
+ hir_id: binding.hir_id,
item_name: binding.ident,
kind,
gen_args: binding.gen_args,
item_segment: &hir::PathSegment<'_>,
parent_substs: SubstsRef<'tcx>,
) -> SubstsRef<'tcx> {
+ debug!(
+ "create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
+ span, item_def_id, item_segment
+ );
if tcx.generics_of(item_def_id).params.is_empty() {
self.prohibit_generics(slice::from_ref(item_segment));
.span_label(binding.span, "private associated type")
.emit();
}
- tcx.check_stability(assoc_ty.def_id, Some(hir_ref_id), binding.span);
+ tcx.check_stability(assoc_ty.def_id, Some(hir_ref_id), binding.span, None);
if !speculative {
dup_bindings
// Include substitutions for generic parameters of associated types
let projection_ty = candidate.map_bound(|trait_ref| {
+ let ident = Ident::new(assoc_ty.ident.name, binding.item_name.span);
let item_segment = hir::PathSegment {
- ident: assoc_ty.ident,
- hir_id: None,
+ ident,
+ hir_id: Some(binding.hir_id),
res: None,
args: Some(binding.gen_args),
infer_args: false,
.find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did));
if let Some(variant_def) = variant_def {
if permit_variants {
- tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span);
+ tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
self.prohibit_generics(slice::from_ref(assoc_segment));
return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
} else {
.span_label(span, &format!("private {}", kind))
.emit();
}
- tcx.check_stability(item.def_id, Some(hir_ref_id), span);
+ tcx.check_stability(item.def_id, Some(hir_ref_id), span, None);
if let Some(variant_def_id) = variant_resolution {
tcx.struct_span_lint_hir(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
// struct-like enums (yet...), but it's definitely not
// a bug to have constructed one.
if adt_kind != AdtKind::Enum {
- tcx.check_stability(v_field.did, Some(expr_id), field.span);
+ tcx.check_stability(v_field.did, Some(expr_id), field.span, None);
}
self.field_ty(field.span, v_field, substs)
self.apply_adjustments(base, adjustments);
self.register_predicates(autoderef.into_obligations());
- self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
+ self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
return field_ty;
}
private_candidate = Some((base_def.did, field_ty));
.insert(*import_id);
}
- self.tcx.check_stability(pick.item.def_id, Some(call_expr.hir_id), span);
+ self.tcx.check_stability(pick.item.def_id, Some(call_expr.hir_id), span, None);
let result =
self.confirm_method(span, self_expr, call_expr, self_ty, pick.clone(), segment);
// them as well. It's ok to use the variant's id as a ctor id since an
// error will be reported on any use of such resolution anyway.
let ctor_def_id = variant_def.ctor_def_id.unwrap_or(variant_def.def_id);
- tcx.check_stability(ctor_def_id, Some(expr_id), span);
+ tcx.check_stability(ctor_def_id, Some(expr_id), span, Some(method_name.span));
return Ok((
DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind),
ctor_def_id,
let def_kind = pick.item.kind.as_def_kind();
debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id);
- tcx.check_stability(pick.item.def_id, Some(expr_id), span);
+ tcx.check_stability(pick.item.def_id, Some(expr_id), span, Some(method_name.span));
Ok((def_kind, pick.item.def_id))
}
if let Some(uc) = unstable_candidates {
applicable_candidates.retain(|&(p, _)| {
if let stability::EvalResult::Deny { feature, .. } =
- self.tcx.eval_stability(p.item.def_id, None, self.span)
+ self.tcx.eval_stability(p.item.def_id, None, self.span, None)
{
uc.push((p, feature));
return false;
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
self.check_pat(&subpat, field_ty, def_bm, TopInfo { parent_pat: Some(&pat), ..ti });
- self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
+ self.tcx.check_stability(
+ variant.fields[i].did,
+ Some(pat.hir_id),
+ subpat.span,
+ None,
+ );
}
} else {
// Pattern has wrong number of fields.
.get(&ident)
.map(|(i, f)| {
self.write_field_index(field.hir_id, *i);
- self.tcx.check_stability(f.did, Some(pat.hir_id), span);
+ self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
self.field_ty(span, f, substs)
})
.unwrap_or_else(|| {
use crate::structured_errors::StructuredDiagnostic;
-use hir::def::DefKind;
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_hir as hir;
+use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
use rustc_middle::ty::{self as ty, TyCtxt};
use rustc_session::Session;
-use rustc_span::Span;
use rustc_span::{def_id::DefId, MultiSpan};
+use GenericArgsInfo::*;
+
/// Handles the `wrong number of type / lifetime / ... arguments` family of error messages.
pub struct WrongNumberOfGenericArgs<'a, 'tcx> {
crate tcx: TyCtxt<'tcx>,
- /// "type", "lifetime" etc., put verbatim into the message
- crate kind: &'static str,
-
- /// Minimum number of expected generic arguments (e.g. `2` for `HashMap`)
- crate expected_min: usize,
+ crate angle_brackets: AngleBrackets,
- /// Maximum number of expected generic arguments (e.g. `3` for `HashMap`)
- crate expected_max: usize,
-
- /// Number of generic arguments provided by the user
- crate provided: usize,
-
- /// Offset into `gen_params` - depends on the `kind`; might be different than `args_offset` when
- /// user passed e.g. more arguments than was actually expected
- crate params_offset: usize,
-
- /// Offset into `gen_args` - depends on the `kind`
- crate args_offset: usize,
+ crate gen_args_info: GenericArgsInfo,
/// Offending path segment
crate path_segment: &'a hir::PathSegment<'a>,
/// Generic parameters as expected by type or trait
crate gen_params: &'a ty::Generics,
+ /// Index offset into parameters. Depends on whether `Self` is included and on
+ /// number of lifetime parameters in case we're processing missing or redundant
+ /// type or constant arguments.
+ crate params_offset: usize,
+
/// Generic arguments as provided by user
crate gen_args: &'a hir::GenericArgs<'a>,
/// DefId of the generic type
crate def_id: DefId,
+}
+
+// Provides information about the kind of arguments that were provided for
+// the PathSegment, for which missing generic arguments were detected
+#[derive(Debug)]
+pub(crate) enum AngleBrackets {
+ // No angle brackets were provided, but generic arguments exist in elided form
+ Implied,
+
+ // No angle brackets were provided
+ Missing,
+
+ // Angle brackets are available, but missing some generic arguments
+ Available,
+}
- /// Offending place where the generic type has been misused
- crate span: Span,
+// Information about the kind of arguments that are either missing or are unexpected
+#[derive(Debug)]
+pub enum GenericArgsInfo {
+ MissingLifetimes {
+ num_missing_args: usize,
+ },
+ ExcessLifetimes {
+ num_redundant_args: usize,
+ },
+ MissingTypesOrConsts {
+ num_missing_args: usize,
+
+ // type or const generic arguments can have default values
+ num_default_params: usize,
+
+ // lifetime arguments precede type and const parameters, this
+ // field gives the number of generic lifetime arguments to let
+ // us infer the position of type and const generic arguments
+ // in the angle brackets
+ args_offset: usize,
+ },
+
+ ExcessTypesOrConsts {
+ num_redundant_args: usize,
+
+ // type or const generic arguments can have default values
+ num_default_params: usize,
+
+ // lifetime arguments precede type and const parameters, this
+ // field gives the number of generic lifetime arguments to let
+ // us infer the position of type and const generic arguments
+ // in the angle brackets
+ args_offset: usize,
+ },
}
-impl<'tcx> WrongNumberOfGenericArgs<'_, 'tcx> {
- fn quantifier_and_bound(&self) -> (&'static str, usize) {
- if self.expected_min == self.expected_max {
- ("", self.expected_min)
- } else if self.provided < self.expected_min {
- ("at least ", self.expected_min)
+impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
+ pub fn new(
+ tcx: TyCtxt<'tcx>,
+ gen_args_info: GenericArgsInfo,
+ path_segment: &'a hir::PathSegment<'_>,
+ gen_params: &'a ty::Generics,
+ params_offset: usize,
+ gen_args: &'a hir::GenericArgs<'a>,
+ def_id: DefId,
+ ) -> Self {
+ let angle_brackets = if gen_args.is_empty() {
+ AngleBrackets::Missing
} else {
- ("at most ", self.expected_max)
+ if gen_args.span().is_none() {
+ AngleBrackets::Implied
+ } else {
+ AngleBrackets::Available
+ }
+ };
+
+ Self {
+ tcx,
+ angle_brackets,
+ gen_args_info,
+ path_segment,
+ gen_params,
+ params_offset,
+ gen_args,
+ def_id,
}
}
- fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> {
- let span = self.path_segment.ident.span;
+ fn missing_lifetimes(&self) -> bool {
+ match self.gen_args_info {
+ MissingLifetimes { .. } | ExcessLifetimes { .. } => true,
+ MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => false,
+ }
+ }
- let msg = {
- let def_path = self.tcx.def_path_str(self.def_id);
- let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
- let (quantifier, bound) = self.quantifier_and_bound();
+ fn kind(&self) -> String {
+ if self.missing_lifetimes() { "lifetime".to_string() } else { "generic".to_string() }
+ }
- if self.gen_args.span().is_some() {
- format!(
- "this {} takes {}{} {} argument{} but {}{} {} argument{} {} supplied",
- def_kind,
- quantifier,
- bound,
- self.kind,
- pluralize!(bound),
- if self.provided > 0 && self.provided < self.expected_min {
- "only "
- } else {
- ""
- },
- self.provided,
- self.kind,
- pluralize!(self.provided),
- if self.provided == 1 { "was" } else { "were" },
- )
- } else {
- format!("missing generics for {} `{}`", def_kind, def_path)
+ fn num_provided_args(&self) -> usize {
+ if self.missing_lifetimes() {
+ self.num_provided_lifetime_args()
+ } else {
+ self.num_provided_type_or_const_args()
+ }
+ }
+
+ fn num_provided_lifetime_args(&self) -> usize {
+ match self.angle_brackets {
+ AngleBrackets::Missing => 0,
+ // Only lifetime arguments can be implied
+ AngleBrackets::Implied => self.gen_args.args.len(),
+ AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
+ hir::GenericArg::Lifetime(_) => acc + 1,
+ _ => acc,
+ }),
+ }
+ }
+
+ fn num_provided_type_or_const_args(&self) -> usize {
+ match self.angle_brackets {
+ AngleBrackets::Missing => 0,
+ // Only lifetime arguments can be implied
+ AngleBrackets::Implied => 0,
+ AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
+ hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => acc + 1,
+ _ => acc,
+ }),
+ }
+ }
+
+ fn num_expected_lifetime_args(&self) -> usize {
+ let num_provided_args = self.num_provided_lifetime_args();
+ match self.gen_args_info {
+ MissingLifetimes { num_missing_args } => num_provided_args + num_missing_args,
+ ExcessLifetimes { num_redundant_args } => num_provided_args - num_redundant_args,
+ _ => 0,
+ }
+ }
+
+ fn num_expected_type_or_const_args(&self) -> usize {
+ let num_provided_args = self.num_provided_type_or_const_args();
+ match self.gen_args_info {
+ MissingTypesOrConsts { num_missing_args, .. } => num_provided_args + num_missing_args,
+ ExcessTypesOrConsts { num_redundant_args, .. } => {
+ num_provided_args - num_redundant_args
+ }
+ _ => 0,
+ }
+ }
+
+ // Gives the number of expected arguments taking into account default arguments
+ fn num_expected_type_or_const_args_including_defaults(&self) -> usize {
+ let provided_args = self.num_provided_type_or_const_args();
+ match self.gen_args_info {
+ MissingTypesOrConsts { num_missing_args, num_default_params, .. } => {
+ provided_args + num_missing_args - num_default_params
+ }
+ ExcessTypesOrConsts { num_redundant_args, num_default_params, .. } => {
+ provided_args - num_redundant_args - num_default_params
+ }
+ _ => 0,
+ }
+ }
+
+ fn num_missing_lifetime_args(&self) -> usize {
+ let missing_args = self.num_expected_lifetime_args() - self.num_provided_lifetime_args();
+ assert!(missing_args > 0);
+ missing_args
+ }
+
+ fn num_missing_type_or_const_args(&self) -> usize {
+ let missing_args = self.num_expected_type_or_const_args_including_defaults()
+ - self.num_provided_type_or_const_args();
+ assert!(missing_args > 0);
+ missing_args
+ }
+
+ fn num_excess_lifetime_args(&self) -> usize {
+ match self.gen_args_info {
+ ExcessLifetimes { num_redundant_args } => num_redundant_args,
+ _ => 0,
+ }
+ }
+
+ fn num_excess_type_or_const_args(&self) -> usize {
+ match self.gen_args_info {
+ ExcessTypesOrConsts { num_redundant_args, .. } => num_redundant_args,
+ _ => 0,
+ }
+ }
+
+ fn too_many_args_provided(&self) -> bool {
+ match self.gen_args_info {
+ MissingLifetimes { .. } | MissingTypesOrConsts { .. } => false,
+ ExcessLifetimes { num_redundant_args }
+ | ExcessTypesOrConsts { num_redundant_args, .. } => {
+ assert!(num_redundant_args > 0);
+ true
+ }
+ }
+ }
+
+ fn not_enough_args_provided(&self) -> bool {
+ match self.gen_args_info {
+ MissingLifetimes { num_missing_args }
+ | MissingTypesOrConsts { num_missing_args, .. } => {
+ assert!(num_missing_args > 0);
+ true
+ }
+ ExcessLifetimes { .. } | ExcessTypesOrConsts { .. } => false,
+ }
+ }
+
+ // Helper method to get the index offset in angle brackets, at which type or const arguments
+ // start appearing
+ fn get_lifetime_args_offset(&self) -> usize {
+ match self.gen_args_info {
+ MissingLifetimes { .. } | ExcessLifetimes { .. } => 0,
+ MissingTypesOrConsts { args_offset, .. } | ExcessTypesOrConsts { args_offset, .. } => {
+ args_offset
}
+ }
+ }
+
+ fn get_num_default_params(&self) -> usize {
+ match self.gen_args_info {
+ MissingTypesOrConsts { num_default_params, .. }
+ | ExcessTypesOrConsts { num_default_params, .. } => num_default_params,
+ _ => 0,
+ }
+ }
+
+ // Helper function to choose a quantifier word for the number of expected arguments
+ // and to give a bound for the number of expected arguments
+ fn get_quantifier_and_bound(&self) -> (&'static str, usize) {
+ if self.get_num_default_params() == 0 {
+ match self.gen_args_info {
+ MissingLifetimes { .. } | ExcessLifetimes { .. } => {
+ ("", self.num_expected_lifetime_args())
+ }
+ MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => {
+ ("", self.num_expected_type_or_const_args())
+ }
+ }
+ } else {
+ match self.gen_args_info {
+ MissingLifetimes { .. } => ("at least ", self.num_expected_lifetime_args()),
+ MissingTypesOrConsts { .. } => {
+ ("at least ", self.num_expected_type_or_const_args_including_defaults())
+ }
+ ExcessLifetimes { .. } => ("at most ", self.num_expected_lifetime_args()),
+ ExcessTypesOrConsts { .. } => ("at most ", self.num_expected_type_or_const_args()),
+ }
+ }
+ }
+
+ // Creates lifetime name suggestions from the lifetime parameter names
+ fn get_lifetime_args_suggestions_from_param_names(&self, num_params_to_take: usize) -> String {
+ self.gen_params
+ .params
+ .iter()
+ .skip(self.params_offset + self.num_provided_lifetime_args())
+ .take(num_params_to_take)
+ .map(|param| param.name.to_string())
+ .collect::<Vec<_>>()
+ .join(", ")
+ }
+
+ // Creates type or constant name suggestions from the provided parameter names
+ fn get_type_or_const_args_suggestions_from_param_names(
+ &self,
+ num_params_to_take: usize,
+ ) -> String {
+ self.gen_params
+ .params
+ .iter()
+ .skip(self.params_offset + self.num_provided_type_or_const_args())
+ .take(num_params_to_take)
+ .map(|param| param.name.to_string())
+ .collect::<Vec<_>>()
+ .join(", ")
+ }
+
+ fn create_error_message(&self) -> String {
+ let def_path = self.tcx.def_path_str(self.def_id);
+ let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
+ let (quantifier, bound) = self.get_quantifier_and_bound();
+ let kind = self.kind();
+ let provided_lt_args = self.num_provided_lifetime_args();
+ let provided_type_or_const_args = self.num_provided_type_or_const_args();
+
+ let get_verb = |num_args| if num_args == 1 { "was" } else { "were" };
+
+ let (provided_args_str, verb) = match self.gen_args_info {
+ MissingLifetimes { .. } | ExcessLifetimes { .. } => (
+ format!("{} lifetime argument{}", provided_lt_args, pluralize!(provided_lt_args)),
+ get_verb(provided_lt_args),
+ ),
+ MissingTypesOrConsts { .. } | ExcessTypesOrConsts { .. } => (
+ format!(
+ "{} generic argument{}",
+ provided_type_or_const_args,
+ pluralize!(provided_type_or_const_args)
+ ),
+ get_verb(provided_type_or_const_args),
+ ),
};
+ if self.gen_args.span().is_some() {
+ format!(
+ "this {} takes {}{} {} argument{} but {} {} supplied",
+ def_kind,
+ quantifier,
+ bound,
+ kind,
+ pluralize!(bound),
+ provided_args_str.as_str(),
+ verb
+ )
+ } else {
+ format!("missing generics for {} `{}`", def_kind, def_path)
+ }
+ }
+
+ fn start_diagnostics(&self) -> DiagnosticBuilder<'tcx> {
+ let span = self.path_segment.ident.span;
+ let msg = self.create_error_message();
+
self.tcx.sess.struct_span_err_with_code(span, &msg, self.code())
}
/// Builds the `expected 1 type argument / supplied 2 type arguments` message.
fn notify(&self, err: &mut DiagnosticBuilder<'_>) {
- let (quantifier, bound) = self.quantifier_and_bound();
+ let (quantifier, bound) = self.get_quantifier_and_bound();
+ let provided_args = self.num_provided_args();
err.span_label(
self.path_segment.ident.span,
"expected {}{} {} argument{}",
quantifier,
bound,
- self.kind,
+ self.kind(),
pluralize!(bound),
),
);
- // When user's provided too many arguments, we don't highlight each of them, because it
+ // When too many arguments were provided, we don't highlight each of them, because it
// would overlap with the suggestion to remove them:
//
// ```
// ----- ----- supplied 2 type arguments
// ^^^^^^^ remove this type argument
// ```
- if self.provided > self.expected_max {
+ if self.too_many_args_provided() {
return;
}
- let args = self.gen_args.args.iter().skip(self.args_offset).take(self.provided).enumerate();
+ let args = self
+ .gen_args
+ .args
+ .iter()
+ .skip(self.get_lifetime_args_offset())
+ .take(provided_args)
+ .enumerate();
for (i, arg) in args {
err.span_label(
arg.span(),
- if i + 1 == self.provided {
+ if i + 1 == provided_args {
format!(
"supplied {} {} argument{}",
- self.provided,
- self.kind,
- pluralize!(self.provided)
+ provided_args,
+ self.kind(),
+ pluralize!(provided_args)
)
} else {
String::new()
}
fn suggest(&self, err: &mut DiagnosticBuilder<'_>) {
- if self.provided == 0 {
- if self.gen_args.span().is_some() {
- self.suggest_adding_args(err);
- } else {
- self.suggest_creating_generics(err);
- }
- } else if self.provided < self.expected_min {
- self.suggest_adding_args(err);
- } else {
- self.suggest_removing_args_or_generics(err);
- }
- }
-
- /// Suggests to create generics (`<...>`) when current invocation site contains no generics at
- /// all:
- ///
- /// ```text
- /// type Map = HashMap;
- /// ```
- fn suggest_creating_generics(&self, err: &mut DiagnosticBuilder<'_>) {
- let params = self
- .gen_params
- .params
- .iter()
- .skip(self.params_offset)
- .take(self.expected_min)
- .map(|param| param.name.to_string())
- .collect::<Vec<_>>()
- .join(", ");
-
- let def_kind = self.tcx.def_kind(self.def_id);
-
- let sugg = if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) {
- format!("::<{}>", params)
- } else {
- format!("<{}>", params)
- };
-
- let msg = format!(
- "use angle brackets to add missing {} argument{}",
- self.kind,
- pluralize!(self.expected_min),
+ debug!(
+ "suggest(self.provided {:?}, self.gen_args.span(): {:?})",
+ self.num_provided_args(),
+ self.gen_args.span(),
);
- err.span_suggestion_verbose(
- self.path_segment.ident.span.shrink_to_hi(),
- &msg,
- sugg,
- Applicability::HasPlaceholders,
- );
+ match self.angle_brackets {
+ AngleBrackets::Missing | AngleBrackets::Implied => self.suggest_adding_args(err),
+ AngleBrackets::Available => {
+ if self.not_enough_args_provided() {
+ self.suggest_adding_args(err);
+ } else if self.too_many_args_provided() {
+ self.suggest_removing_args_or_generics(err);
+ } else {
+ unreachable!();
+ }
+ }
+ }
}
/// Suggests to add missing argument(s) when current invocation site already contains some
/// type Map = HashMap<String>;
/// ```
fn suggest_adding_args(&self, err: &mut DiagnosticBuilder<'_>) {
- assert!(!self.gen_args.is_empty());
-
if self.gen_args.parenthesized {
return;
}
- let missing_arg_count = self.expected_min - self.provided;
+ match self.gen_args_info {
+ MissingLifetimes { .. } => {
+ self.suggest_adding_lifetime_args(err);
+ }
+ MissingTypesOrConsts { .. } => {
+ self.suggest_adding_type_and_const_args(err);
+ }
+ _ => unreachable!(),
+ }
+ }
- let (span, sugg_prefix) = if self.args_offset + self.provided == 0 {
- let span = self.gen_args.args[0].span().shrink_to_lo();
- (span, "")
+ fn suggest_adding_lifetime_args(&self, err: &mut DiagnosticBuilder<'_>) {
+ debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
+ let num_missing_args = self.num_missing_lifetime_args();
+ let num_params_to_take = num_missing_args;
+ let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
+
+ // we first try to get lifetime name suggestions from scope or elision information. If none is
+ // available we use the parameter defintions
+ let suggested_args = if let Some(hir_id) = self.path_segment.hir_id {
+ if let Some(lifetimes_in_scope) = self.tcx.lifetime_scope(hir_id) {
+ match lifetimes_in_scope {
+ LifetimeScopeForPath::NonElided(param_names) => {
+ debug!("NonElided(param_names: {:?})", param_names);
+
+ if param_names.len() >= num_params_to_take {
+ // use lifetime parameters in scope for suggestions
+ param_names
+ .iter()
+ .take(num_params_to_take)
+ .map(|p| (*p).clone())
+ .collect::<Vec<_>>()
+ .join(", ")
+ } else {
+ // Not enough lifetime arguments in scope -> create suggestions from
+ // lifetime parameter names in definition. An error for the incorrect
+ // lifetime scope will be output later.
+ self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
+ }
+ }
+ LifetimeScopeForPath::Elided => {
+ debug!("Elided");
+ // use suggestions of the form `<'_, '_>` in case lifetime can be elided
+ ["'_"].repeat(num_params_to_take).join(",")
+ }
+ }
+ } else {
+ self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
+ }
} else {
- let span =
- self.gen_args.args[self.args_offset + self.provided - 1].span().shrink_to_hi();
- (span, ", ")
+ self.get_lifetime_args_suggestions_from_param_names(num_params_to_take)
};
- let msg = format!("add missing {} argument{}", self.kind, pluralize!(missing_arg_count));
+ debug!("suggested_args: {:?}", &suggested_args);
- let sugg = self
- .gen_params
- .params
- .iter()
- .skip(self.params_offset + self.provided)
- .take(missing_arg_count)
- .map(|param| param.name.to_string())
- .collect::<Vec<_>>()
- .join(", ");
+ match self.angle_brackets {
+ AngleBrackets::Missing => {
+ let span = self.path_segment.ident.span;
+
+ // insert a suggestion of the form "Y<'a, 'b>"
+ let ident = self.path_segment.ident.name.to_ident_string();
+ let sugg = format!("{}<{}>", ident, suggested_args);
+ debug!("sugg: {:?}", sugg);
+
+ err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
+ }
+
+ AngleBrackets::Available => {
+ // angle brackets exist, so we insert missing arguments after the existing args
+
+ assert!(!self.gen_args.args.is_empty());
+
+ if self.num_provided_lifetime_args() > 0 {
+ let last_lt_arg_span = self.gen_args.args
+ [self.num_provided_lifetime_args() - 1]
+ .span()
+ .shrink_to_hi();
+ let source_map = self.tcx.sess.source_map();
- let sugg = format!("{}{}", sugg_prefix, sugg);
+ if let Ok(last_gen_arg) = source_map.span_to_snippet(last_lt_arg_span) {
+ let sugg = format!("{}, {}", last_gen_arg, suggested_args);
- err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
+ err.span_suggestion_verbose(
+ last_lt_arg_span,
+ &msg,
+ sugg,
+ Applicability::HasPlaceholders,
+ );
+ }
+ } else {
+ // Non-lifetime arguments included in `gen_args` -> insert missing lifetimes before
+ // existing arguments
+ let first_arg_span = self.gen_args.args[0].span().shrink_to_lo();
+ let source_map = self.tcx.sess.source_map();
+
+ if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) {
+ let sugg = format!("{}, {}", suggested_args, first_gen_arg);
+
+ err.span_suggestion_verbose(
+ first_arg_span,
+ &msg,
+ sugg,
+ Applicability::HasPlaceholders,
+ );
+ }
+ }
+ }
+ AngleBrackets::Implied => {
+ // We never encounter missing lifetimes in situations in which lifetimes are elided
+ unreachable!();
+ }
+ }
+ }
+
+ fn suggest_adding_type_and_const_args(&self, err: &mut DiagnosticBuilder<'_>) {
+ let num_missing_args = self.num_missing_type_or_const_args();
+ let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
+
+ let suggested_args =
+ self.get_type_or_const_args_suggestions_from_param_names(num_missing_args);
+ debug!("suggested_args: {:?}", suggested_args);
+
+ match self.angle_brackets {
+ AngleBrackets::Missing | AngleBrackets::Implied => {
+ let span = self.path_segment.ident.span;
+
+ // insert a suggestion of the form "Y<T, U>"
+ let ident = self.path_segment.ident.name.to_ident_string();
+ let sugg = format!("{}<{}>", ident, suggested_args);
+ debug!("sugg: {:?}", sugg);
+
+ err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
+ }
+ AngleBrackets::Available => {
+ // angle brackets exist, so we just insert missing arguments after the existing
+ // type or const args
+
+ let index_last_provided_arg =
+ self.get_lifetime_args_offset() + self.num_provided_type_or_const_args() - 1;
+ if index_last_provided_arg < self.gen_args.args.len() {
+ let first_arg_span =
+ self.gen_args.args[index_last_provided_arg].span().shrink_to_hi();
+ let source_map = self.tcx.sess.source_map();
+ if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) {
+ let sugg = format!("{}, {}", first_gen_arg, suggested_args);
+ debug!("sugg: {:?}", sugg);
+
+ err.span_suggestion_verbose(
+ first_arg_span,
+ &msg,
+ sugg,
+ Applicability::HasPlaceholders,
+ );
+ }
+ }
+ }
+ }
}
/// Suggests to remove redundant argument(s):
/// type Map = HashMap<String, String, String, String>;
/// ```
fn suggest_removing_args_or_generics(&self, err: &mut DiagnosticBuilder<'_>) {
- assert!(self.provided > 0);
+ let num_provided_lt_args = self.num_provided_lifetime_args();
+ let num_provided_type_const_args = self.num_provided_type_or_const_args();
+ let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
+ assert!(num_provided_args > 0);
+
+ let num_redundant_lt_args = self.num_excess_lifetime_args();
+ let num_redundant_type_or_const_args = self.num_excess_type_or_const_args();
+ let num_redundant_args = num_redundant_lt_args + num_redundant_type_or_const_args;
+
+ let redundant_lifetime_args = num_redundant_lt_args > 0;
+ let redundant_type_or_const_args = num_redundant_type_or_const_args > 0;
+
+ let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
+
+ let remove_lifetime_args = |err: &mut DiagnosticBuilder<'_>| {
+ let idx_first_redundant_lt_args = self.num_expected_lifetime_args();
+ let span_lo_redundant_lt_args =
+ self.gen_args.args[idx_first_redundant_lt_args].span().shrink_to_lo();
+ let span_hi_redundant_lt_args = self.gen_args.args
+ [idx_first_redundant_lt_args + num_redundant_lt_args - 1]
+ .span()
+ .shrink_to_hi();
+ let eat_comma =
+ idx_first_redundant_lt_args + num_redundant_lt_args - 1 != self.gen_args.args.len();
+
+ let span_redundant_lt_args = if eat_comma {
+ let span_hi = self.gen_args.args
+ [idx_first_redundant_lt_args + num_redundant_lt_args - 1]
+ .span()
+ .shrink_to_hi();
+ span_lo_redundant_lt_args.to(span_hi)
+ } else {
+ span_lo_redundant_lt_args.to(span_hi_redundant_lt_args)
+ };
+ debug!("span_redundant_lt_args: {:?}", span_redundant_lt_args);
+
+ let msg_lifetimes = format!(
+ "remove {} {} argument{}",
+ if num_redundant_args == 1 { "this" } else { "these" },
+ "lifetime",
+ pluralize!(num_redundant_lt_args),
+ );
+
+ err.span_suggestion(
+ span_redundant_lt_args,
+ &msg_lifetimes,
+ String::new(),
+ Applicability::MaybeIncorrect,
+ );
+ };
+
+ let remove_type_or_const_args = |err: &mut DiagnosticBuilder<'_>| {
+ let idx_first_redundant_type_or_const_args = self.get_lifetime_args_offset()
+ + num_redundant_lt_args
+ + self.num_expected_type_or_const_args();
+
+ let span_lo_redundant_type_or_const_args =
+ self.gen_args.args[idx_first_redundant_type_or_const_args].span().shrink_to_lo();
- let redundant_args_count = self.provided - self.expected_max;
- let remove_entire_generics = redundant_args_count >= self.gen_args.args.len();
+ let span_hi_redundant_type_or_const_args = self.gen_args.args
+ [idx_first_redundant_type_or_const_args + num_redundant_type_or_const_args - 1]
+ .span()
+ .shrink_to_hi();
- let (span, msg) = if remove_entire_generics {
+ let span_redundant_type_or_const_args =
+ span_lo_redundant_type_or_const_args.to(span_hi_redundant_type_or_const_args);
+
+ debug!("span_redundant_type_or_const_args: {:?}", span_redundant_type_or_const_args);
+
+ let msg_types_or_consts = format!(
+ "remove {} {} argument{}",
+ if num_redundant_args == 1 { "this" } else { "these" },
+ "generic",
+ pluralize!(num_redundant_type_or_const_args),
+ );
+
+ err.span_suggestion(
+ span_redundant_type_or_const_args,
+ &msg_types_or_consts,
+ String::new(),
+ Applicability::MaybeIncorrect,
+ );
+ };
+
+ if remove_entire_generics {
let sm = self.tcx.sess.source_map();
let span = self
if self.gen_args.parenthesized { "parenthetical " } else { "" },
);
- (span, msg)
+ err.span_suggestion(span, &msg, String::new(), Applicability::MaybeIncorrect);
+ } else if redundant_lifetime_args && redundant_type_or_const_args {
+ remove_lifetime_args(err);
+ remove_type_or_const_args(err);
+ } else if redundant_lifetime_args {
+ remove_lifetime_args(err);
} else {
- // When it comes to removing particular argument(s) from the generics, there are two
- // edge cases we have to consider:
- //
- // When the first redundant argument is at the beginning or in the middle of the
- // generics, like so:
- //
- // ```
- // type Map = HashMap<String, String, String, String>;
- // ^^^^^^^^^^^^^^^^
- // | span must start with the argument
- // ```
- //
- // When the last redundant argument is at the ending of the generics, like so:
- //
- // ```
- // type Map = HashMap<String, String, String, String>;
- // ^^^^^^^^^^^^^^^^
- // | span must start with the comma
- // ```
-
- // Index of the first redundant argument
- let from_idx = self.args_offset + self.expected_max;
-
- // Index of the last redundant argument
- let to_idx = self.args_offset + self.provided - 1;
-
- assert!(from_idx <= to_idx);
-
- let (from, comma_eaten) = {
- let first_argument_starts_generics = from_idx == 0;
- let last_argument_ends_generics = to_idx + 1 == self.gen_args.args.len();
-
- if !first_argument_starts_generics && last_argument_ends_generics {
- (self.gen_args.args[from_idx - 1].span().hi(), true)
- } else {
- (self.gen_args.args[from_idx].span().lo(), false)
- }
- };
-
- let to = {
- let hi = self.gen_args.args[to_idx].span().hi();
-
- if comma_eaten {
- hi
- } else {
- self.gen_args.args.get(to_idx + 1).map(|arg| arg.span().lo()).unwrap_or(hi)
- }
- };
-
- let span = Span::new(from, to, self.span.ctxt());
-
- let msg = format!(
- "remove {} {} argument{}",
- if redundant_args_count == 1 { "this" } else { "these" },
- self.kind,
- pluralize!(redundant_args_count),
- );
-
- (span, msg)
- };
-
- err.span_suggestion(span, &msg, String::new(), Applicability::MaybeIncorrect);
+ assert!(redundant_type_or_const_args);
+ remove_type_or_const_args(err);
+ }
}
/// Builds the `type defined here` message.
let msg = {
let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
- let (quantifier, bound) = self.quantifier_and_bound();
+ let (quantifier, bound) = self.get_quantifier_and_bound();
let params = if bound == 0 {
String::new()
def_kind,
quantifier,
bound,
- self.kind,
+ self.kind(),
pluralize!(bound),
params,
)
impl<K, V> Drop for Dropper<K, V> {
fn drop(&mut self) {
// Similar to advancing a non-fusing iterator.
- fn next_or_end<K, V>(this: &mut Dropper<K, V>) -> Option<(K, V)> {
+ fn next_or_end<K, V>(
+ this: &mut Dropper<K, V>,
+ ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>>
+ {
if this.remaining_length == 0 {
unsafe { ptr::read(&this.front).deallocating_end() }
None
fn drop(&mut self) {
// Continue the same loop we perform below. This only runs when unwinding, so we
// don't have to care about panics this time (they'll abort).
- while let Some(_pair) = next_or_end(&mut self.0) {}
+ while let Some(kv) = next_or_end(&mut self.0) {
+ kv.drop_key_val();
+ }
}
}
- while let Some(pair) = next_or_end(self) {
+ while let Some(kv) = next_or_end(self) {
let guard = DropGuard(self);
- drop(pair);
+ kv.drop_key_val();
mem::forget(guard);
}
}
None
} else {
self.length -= 1;
- Some(unsafe { self.range.front.as_mut().unwrap().deallocating_next_unchecked() })
+ let front = self.range.front.as_mut().unwrap();
+ let kv = unsafe { front.deallocating_next_unchecked() };
+ Some(kv.into_key_val())
}
}
None
} else {
self.length -= 1;
- Some(unsafe { self.range.back.as_mut().unwrap().deallocating_next_back_unchecked() })
+ let back = self.range.back.as_mut().unwrap();
+ let kv = unsafe { back.deallocating_next_back_unchecked() };
+ Some(kv.into_key_val())
}
}
}
impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// Given a leaf edge handle into a dying tree, returns the next leaf edge
- /// on the right side, and the key-value pair in between, which is either
- /// in the same leaf node, in an ancestor node, or non-existent.
+ /// on the right side, and the key-value pair in between, if they exist.
///
- /// This method also deallocates any node(s) it reaches the end of. This
- /// implies that if no more key-value pair exists, the entire remainder of
- /// the tree will have been deallocated and there is nothing left to return.
+ /// If the given edge is the last one in a leaf, this method deallocates
+ /// the leaf, as well as any ancestor nodes whose last edge was reached.
+ /// This implies that if no more key-value pair follows, the entire tree
+ /// will have been deallocated and there is nothing left to return.
///
/// # Safety
- /// The given edge must not have been previously returned by counterpart
- /// `deallocating_next_back`.
- unsafe fn deallocating_next(self) -> Option<(Self, (K, V))> {
+ /// - The given edge must not have been previously returned by counterpart
+ /// `deallocating_next_back`.
+ /// - The returned KV handle is only valid to access the key and value,
+ /// and only valid until the next call to this method or counterpart
+ /// `deallocating_next_back`.
+ pub unsafe fn deallocating_next(
+ self,
+ ) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
+ {
let mut edge = self.forget_node_type();
loop {
edge = match edge.right_kv() {
- Ok(kv) => {
- let k = unsafe { ptr::read(kv.reborrow().into_kv().0) };
- let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
- return Some((kv.next_leaf_edge(), (k, v)));
- }
+ Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)),
Err(last_edge) => match unsafe { last_edge.into_node().deallocate_and_ascend() } {
Some(parent_edge) => parent_edge.forget_node_type(),
None => return None,
}
/// Given a leaf edge handle into a dying tree, returns the next leaf edge
- /// on the left side, and the key-value pair in between, which is either
- /// in the same leaf node, in an ancestor node, or non-existent.
+ /// on the left side, and the key-value pair in between, if they exist.
///
- /// This method also deallocates any node(s) it reaches the end of. This
- /// implies that if no more key-value pair exists, the entire remainder of
- /// the tree will have been deallocated and there is nothing left to return.
+ /// If the given edge is the first one in a leaf, this method deallocates
+ /// the leaf, as well as any ancestor nodes whose first edge was reached.
+ /// This implies that if no more key-value pair follows, the entire tree
+ /// will have been deallocated and there is nothing left to return.
///
/// # Safety
- /// The given edge must not have been previously returned by counterpart
- /// `deallocating_next`.
- unsafe fn deallocating_next_back(self) -> Option<(Self, (K, V))> {
+ /// - The given edge must not have been previously returned by counterpart
+ /// `deallocating_next`.
+ /// - The returned KV handle is only valid to access the key and value,
+ /// and only valid until the next call to this method or counterpart
+ /// `deallocating_next`.
+ unsafe fn deallocating_next_back(
+ self,
+ ) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
+ {
let mut edge = self.forget_node_type();
loop {
edge = match edge.left_kv() {
- Ok(kv) => {
- let k = unsafe { ptr::read(kv.reborrow().into_kv().0) };
- let v = unsafe { ptr::read(kv.reborrow().into_kv().1) };
- return Some((kv.next_back_leaf_edge(), (k, v)));
- }
+ Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)),
Err(last_edge) => match unsafe { last_edge.into_node().deallocate_and_ascend() } {
Some(parent_edge) => parent_edge.forget_node_type(),
None => return None,
///
/// # Safety
/// - There must be another KV in the direction travelled.
- /// - That KV was not previously returned by counterpart `next_back_unchecked`
- /// on any copy of the handles being used to traverse the tree.
+ /// - That KV was not previously returned by counterpart
+ /// `deallocating_next_back_unchecked` on any copy of the handles
+ /// being used to traverse the tree.
///
/// The only safe way to proceed with the updated handle is to compare it, drop it,
- /// call this method again subject to its safety conditions, or call counterpart
- /// `next_back_unchecked` subject to its safety conditions.
- pub unsafe fn deallocating_next_unchecked(&mut self) -> (K, V) {
+ /// or call this method or counterpart `deallocating_next_back_unchecked` again.
+ pub unsafe fn deallocating_next_unchecked(
+ &mut self,
+ ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
super::mem::replace(self, |leaf_edge| unsafe {
leaf_edge.deallocating_next().unwrap_unchecked()
})
///
/// # Safety
/// - There must be another KV in the direction travelled.
- /// - That leaf edge was not previously returned by counterpart `next_unchecked`
- /// on any copy of the handles being used to traverse the tree.
+ /// - That leaf edge was not previously returned by counterpart
+ /// `deallocating_next_unchecked` on any copy of the handles
+ /// being used to traverse the tree.
///
/// The only safe way to proceed with the updated handle is to compare it, drop it,
- /// call this method again subject to its safety conditions, or call counterpart
- /// `next_unchecked` subject to its safety conditions.
- pub unsafe fn deallocating_next_back_unchecked(&mut self) -> (K, V) {
+ /// or call this method or counterpart `deallocating_next_unchecked` again.
+ pub unsafe fn deallocating_next_back_unchecked(
+ &mut self,
+ ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
super::mem::replace(self, |leaf_edge| unsafe {
leaf_edge.deallocating_next_back().unwrap_unchecked()
})
NodeRef { height: self.height, node: self.node, _marker: PhantomData }
}
- /// Borrows exclusive access to the leaf portion of any leaf or internal node.
+ /// Borrows exclusive access to the leaf portion of a leaf or internal node.
fn as_leaf_mut(&mut self) -> &mut LeafNode<K, V> {
let ptr = Self::as_leaf_ptr(self);
// SAFETY: we have exclusive access to the entire node.
unsafe { &mut *ptr }
}
- /// Offers exclusive access to the leaf portion of any leaf or internal node.
+ /// Offers exclusive access to the leaf portion of a leaf or internal node.
fn into_leaf_mut(mut self) -> &'a mut LeafNode<K, V> {
let ptr = Self::as_leaf_ptr(&mut self);
// SAFETY: we have exclusive access to the entire node.
}
}
+impl<K, V, Type> NodeRef<marker::Dying, K, V, Type> {
+ /// Borrows exclusive access to the leaf portion of a dying leaf or internal node.
+ fn as_leaf_dying(&mut self) -> &mut LeafNode<K, V> {
+ let ptr = Self::as_leaf_ptr(self);
+ // SAFETY: we have exclusive access to the entire node.
+ unsafe { &mut *ptr }
+ }
+}
+
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
/// Borrows exclusive access to an element of the key storage area.
///
}
}
- /// Replace the key and value that the KV handle refers to.
+ /// Replaces the key and value that the KV handle refers to.
pub fn replace_kv(&mut self, k: K, v: V) -> (K, V) {
let (key, val) = self.kv_mut();
(mem::replace(key, k), mem::replace(val, v))
}
}
+impl<K, V, NodeType> Handle<NodeRef<marker::Dying, K, V, NodeType>, marker::KV> {
+ /// Extracts the key and value that the KV handle refers to.
+ pub fn into_key_val(mut self) -> (K, V) {
+ debug_assert!(self.idx < self.node.len());
+ let leaf = self.node.as_leaf_dying();
+ unsafe {
+ let key = leaf.keys.get_unchecked_mut(self.idx).assume_init_read();
+ let val = leaf.vals.get_unchecked_mut(self.idx).assume_init_read();
+ (key, val)
+ }
+ }
+
+ /// Drops the key and value that the KV handle refers to.
+ #[inline]
+ pub fn drop_key_val(mut self) {
+ debug_assert!(self.idx < self.node.len());
+ let leaf = self.node.as_leaf_dying();
+ unsafe {
+ leaf.keys.get_unchecked_mut(self.idx).assume_init_drop();
+ leaf.vals.get_unchecked_mut(self.idx).assume_init_drop();
+ }
+ }
+}
+
impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
/// Helps implementations of `split` for a particular `NodeType`,
/// by taking care of leaf data.
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
fn source_text($self: $S::Span) -> Option<String>;
+ fn save_span($self: $S::Span) -> usize;
+ fn recover_proc_macro_span(id: usize) -> $S::Span;
},
}
};
&'a [u8],
&'a str,
String,
+ usize,
Delimiter,
Level,
LineColumn,
/// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
/// To quote `$` itself, use `$$`.
#[unstable(feature = "proc_macro_quote", issue = "54722")]
-#[allow_internal_unstable(proc_macro_def_site)]
+#[allow_internal_unstable(proc_macro_def_site, proc_macro_internals)]
#[rustc_builtin_macro]
pub macro quote($($t:tt)*) {
/* compiler built-in */
self.0.source_text()
}
+ // Used by the implementation of `Span::quote`
+ #[doc(hidden)]
+ #[unstable(feature = "proc_macro_internals", issue = "27812")]
+ pub fn save_span(&self) -> usize {
+ self.0.save_span()
+ }
+
+ // Used by the implementation of `Span::quote`
+ #[doc(hidden)]
+ #[unstable(feature = "proc_macro_internals", issue = "27812")]
+ pub fn recover_proc_macro_span(id: usize) -> Span {
+ Span(bridge::client::Span::recover_proc_macro_span(id))
+ }
+
diagnostic_method!(error, Level::Error);
diagnostic_method!(warning, Level::Warning);
diagnostic_method!(note, Level::Note);
if stream.is_empty() {
return quote!(crate::TokenStream::new());
}
+ let proc_macro_crate = quote!(crate);
let mut after_dollar = false;
let tokens = stream
.into_iter()
))),
TokenTree::Ident(tt) => quote!(crate::TokenTree::Ident(crate::Ident::new(
(@ TokenTree::from(Literal::string(&tt.to_string()))),
- (@ quote_span(tt.span())),
+ (@ quote_span(proc_macro_crate.clone(), tt.span())),
))),
TokenTree::Literal(tt) => quote!(crate::TokenTree::Literal({
let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
if let (Some(crate::TokenTree::Literal(mut lit)), None) =
(iter.next(), iter.next())
{
- lit.set_span((@ quote_span(tt.span())));
+ lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
lit
} else {
unreachable!()
/// Quote a `Span` into a `TokenStream`.
/// This is needed to implement a custom quoter.
#[unstable(feature = "proc_macro_quote", issue = "54722")]
-pub fn quote_span(_: Span) -> TokenStream {
- quote!(crate::Span::def_site())
+pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
+ let id = span.save_span();
+ quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
}
/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
- _set_var(k.as_ref(), v.as_ref())
+pub fn set_var<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
+ _set_var(key.as_ref(), value.as_ref())
}
-fn _set_var(k: &OsStr, v: &OsStr) {
- os_imp::setenv(k, v).unwrap_or_else(|e| {
- panic!("failed to set environment variable `{:?}` to `{:?}`: {}", k, v, e)
+fn _set_var(key: &OsStr, value: &OsStr) {
+ os_imp::setenv(key, value).unwrap_or_else(|e| {
+ panic!("failed to set environment variable `{:?}` to `{:?}`: {}", key, value, e)
})
}
/// assert!(env::var(key).is_err());
/// ```
#[stable(feature = "env", since = "1.0.0")]
-pub fn remove_var<K: AsRef<OsStr>>(k: K) {
- _remove_var(k.as_ref())
+pub fn remove_var<K: AsRef<OsStr>>(key: K) {
+ _remove_var(key.as_ref())
}
-fn _remove_var(k: &OsStr) {
- os_imp::unsetenv(k)
- .unwrap_or_else(|e| panic!("failed to remove environment variable `{:?}`: {}", k, e))
+fn _remove_var(key: &OsStr) {
+ os_imp::unsetenv(key)
+ .unwrap_or_else(|e| panic!("failed to remove environment variable `{:?}`: {}", key, e))
}
/// An iterator that splits an environment variable into paths according to
#![feature(const_cstr_unchecked)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_fn_transmute)]
-#![feature(const_fn)]
#![feature(const_fn_fn_ptr_basics)]
#![feature(const_io_structs)]
#![feature(const_ip)]
cargo.rustdocflag("--enable-index-page");
cargo.rustdocflag("-Zunstable-options");
cargo.rustdocflag("-Znormalize-docs");
+ cargo.rustdocflag("--show-type-layout");
compile::rustc_cargo(builder, &mut cargo, target);
// Only include compiler crates, no dependencies of those, such as `libc`.
cargo.rustdocflag("--document-private-items");
cargo.rustdocflag("--enable-index-page");
+ cargo.rustdocflag("--show-type-layout");
cargo.rustdocflag("-Zunstable-options");
builder.run(&mut cargo.into());
}
}
let out_dir = builder.test_out(self.target).join("rustdoc-gui");
- let mut command = builder.rustdoc_cmd(self.compiler);
- command.arg("src/test/rustdoc-gui/lib.rs").arg("-o").arg(&out_dir);
- builder.run(&mut command);
+ // We remove existing folder to be sure there won't be artifacts remaining.
+ let _ = fs::remove_dir_all(&out_dir);
+
+ // We generate docs for the libraries present in the rustdoc-gui's src folder.
+ let libs_dir = builder.build.src.join("src/test/rustdoc-gui/src");
+ for entry in libs_dir.read_dir().expect("read_dir call failed") {
+ let entry = entry.expect("invalid entry");
+ let path = entry.path();
+ if path.extension().map(|e| e == "rs").unwrap_or(false) {
+ let mut command = builder.rustdoc_cmd(self.compiler);
+ command.arg(path).arg("-o").arg(&out_dir);
+ builder.run(&mut command);
+ }
+ }
+
+ // We now run GUI tests.
let mut command = Command::new(&nodejs);
command
- .arg("src/tools/rustdoc-gui/tester.js")
+ .arg(builder.build.src.join("src/tools/rustdoc-gui/tester.js"))
.arg("--doc-folder")
- .arg(out_dir.join("test_docs"))
+ .arg(out_dir)
.arg("--tests-folder")
- .arg("src/test/rustdoc-gui");
+ .arg(builder.build.src.join("src/test/rustdoc-gui"));
builder.run(&mut command);
} else {
builder.info("No nodejs found, skipping \"src/test/rustdoc-gui\" tests");
# Download and build a single-file stress test benchmark on perf.rust-lang.org.
function pgo_perf_benchmark {
- local PERF=9442def56a39d742bf27ebcc3e0614cf117e1bc2
+ local PERF=1e19fc4c6168d2f7596e512f42f358f245d8f09d
local github_prefix=https://raw.githubusercontent.com/rust-lang/rustc-perf/$PERF
local name=$1
curl -o /tmp/$name.rs $github_prefix/collector/benchmarks/$name/src/lib.rs
+++ /dev/null
-# `const_fn`
-
-The tracking issue for this feature is: [#57563]
-
-[#57563]: https://github.com/rust-lang/rust/issues/57563
-
-------------------------
-
-The `const_fn` feature enables additional functionality not stabilized in the
-[minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555)
crate fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf {
match self.src(tcx) {
- FileName::Real(ref p) => match p.local_path().parent() {
+ FileName::Real(ref p) => match p.local_path_if_available().parent() {
Some(p) => p.to_path_buf(),
None => PathBuf::new(),
},
crate document_hidden: bool,
/// If `true`, generate a JSON file in the crate folder instead of HTML redirection files.
crate generate_redirect_map: bool,
+ /// Show the memory layout of types in the docs.
+ crate show_type_layout: bool,
crate unstable_features: rustc_feature::UnstableFeatures,
crate emit: Vec<EmitType>,
}
let document_hidden = matches.opt_present("document-hidden-items");
let run_check = matches.opt_present("check");
let generate_redirect_map = matches.opt_present("generate-redirect-map");
+ let show_type_layout = matches.opt_present("show-type-layout");
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
document_private,
document_hidden,
generate_redirect_map,
+ show_type_layout,
unstable_features: rustc_feature::UnstableFeatures::from_environment(
crate_name.as_deref(),
),
if !item_path.is_empty() {
item_path.push(' ');
}
- format!("{} - {}(line {})", filename, item_path, line)
+ format!("{} - {}(line {})", filename.prefer_local(), item_path, line)
}
crate fn set_position(&mut self, position: Span) {
let filename = source_map.span_to_filename(self.position);
if let FileName::Real(ref filename) = filename {
if let Ok(cur_dir) = env::current_dir() {
- if let Ok(path) = filename.local_path().strip_prefix(&cur_dir) {
- return path.to_owned().into();
+ if let Some(local_path) = filename.local_path() {
+ if let Ok(path) = local_path.strip_prefix(&cur_dir) {
+ return path.to_owned().into();
+ }
}
}
}
self.compiling_test_count.fetch_add(1, Ordering::SeqCst);
}
- // FIXME(#44940): if doctests ever support path remapping, then this filename
- // needs to be the result of `SourceMap::span_to_unmapped_path`.
let path = match &filename {
- FileName::Real(path) => path.local_path().to_path_buf(),
+ FileName::Real(path) => {
+ if let Some(local_path) = path.local_path() {
+ local_path.to_path_buf()
+ } else {
+ // Somehow we got the filename from the metadata of another crate, should never happen
+ unreachable!("doctest from a different crate");
+ }
+ }
_ => PathBuf::from(r"doctest.rs"),
};
// For example `module/file.rs` would become `module_file_rs`
let file = filename
- .to_string()
+ .prefer_local()
+ .to_string_lossy()
.chars()
.map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
.collect::<String>();
placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
type=\"search\">\
</div>\
- <button type=\"button\" class=\"help-button\">?</button>
+ <button type=\"button\" id=\"help-button\">?</button>
<a id=\"settings-menu\" href=\"{root_path}settings.html\">\
<img src=\"{static_root_path}wheel{suffix}.svg\" \
width=\"18\" height=\"18\" \
map.insert("theme-picker".to_owned(), 1);
map.insert("theme-choices".to_owned(), 1);
map.insert("settings-menu".to_owned(), 1);
+ map.insert("help-button".to_owned(), 1);
map.insert("main".to_owned(), 1);
map.insert("search".to_owned(), 1);
map.insert("crate-search".to_owned(), 1);
crate include_sources: bool,
/// The local file sources we've emitted and their respective url-paths.
crate local_sources: FxHashMap<PathBuf, String>,
+ /// Show the memory layout of types in the docs.
+ pub(super) show_type_layout: bool,
/// Whether the collapsed pass ran
collapsed: bool,
/// The base-URL of the issue tracker for when an item has been tagged with
Ok(())
}
- /// Based on whether the `collapse-docs` pass was run, return either the `doc_value` or the
- /// `collapsed_doc_value` of the given item.
+ /// Returns the `collapsed_doc_value` of the given item if this is the main crate, otherwise
+ /// returns the `doc_value`.
crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<String> {
if self.collapsed { item.collapsed_doc_value() } else { item.doc_value() }
}
// We can safely ignore synthetic `SourceFile`s.
let file = match item.span(self.tcx()).filename(self.sess()) {
- FileName::Real(ref path) => path.local_path().to_path_buf(),
+ FileName::Real(ref path) => path.local_path_if_available().to_path_buf(),
_ => return None,
};
let file = &file;
generate_search_filter,
unstable_features,
generate_redirect_map,
+ show_type_layout,
..
} = options;
let src_root = match krate.src {
- FileName::Real(ref p) => match p.local_path().parent() {
+ FileName::Real(ref p) => match p.local_path_if_available().parent() {
Some(p) => p.to_path_buf(),
None => PathBuf::new(),
},
all: RefCell::new(AllTypes::new()),
errors: receiver,
redirections: if generate_redirect_map { Some(Default::default()) } else { None },
+ show_type_layout,
};
// Add the default themes to the `Vec` of stylepaths
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::stability;
+use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::TyCtxt;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
document(w, cx, it, None);
+ let def_id = it.def_id.expect_real();
// Render any items associated directly to this alias, as otherwise they
// won't be visible anywhere in the docs. It would be nice to also show
// associated items from the aliased type (see discussion in #32077), but
// we need #14072 to make sense of the generics.
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All)
+ render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
}
fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
});
document(w, cx, it, None);
+
let mut fields = s
.fields
.iter()
document(w, cx, field, Some(it));
}
}
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All)
+ let def_id = it.def_id.expect_real();
+ render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
+ document_type_layout(w, cx, def_id);
}
fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) {
});
document(w, cx, it, None);
+
if !e.variants.is_empty() {
write!(
w,
render_stability_since(w, variant, it, cx.tcx());
}
}
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All)
+ let def_id = it.def_id.expect_real();
+ render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
+ document_type_layout(w, cx, def_id);
}
fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) {
});
document(w, cx, it, None);
+
let mut fields = s
.fields
.iter()
}
}
}
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All)
+ let def_id = it.def_id.expect_real();
+ render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
+ document_type_layout(w, cx, def_id);
}
fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
w.write_str("</div></details>");
}
}
+
+fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
+ if !cx.shared.show_type_layout {
+ return;
+ }
+
+ writeln!(w, "<h2 class=\"small-section-header\">Layout</h2>");
+ writeln!(w, "<div class=\"docblock\">");
+
+ let tcx = cx.tcx();
+ let param_env = tcx.param_env(ty_def_id);
+ let ty = tcx.type_of(ty_def_id);
+ match tcx.layout_of(param_env.and(ty)) {
+ Ok(ty_layout) => {
+ writeln!(
+ w,
+ "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \
+ completely unstable and may be different between compiler versions and platforms. \
+ The only exception is types with certain <code>repr(...)</code> attributes. \
+ Please see the Rust Reference’s \
+ <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \
+ chapter for details on type layout guarantees.</p></div>"
+ );
+ if ty_layout.layout.abi.is_unsized() {
+ writeln!(w, "<p><strong>Size:</strong> (unsized)</p>");
+ } else {
+ let bytes = ty_layout.layout.size.bytes();
+ writeln!(
+ w,
+ "<p><strong>Size:</strong> {size} byte{pl}</p>",
+ size = bytes,
+ pl = if bytes == 1 { "" } else { "s" },
+ );
+ }
+ }
+ // This kind of layout error can occur with valid code, e.g. if you try to
+ // get the layout of a generic type such as `Vec<T>`.
+ Err(LayoutError::Unknown(_)) => {
+ writeln!(
+ w,
+ "<p><strong>Note:</strong> Unable to compute type layout, \
+ possibly due to this type having generic parameters. \
+ Layout can only be computed for concrete, fully-instantiated types.</p>"
+ );
+ }
+ // This kind of error probably can't happen with valid code, but we don't
+ // want to panic and prevent the docs from building, so we just let the
+ // user know that we couldn't compute the layout.
+ Err(LayoutError::SizeOverflow(_)) => {
+ writeln!(
+ w,
+ "<p><strong>Note:</strong> Encountered an error during type layout; \
+ the type was too big.</p>"
+ );
+ }
+ }
+
+ writeln!(w, "</div>");
+}
Err(e) => {
self.scx.tcx.sess.span_err(
item.span(self.scx.tcx).inner(),
- &format!("failed to render source code for `{}`: {}", filename, e),
+ &format!(
+ "failed to render source code for `{}`: {}",
+ filename.prefer_local(),
+ e
+ ),
);
false
}
/// Renders the given filename into its corresponding HTML source file.
fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
let p = match *filename {
- FileName::Real(ref file) => file.local_path().to_path_buf(),
+ FileName::Real(ref file) => {
+ if let Some(local_path) = file.local_path() {
+ local_path.to_path_buf()
+ } else {
+ unreachable!("only the current crate should have sources emitted");
+ }
+ }
_ => return Ok(()),
};
if self.scx.local_sources.contains_key(&*p) {
href.push_str(&fname.to_string_lossy());
let title = format!("{} - source", src_fname.to_string_lossy());
- let desc = format!("Source of the Rust file `{}`.", filename);
+ let desc = format!("Source of the Rust file `{}`.", filename.prefer_remapped());
let page = layout::Page {
title: &title,
css_class: "source",
}
}
- function highlightSourceLines(match, ev) {
- if (typeof match === "undefined") {
- // If we're in mobile mode, we should hide the sidebar in any case.
- hideSidebar();
- match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
- }
- if (!match) {
- return;
- }
- var from = parseInt(match[1], 10);
- var to = from;
- if (typeof match[2] !== "undefined") {
- to = parseInt(match[2], 10);
- }
- if (to < from) {
- var tmp = to;
- to = from;
- from = tmp;
- }
- var elem = document.getElementById(from);
- if (!elem) {
- return;
- }
- if (!ev) {
- var x = document.getElementById(from);
- if (x) {
- x.scrollIntoView();
- }
- }
- onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
- onEachLazy(e.getElementsByTagName("span"), function(i_e) {
- removeClass(i_e, "line-highlighted");
- });
- });
- for (var i = from; i <= to; ++i) {
- elem = document.getElementById(i);
- if (!elem) {
- break;
- }
- addClass(elem, "line-highlighted");
- }
- }
-
function onHashChange(ev) {
// If we're in mobile mode, we should hide the sidebar in any case.
hideSidebar();
- var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
- if (match) {
- return highlightSourceLines(match, ev);
- }
handleHashes(ev);
}
}
function getHelpElement(build) {
- if (build !== false) {
+ if (build) {
buildHelperPopup();
}
return document.getElementById("help");
}
function displayHelp(display, ev, help) {
- if (display === true) {
+ if (display) {
help = help ? help : getHelpElement(true);
if (hasClass(help, "hidden")) {
ev.preventDefault();
// No need to build the help popup if we want to hide it in case it hasn't been
// built yet...
help = help ? help : getHelpElement(false);
- if (help && hasClass(help, "hidden") === false) {
+ if (help && !hasClass(help, "hidden")) {
ev.preventDefault();
addClass(help, "hidden");
removeClass(document.body, "blur");
function handleEscape(ev) {
var help = getHelpElement(false);
var search = searchState.outputElement();
- if (hasClass(help, "hidden") === false) {
+ if (!hasClass(help, "hidden")) {
displayHelp(false, ev, help);
- } else if (hasClass(search, "hidden") === false) {
+ } else if (!hasClass(search, "hidden")) {
searchState.clearInputTimeout();
ev.preventDefault();
searchState.hideResults(search);
var disableShortcuts = getSettingValue("disable-shortcuts") === "true";
function handleShortcut(ev) {
// Don't interfere with browser shortcuts
- if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts === true) {
+ if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {
return;
}
}
}
- function findParentElement(elem, tagName) {
- do {
- if (elem && elem.tagName === tagName) {
- return elem;
- }
- elem = elem.parentNode;
- } while (elem);
- return null;
- }
-
document.addEventListener("keypress", handleShortcut);
document.addEventListener("keydown", handleShortcut);
- var handleSourceHighlight = (function() {
- var prev_line_id = 0;
-
- var set_fragment = function(name) {
- var x = window.scrollX,
- y = window.scrollY;
- if (searchState.browserSupportsHistoryApi()) {
- history.replaceState(null, null, "#" + name);
- highlightSourceLines();
- } else {
- location.replace("#" + name);
- }
- // Prevent jumps when selecting one or many lines
- window.scrollTo(x, y);
- };
-
- return function(ev) {
- var cur_line_id = parseInt(ev.target.id, 10);
- ev.preventDefault();
-
- if (ev.shiftKey && prev_line_id) {
- // Swap selection if needed
- if (prev_line_id > cur_line_id) {
- var tmp = prev_line_id;
- prev_line_id = cur_line_id;
- cur_line_id = tmp;
- }
-
- set_fragment(prev_line_id + "-" + cur_line_id);
- } else {
- prev_line_id = cur_line_id;
-
- set_fragment(cur_line_id);
- }
- };
- }());
-
- document.addEventListener("click", function(ev) {
- var helpElem = getHelpElement(false);
- if (hasClass(ev.target, "help-button")) {
- displayHelp(true, ev);
- } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) {
- handleSourceHighlight(ev);
- } else if (helpElem && hasClass(helpElem, "hidden") === false) {
- var is_inside_help_popup = ev.target !== helpElem && helpElem.contains(ev.target);
- if (is_inside_help_popup === false) {
- addClass(helpElem, "hidden");
- removeClass(document.body, "blur");
- }
- } else {
- // Making a collapsed element visible on onhashchange seems
- // too late
- var a = findParentElement(ev.target, "A");
- if (a && a.hash) {
- expandSection(a.hash.replace(/^#/, ""));
- }
- }
- });
-
(function() {
var x = document.getElementsByClassName("version-selector");
if (x.length > 0) {
function implHider(addOrRemove, fullHide) {
return function(n) {
var shouldHide =
- fullHide === true ||
- hasClass(n, "method") === true ||
- hasClass(n, "associatedconstant") === true;
- if (shouldHide === true || hasClass(n, "type") === true) {
- if (shouldHide === true) {
+ fullHide ||
+ hasClass(n, "method") ||
+ hasClass(n, "associatedconstant");
+ if (shouldHide || hasClass(n, "type")) {
+ if (shouldHide) {
if (addOrRemove) {
addClass(n, "hidden-by-impl-hider");
} else {
var relatedDoc;
var action = mode;
- if (hasClass(toggle.parentNode, "impl") === false) {
+ if (!hasClass(toggle.parentNode, "impl")) {
relatedDoc = toggle.parentNode.nextElementSibling;
if (hasClass(relatedDoc, "item-info")) {
relatedDoc = relatedDoc.nextElementSibling;
relatedDoc = parentElem;
var docblock = relatedDoc.nextElementSibling;
- while (hasClass(relatedDoc, "impl-items") === false) {
+ while (!hasClass(relatedDoc, "impl-items")) {
relatedDoc = relatedDoc.nextElementSibling;
}
- if (!relatedDoc && hasClass(docblock, "docblock") === false) {
+ if (!relatedDoc && !hasClass(docblock, "docblock")) {
return;
}
if (action === "show") {
removeClass(relatedDoc, "fns-now-collapsed");
// Stability/deprecation/portability information is never hidden.
- if (hasClass(docblock, "item-info") === false) {
+ if (!hasClass(docblock, "item-info")) {
removeClass(docblock, "hidden-by-usual-hider");
}
onEachLazy(toggle.childNodes, adjustToggle(false, dontApplyBlockRule));
addClass(relatedDoc, "fns-now-collapsed");
// Stability/deprecation/portability information should be shown even when detailed
// info is hidden.
- if (hasClass(docblock, "item-info") === false) {
+ if (!hasClass(docblock, "item-info")) {
addClass(docblock, "hidden-by-usual-hider");
}
onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule));
});
}
- if (hideMethodDocs === true) {
+ if (hideMethodDocs) {
onEachLazy(document.getElementsByClassName("method"), function(e) {
var toggle = e.parentNode;
if (toggle) {
});
}());
+ function handleClick(id, f) {
+ var elem = document.getElementById(id);
+ if (elem) {
+ elem.addEventListener("click", f);
+ }
+ }
+ handleClick("help-button", function(ev) {
+ displayHelp(true, ev);
+ });
+
+ onEachLazy(document.getElementsByTagName("a"), function(el) {
+ // For clicks on internal links (<A> tags with a hash property), we expand the section we're
+ // jumping to *before* jumping there. We can't do this in onHashChange, because it changes
+ // the height of the document so we wind up scrolled to the wrong place.
+ if (el.hash) {
+ el.addEventListener("click", function() {
+ expandSection(el.hash.slice(1));
+ });
+ }
+ });
+
onEachLazy(document.getElementsByClassName("notable-traits"), function(e) {
e.onclick = function() {
this.getElementsByClassName('notable-traits-tooltiptext')[0]
if (sidebar_menu) {
sidebar_menu.onclick = function() {
var sidebar = document.getElementsByClassName("sidebar")[0];
- if (hasClass(sidebar, "mobile") === true) {
+ if (hasClass(sidebar, "mobile")) {
hideSidebar();
} else {
showSidebar();
addClass(popup, "hidden");
popup.id = "help";
+ popup.addEventListener("click", function(ev) {
+ if (ev.target === popup) {
+ // Clicked the blurred zone outside the help popup; dismiss help.
+ displayHelp(false, ev);
+ }
+ });
+
var book_info = document.createElement("span");
book_info.innerHTML = "You can find more information in \
<a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
}
onHashChange(null);
- window.onhashchange = onHashChange;
+ window.addEventListener("hashchange", onHashChange);
searchState.setup();
}());
outline: none;
}
-#settings-menu, .help-button {
+#settings-menu, #help-button {
position: absolute;
top: 10px;
}
outline: none;
}
-#theme-picker, #settings-menu, .help-button, #copy-path {
+#theme-picker, #settings-menu, #help-button, #copy-path {
padding: 4px;
width: 27px;
height: 29px;
cursor: pointer;
}
-.help-button {
+#help-button {
right: 30px;
font-family: "Fira Sans", Arial, sans-serif;
text-align: center;
}
/* We don't display the help button on mobile devices. */
- .help-button {
+ #help-button {
display: none;
}
.search-container > div {
removeEmptyStringsFromArray(split);
- function transformResults(results, isType) {
+ function transformResults(results) {
var out = [];
for (var i = 0, len = results.length; i < len; ++i) {
if (results[i].id > -1) {
var obj = searchIndex[results[i].id];
obj.lev = results[i].lev;
- if (isType !== true || obj.type) {
- var res = buildHrefAndPath(obj);
- obj.displayPath = pathSplitter(res[0]);
- obj.fullPath = obj.displayPath + obj.name;
- // To be sure than it some items aren't considered as duplicate.
- obj.fullPath += "|" + obj.ty;
- obj.href = res[1];
- out.push(obj);
- if (out.length >= MAX_RESULTS) {
- break;
- }
+ var res = buildHrefAndPath(obj);
+ obj.displayPath = pathSplitter(res[0]);
+ obj.fullPath = obj.displayPath + obj.name;
+ // To be sure than it some items aren't considered as duplicate.
+ obj.fullPath += "|" + obj.ty;
+ obj.href = res[1];
+ out.push(obj);
+ if (out.length >= MAX_RESULTS) {
+ break;
}
}
}
path = result.item.path.toLowerCase(),
parent = result.item.parent;
- if (isType !== true &&
- validateResult(name, path, split, parent) === false)
- {
+ if (!isType && !validateResult(name, path, split, parent)) {
result.id = -1;
}
}
var lev_distance = MAX_LEV_DISTANCE + 1;
var len, x, firstGeneric;
if (obj[NAME] === val.name) {
- if (literalSearch === true) {
+ if (literalSearch) {
if (val.generics && val.generics.length !== 0) {
if (obj.length > GENERICS_DATA &&
obj[GENERICS_DATA].length >= val.generics.length) {
break;
}
}
- if (allFound === true) {
+ if (allFound) {
return true;
}
} else {
}
}
// Names didn't match so let's check if one of the generic types could.
- if (literalSearch === true) {
+ if (literalSearch) {
if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) {
return obj[GENERICS_DATA].some(
function(name) {
var length = obj.type[INPUTS_DATA].length;
for (var i = 0; i < length; i++) {
var tmp = obj.type[INPUTS_DATA][i];
- if (typePassesFilter(typeFilter, tmp[1]) === false) {
+ if (!typePassesFilter(typeFilter, tmp[1])) {
continue;
}
tmp = checkType(tmp, val, literalSearch);
- if (literalSearch === true) {
- if (tmp === true) {
+ if (literalSearch) {
+ if (tmp) {
return true;
}
continue;
}
}
}
- return literalSearch === true ? false : lev_distance;
+ return literalSearch ? false : lev_distance;
}
function checkReturned(obj, val, literalSearch, typeFilter) {
}
for (var x = 0, len = ret.length; x < len; ++x) {
var tmp = ret[x];
- if (typePassesFilter(typeFilter, tmp[1]) === false) {
+ if (!typePassesFilter(typeFilter, tmp[1])) {
continue;
}
tmp = checkType(tmp, val, literalSearch);
- if (literalSearch === true) {
- if (tmp === true) {
+ if (literalSearch) {
+ if (tmp) {
return true;
}
continue;
}
}
}
- return literalSearch === true ? false : lev_distance;
+ return literalSearch ? false : lev_distance;
}
function checkPath(contains, lastElem, ty) {
}
lev_total += lev;
}
- if (aborted === false) {
+ if (!aborted) {
ret_lev = Math.min(ret_lev, Math.round(lev_total / clength));
}
}
dontValidate: true,
};
}
- if (in_args === true && results_in_args[fullId] === undefined) {
+ if (in_args && results_in_args[fullId] === undefined) {
results_in_args[fullId] = {
id: i,
index: -1,
dontValidate: true,
};
}
- if (returned === true && results_returned[fullId] === undefined) {
+ if (returned && results_returned[fullId] === undefined) {
results_returned[fullId] = {
id: i,
index: -1,
fullId = ty.id;
returned = checkReturned(ty, output, true, NO_TYPE_FILTER);
- if (output.name === "*" || returned === true) {
+ if (output.name === "*" || returned) {
in_args = false;
var is_module = false;
is_module = true;
} else {
var allFound = true;
- for (it = 0, len = inputs.length; allFound === true && it < len; it++) {
+ for (it = 0, len = inputs.length; allFound && it < len; it++) {
allFound = checkType(type, inputs[it], true);
}
in_args = allFound;
}
- if (in_args === true) {
+ if (in_args) {
results_in_args[fullId] = {
id: i,
index: -1,
dontValidate: true,
};
}
- if (returned === true) {
+ if (returned) {
results_returned[fullId] = {
id: i,
index: -1,
dontValidate: true,
};
}
- if (is_module === true) {
+ if (is_module) {
results[fullId] = {
id: i,
index: -1,
}
}
if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) {
- if (typePassesFilter(typeFilter, ty.ty) === false) {
- lev = MAX_LEV_DISTANCE + 1;
- } else {
+ if (typePassesFilter(typeFilter, ty.ty)) {
lev += 1;
+ } else {
+ lev = MAX_LEV_DISTANCE + 1;
}
}
in_args = findArg(ty, valGenerics, false, typeFilter);
var ret = {
"in_args": sortResults(results_in_args, true),
"returned": sortResults(results_returned, true),
- "others": sortResults(results),
+ "others": sortResults(results, false),
};
handleAliases(ret, query, filterCrates);
return ret;
if (query.query.length === 0) {
return;
}
- if (forced !== true && query.id === currentResults) {
+ if (!forced && query.id === currentResults) {
if (query.query.length > 0) {
searchState.putBackSearch(searchState.input);
}
// Local js definitions:
/* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */
+(function() {
function getCurrentFilePath() {
var parts = window.location.pathname.split("/");
if (elem.dirs) {
for (i = 0, len = elem.dirs.length; i < len; ++i) {
if (createDirEntry(elem.dirs[i], folders, fullPath, currentFile,
- hasFoundFile) === true) {
+ hasFoundFile)) {
addClass(name, "expand");
hasFoundFile = true;
}
var file = document.createElement("a");
file.innerText = elem.files[i];
file.href = window.rootPath + "src/" + fullPath + elem.files[i] + ".html";
- if (hasFoundFile === false &&
- currentFile === fullPath + elem.files[i]) {
+ if (!hasFoundFile && currentFile === fullPath + elem.files[i]) {
file.className = "selected";
addClass(name, "expand");
hasFoundFile = true;
children.appendChild(files);
parent.appendChild(name);
parent.appendChild(children);
- return hasFoundFile === true && currentFile.startsWith(fullPath);
+ return hasFoundFile && currentFile.startsWith(fullPath);
}
function toggleSidebar() {
// This function is called from "source-files.js", generated in `html/render/mod.rs`.
// eslint-disable-next-line no-unused-vars
function createSourceSidebar() {
- if (window.rootPath.endsWith("/") === false) {
+ if (!window.rootPath.endsWith("/")) {
window.rootPath += "/";
}
var main = document.getElementById("main");
selected_elem.focus();
}
}
+
+var lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/;
+
+function highlightSourceLines(match, ev) {
+ if (typeof match === "undefined") {
+ match = window.location.hash.match(lineNumbersRegex);
+ }
+ if (!match) {
+ return;
+ }
+ var from = parseInt(match[1], 10);
+ var to = from;
+ if (typeof match[2] !== "undefined") {
+ to = parseInt(match[2], 10);
+ }
+ if (to < from) {
+ var tmp = to;
+ to = from;
+ from = tmp;
+ }
+ var elem = document.getElementById(from);
+ if (!elem) {
+ return;
+ }
+ if (!ev) {
+ var x = document.getElementById(from);
+ if (x) {
+ x.scrollIntoView();
+ }
+ }
+ onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
+ onEachLazy(e.getElementsByTagName("span"), function(i_e) {
+ removeClass(i_e, "line-highlighted");
+ });
+ });
+ for (var i = from; i <= to; ++i) {
+ elem = document.getElementById(i);
+ if (!elem) {
+ break;
+ }
+ addClass(elem, "line-highlighted");
+ }
+}
+
+var handleSourceHighlight = (function() {
+ var prev_line_id = 0;
+
+ var set_fragment = function(name) {
+ var x = window.scrollX,
+ y = window.scrollY;
+ if (searchState.browserSupportsHistoryApi()) {
+ history.replaceState(null, null, "#" + name);
+ highlightSourceLines();
+ } else {
+ location.replace("#" + name);
+ }
+ // Prevent jumps when selecting one or many lines
+ window.scrollTo(x, y);
+ };
+
+ return function(ev) {
+ var cur_line_id = parseInt(ev.target.id, 10);
+ ev.preventDefault();
+
+ if (ev.shiftKey && prev_line_id) {
+ // Swap selection if needed
+ if (prev_line_id > cur_line_id) {
+ var tmp = prev_line_id;
+ prev_line_id = cur_line_id;
+ cur_line_id = tmp;
+ }
+
+ set_fragment(prev_line_id + "-" + cur_line_id);
+ } else {
+ prev_line_id = cur_line_id;
+
+ set_fragment(cur_line_id);
+ }
+ };
+}());
+
+window.addEventListener("hashchange", function() {
+ var match = window.location.hash.match(lineNumbersRegex);
+ if (match) {
+ return highlightSourceLines(match, ev);
+ }
+});
+
+onEachLazy(document.getElementsByClassName("line-numbers"), function(el) {
+ el.addEventListener("click", handleSourceHighlight);
+});
+
+highlightSourceLines();
+
+window.createSourceSidebar = createSourceSidebar;
+})();
if (arr && arr.length > 0 && func) {
var length = arr.length;
var i;
- if (reversed !== true) {
- for (i = 0; i < length; ++i) {
- if (func(arr[i]) === true) {
+ if (reversed) {
+ for (i = length - 1; i >= 0; --i) {
+ if (func(arr[i])) {
return true;
}
}
} else {
- for (i = length - 1; i >= 0; --i) {
- if (func(arr[i]) === true) {
+ for (i = 0; i < length; ++i) {
+ if (func(arr[i])) {
return true;
}
}
// If this new value comes from a system setting or from the previously
// saved theme, no need to save it.
- if (saveTheme === true) {
+ if (saveTheme) {
updateLocalStorage("rustdoc-theme", newTheme);
}
return true;
}
});
- if (found === true) {
+ if (found) {
styleElem.href = newHref;
}
}
box-shadow-color: #c6cbd1;
}
-#theme-picker, #settings-menu, .help-button, #copy-path {
+#theme-picker, #settings-menu, #help-button, #copy-path {
border-color: #5c6773;
background-color: #0f1419;
color: #fff;
#theme-picker:hover, #theme-picker:focus,
#settings-menu:hover, #settings-menu:focus,
-.help-button:hover, .help-button:focus,
+#help-button:hover, #help-button:focus,
#copy-path:hover, #copy-path:focus {
border-color: #e0e0e0;
}
box-shadow-color: #c6cbd1;
}
-#theme-picker, #settings-menu, .help-button, #copy-path {
+#theme-picker, #settings-menu, #help-button, #copy-path {
border-color: #e0e0e0;
background: #f0f0f0;
color: #000;
#theme-picker:hover, #theme-picker:focus,
#settings-menu:hover, #settings-menu:focus,
-.help-button:hover, .help-button:focus,
+#help-button:hover, #help-button:focus,
#copy-path:hover, #copy-path:focus {
border-color: #ffb900;
}
box-shadow-color: #c6cbd1;
}
-#theme-picker, #settings-menu, .help-button, #copy-path {
+#theme-picker, #settings-menu, #help-button, #copy-path {
border-color: #e0e0e0;
background-color: #fff;
}
#theme-picker:hover, #theme-picker:focus,
#settings-menu:hover, #settings-menu:focus,
-.help-button:hover, .help-button:focus,
+#help-button:hover, #help-button:focus,
#copy-path:hover, #copy-path:focus {
border-color: #717171;
}
fn convert_span(&self, span: clean::Span) -> Option<Span> {
match span.filename(self.sess()) {
rustc_span::FileName::Real(name) => {
- let hi = span.hi(self.sess());
- let lo = span.lo(self.sess());
- Some(Span {
- filename: match name {
- rustc_span::RealFileName::Named(path) => path,
- rustc_span::RealFileName::Devirtualized { local_path, virtual_name: _ } => {
- local_path
- }
- },
- begin: (lo.line, lo.col.to_usize()),
- end: (hi.line, hi.col.to_usize()),
- })
+ if let Some(local_path) = name.into_local_path() {
+ let hi = span.hi(self.sess());
+ let lo = span.lo(self.sess());
+ Some(Span {
+ filename: local_path,
+ begin: (lo.line, lo.col.to_usize()),
+ end: (hi.line, hi.col.to_usize()),
+ })
+ } else {
+ None
+ }
}
_ => None,
}
)
}),
unstable("no-run", |o| o.optflag("", "no-run", "Compile doctests without running them")),
+ unstable("show-type-layout", |o| {
+ o.optflag("", "show-type-layout", "Include the memory layout of types in the docs")
+ }),
]
}
&self
.items
.iter()
- .map(|(k, v)| (k.to_string(), v))
+ .map(|(k, v)| (k.prefer_local().to_string(), v))
.collect::<BTreeMap<String, &ItemCount>>(),
)
.expect("failed to convert JSON data to string")
for (file, &count) in &self.items {
if let Some(percentage) = count.percentage() {
print_table_record(
- &limit_filename_len(file.to_string()),
+ &limit_filename_len(file.prefer_local().to_string_lossy().into()),
count,
percentage,
count.examples_percentage().unwrap_or(0.),
// unless the user had an explicit `allow`
let should_have_docs =
level != lint::Level::Allow || matches!(source, LintLevelSource::Default);
- debug!("counting {:?} {:?} in {}", i.type_(), i.name, filename);
+ debug!("counting {:?} {:?} in {:?}", i.type_(), i.name, filename);
self.items.entry(filename).or_default().count_item(
has_docs,
has_doc_example,
--- /dev/null
+// ignore-windows
+
+// compile-flags: -g -C no-prepopulate-passes -Z simulate-remapped-rust-src-base=/rustc/xyz
+
+// Here we check that importing std will not cause real path to std source files
+// to leak. If rustc was compiled with remap-debuginfo = true, this should be
+// true automatically. If paths to std library hasn't been remapped, we use the
+// above simulate-remapped-rust-src-base option to do it temporarily
+
+// CHECK: !DIFile(filename: "{{/rustc/.*/library/std/src/panic.rs}}"
+fn main() {
+ std::thread::spawn(|| {
+ println!("hello");
+ });
+}
--- /dev/null
+// MIR for `array_casts` after SimplifyCfg-elaborate-drops
+
+fn array_casts() -> () {
+ let mut _0: (); // return place in scope 0 at $DIR/retag.rs:57:18: 57:18
+ let mut _1: [usize; 2]; // in scope 0 at $DIR/retag.rs:58:9: 58:14
+ let mut _3: *mut [usize; 2]; // in scope 0 at $DIR/retag.rs:59:13: 59:19
+ let mut _4: &mut [usize; 2]; // in scope 0 at $DIR/retag.rs:59:13: 59:19
+ let _5: (); // in scope 0 at $DIR/retag.rs:60:5: 60:30
+ let mut _6: *mut usize; // in scope 0 at $DIR/retag.rs:60:15: 60:23
+ let mut _7: *mut usize; // in scope 0 at $DIR/retag.rs:60:15: 60:16
+ let mut _10: *const [usize; 2]; // in scope 0 at $DIR/retag.rs:63:13: 63:15
+ let _11: &[usize; 2]; // in scope 0 at $DIR/retag.rs:63:13: 63:15
+ let _12: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _13: (&usize, &usize); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _14: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _15: usize; // in scope 0 at $DIR/retag.rs:64:16: 64:36
+ let mut _16: *const usize; // in scope 0 at $DIR/retag.rs:64:26: 64:34
+ let mut _17: *const usize; // in scope 0 at $DIR/retag.rs:64:26: 64:27
+ let mut _18: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _19: usize; // in scope 0 at $DIR/retag.rs:64:38: 64:39
+ let mut _22: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _23: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _24: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _25: usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _26: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _28: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _29: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _30: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _31: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _33: &usize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _34: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 1 {
+ debug x => _1; // in scope 1 at $DIR/retag.rs:58:9: 58:14
+ let _2: *mut usize; // in scope 1 at $DIR/retag.rs:59:9: 59:10
+ scope 2 {
+ debug p => _2; // in scope 2 at $DIR/retag.rs:59:9: 59:10
+ let _8: [usize; 2]; // in scope 2 at $DIR/retag.rs:62:9: 62:10
+ scope 3 {
+ }
+ scope 4 {
+ debug x => _8; // in scope 4 at $DIR/retag.rs:62:9: 62:10
+ let _9: *const usize; // in scope 4 at $DIR/retag.rs:63:9: 63:10
+ scope 5 {
+ debug p => _9; // in scope 5 at $DIR/retag.rs:63:9: 63:10
+ let _20: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _21: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let mut _35: &usize; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 6 {
+ }
+ scope 7 {
+ debug left_val => _20; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ debug right_val => _21; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ let _27: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ scope 8 {
+ debug kind => _27; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+ }
+ }
+ }
+ }
+ }
+
+ bb0: {
+ StorageLive(_1); // scope 0 at $DIR/retag.rs:58:9: 58:14
+ _1 = [const 0_usize, const 0_usize]; // scope 0 at $DIR/retag.rs:58:29: 58:35
+ StorageLive(_2); // scope 1 at $DIR/retag.rs:59:9: 59:10
+ StorageLive(_3); // scope 1 at $DIR/retag.rs:59:13: 59:19
+ StorageLive(_4); // scope 1 at $DIR/retag.rs:59:13: 59:19
+ _4 = &mut _1; // scope 1 at $DIR/retag.rs:59:13: 59:19
+ Retag(_4); // scope 1 at $DIR/retag.rs:59:13: 59:19
+ _3 = &raw mut (*_4); // scope 1 at $DIR/retag.rs:59:13: 59:19
+ Retag([raw] _3); // scope 1 at $DIR/retag.rs:59:13: 59:19
+ _2 = move _3 as *mut usize (Pointer(ArrayToPointer)); // scope 1 at $DIR/retag.rs:59:13: 59:33
+ StorageDead(_3); // scope 1 at $DIR/retag.rs:59:32: 59:33
+ StorageDead(_4); // scope 1 at $DIR/retag.rs:59:33: 59:34
+ StorageLive(_5); // scope 2 at $DIR/retag.rs:60:5: 60:30
+ StorageLive(_6); // scope 3 at $DIR/retag.rs:60:15: 60:23
+ StorageLive(_7); // scope 3 at $DIR/retag.rs:60:15: 60:16
+ _7 = _2; // scope 3 at $DIR/retag.rs:60:15: 60:16
+ _6 = ptr::mut_ptr::<impl *mut usize>::add(move _7, const 1_usize) -> bb1; // scope 3 at $DIR/retag.rs:60:15: 60:23
+ // mir::Constant
+ // + span: $DIR/retag.rs:60:17: 60:20
+ // + literal: Const { ty: unsafe fn(*mut usize, usize) -> *mut usize {std::ptr::mut_ptr::<impl *mut usize>::add}, val: Value(Scalar(<ZST>)) }
+ }
+
+ bb1: {
+ StorageDead(_7); // scope 3 at $DIR/retag.rs:60:22: 60:23
+ (*_6) = const 1_usize; // scope 3 at $DIR/retag.rs:60:14: 60:27
+ StorageDead(_6); // scope 3 at $DIR/retag.rs:60:27: 60:28
+ _5 = const (); // scope 3 at $DIR/retag.rs:60:5: 60:30
+ StorageDead(_5); // scope 2 at $DIR/retag.rs:60:29: 60:30
+ StorageLive(_8); // scope 2 at $DIR/retag.rs:62:9: 62:10
+ _8 = [const 0_usize, const 1_usize]; // scope 2 at $DIR/retag.rs:62:25: 62:31
+ StorageLive(_9); // scope 4 at $DIR/retag.rs:63:9: 63:10
+ StorageLive(_10); // scope 4 at $DIR/retag.rs:63:13: 63:15
+ StorageLive(_11); // scope 4 at $DIR/retag.rs:63:13: 63:15
+ _11 = &_8; // scope 4 at $DIR/retag.rs:63:13: 63:15
+ Retag(_11); // scope 4 at $DIR/retag.rs:63:13: 63:15
+ _10 = &raw const (*_11); // scope 4 at $DIR/retag.rs:63:13: 63:15
+ Retag([raw] _10); // scope 4 at $DIR/retag.rs:63:13: 63:15
+ _9 = move _10 as *const usize (Pointer(ArrayToPointer)); // scope 4 at $DIR/retag.rs:63:13: 63:31
+ StorageDead(_10); // scope 4 at $DIR/retag.rs:63:30: 63:31
+ StorageDead(_11); // scope 4 at $DIR/retag.rs:63:31: 63:32
+ StorageLive(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_15); // scope 5 at $DIR/retag.rs:64:16: 64:36
+ StorageLive(_16); // scope 6 at $DIR/retag.rs:64:26: 64:34
+ StorageLive(_17); // scope 6 at $DIR/retag.rs:64:26: 64:27
+ _17 = _9; // scope 6 at $DIR/retag.rs:64:26: 64:27
+ _16 = ptr::const_ptr::<impl *const usize>::add(move _17, const 1_usize) -> bb2; // scope 6 at $DIR/retag.rs:64:26: 64:34
+ // mir::Constant
+ // + span: $DIR/retag.rs:64:28: 64:31
+ // + literal: Const { ty: unsafe fn(*const usize, usize) -> *const usize {std::ptr::const_ptr::<impl *const usize>::add}, val: Value(Scalar(<ZST>)) }
+ }
+
+ bb2: {
+ StorageDead(_17); // scope 6 at $DIR/retag.rs:64:33: 64:34
+ _15 = (*_16); // scope 6 at $DIR/retag.rs:64:25: 64:34
+ _14 = &_15; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _35 = const array_casts::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // ty::Const
+ // + ty: &usize
+ // + val: Unevaluated(array_casts, [], Some(promoted[0]))
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: &usize, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:15 ~ retag[317d]::array_casts), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
+ Retag(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _18 = &(*_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _13 = (move _14, move _18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _20 = (_13.0: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _21 = (_13.1: &usize); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _24 = (*_20); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _25 = (*_21); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _23 = Eq(move _24, move _25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_25); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_24); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _22 = Not(move _23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_23); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _22) -> [false: bb4, otherwise: bb3]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ }
+
+ bb3: {
+ StorageLive(_27); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _27 = core::panicking::AssertKind::Eq; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_28); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_29); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _29 = move _27; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _31 = &(*_20); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _30 = &(*_31); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_30); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _33 = &(*_21); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _32 = &(*_33); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ Retag(_32); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // mir::Constant
+ // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r usize, &'s usize, std::option::Option<std::fmt::Arguments<'t0>>) -> ! {core::panicking::assert_failed::<usize, usize>}, val: Value(Scalar(<ZST>)) }
+ }
+
+ bb4: {
+ _12 = const (); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_22); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_12); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _0 = const (); // scope 0 at $DIR/retag.rs:57:18: 65:2
+ StorageDead(_9); // scope 4 at $DIR/retag.rs:65:1: 65:2
+ StorageDead(_8); // scope 2 at $DIR/retag.rs:65:1: 65:2
+ StorageDead(_2); // scope 1 at $DIR/retag.rs:65:1: 65:2
+ StorageDead(_1); // scope 0 at $DIR/retag.rs:65:1: 65:2
+ return; // scope 0 at $DIR/retag.rs:65:2: 65:2
+ }
+}
let _23: &i32; // in scope 0 at $DIR/retag.rs:47:21: 47:23
let _24: i32; // in scope 0 at $DIR/retag.rs:47:22: 47:23
let mut _26: *const i32; // in scope 0 at $DIR/retag.rs:50:14: 50:28
+ let _27: (); // in scope 0 at $DIR/retag.rs:52:5: 52:18
scope 1 {
debug x => _1; // in scope 1 at $DIR/retag.rs:30:9: 30:14
let _3: &mut i32; // in scope 1 at $DIR/retag.rs:32:13: 32:14
scope 7 {
debug _w => _15; // in scope 7 at $DIR/retag.rs:44:9: 44:11
let _25: *const i32; // in scope 7 at $DIR/retag.rs:50:9: 50:11
- let mut _27: &i32; // in scope 7 at $DIR/retag.rs:47:21: 47:23
+ let mut _28: &i32; // in scope 7 at $DIR/retag.rs:47:21: 47:23
scope 8 {
debug _w => _25; // in scope 8 at $DIR/retag.rs:50:9: 50:11
}
Retag(_7); // scope 1 at $DIR/retag.rs:32:29: 32:35
_6 = &mut (*_7); // scope 1 at $DIR/retag.rs:32:29: 32:35
Retag([2phase] _6); // scope 1 at $DIR/retag.rs:32:29: 32:35
- _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb7]; // scope 1 at $DIR/retag.rs:32:17: 32:36
+ _3 = Test::foo(move _4, move _6) -> [return: bb1, unwind: bb8]; // scope 1 at $DIR/retag.rs:32:17: 32:36
// mir::Constant
// + span: $DIR/retag.rs:32:25: 32:28
// + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x mut i32) -> &'x mut i32 {Test::foo}, val: Value(Scalar(<ZST>)) }
StorageDead(_6); // scope 1 at $DIR/retag.rs:32:35: 32:36
StorageDead(_4); // scope 1 at $DIR/retag.rs:32:35: 32:36
StorageDead(_7); // scope 1 at $DIR/retag.rs:32:36: 32:37
- drop(_5) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/retag.rs:32:36: 32:37
+ drop(_5) -> [return: bb2, unwind: bb9]; // scope 1 at $DIR/retag.rs:32:36: 32:37
}
bb2: {
Retag(_20); // scope 7 at $DIR/retag.rs:47:5: 47:12
StorageLive(_22); // scope 7 at $DIR/retag.rs:47:21: 47:23
StorageLive(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23
- _27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23
+ _28 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23
// ty::Const
// + ty: &i32
// + val: Unevaluated(main, [], Some(promoted[0]))
// mir::Constant
// + span: $DIR/retag.rs:47:21: 47:23
// + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
- Retag(_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
- _23 = &(*_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
+ Retag(_28); // scope 7 at $DIR/retag.rs:47:21: 47:23
+ _23 = &(*_28); // scope 7 at $DIR/retag.rs:47:21: 47:23
Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23
_22 = &(*_23); // scope 7 at $DIR/retag.rs:47:21: 47:23
Retag(_22); // scope 7 at $DIR/retag.rs:47:21: 47:23
- _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb6]; // scope 7 at $DIR/retag.rs:47:5: 47:24
+ _19 = Test::foo_shr(move _20, move _22) -> [return: bb4, unwind: bb7]; // scope 7 at $DIR/retag.rs:47:5: 47:24
// mir::Constant
// + span: $DIR/retag.rs:47:13: 47:20
// + literal: Const { ty: for<'r, 'x> fn(&'r Test, &'x i32) -> &'x i32 {Test::foo_shr}, val: Value(Scalar(<ZST>)) }
StorageDead(_22); // scope 7 at $DIR/retag.rs:47:23: 47:24
StorageDead(_20); // scope 7 at $DIR/retag.rs:47:23: 47:24
StorageDead(_23); // scope 7 at $DIR/retag.rs:47:24: 47:25
- drop(_21) -> [return: bb5, unwind: bb8]; // scope 7 at $DIR/retag.rs:47:24: 47:25
+ drop(_21) -> [return: bb5, unwind: bb9]; // scope 7 at $DIR/retag.rs:47:24: 47:25
}
bb5: {
Retag([raw] _26); // scope 7 at $DIR/retag.rs:50:14: 50:16
_25 = _26; // scope 7 at $DIR/retag.rs:50:14: 50:28
StorageDead(_26); // scope 7 at $DIR/retag.rs:50:28: 50:29
- _0 = const (); // scope 0 at $DIR/retag.rs:29:11: 51:2
- StorageDead(_25); // scope 7 at $DIR/retag.rs:51:1: 51:2
- StorageDead(_15); // scope 6 at $DIR/retag.rs:51:1: 51:2
- StorageDead(_13); // scope 1 at $DIR/retag.rs:51:1: 51:2
- StorageDead(_1); // scope 0 at $DIR/retag.rs:51:1: 51:2
- return; // scope 0 at $DIR/retag.rs:51:2: 51:2
+ StorageLive(_27); // scope 8 at $DIR/retag.rs:52:5: 52:18
+ _27 = array_casts() -> bb6; // scope 8 at $DIR/retag.rs:52:5: 52:18
+ // mir::Constant
+ // + span: $DIR/retag.rs:52:5: 52:16
+ // + literal: Const { ty: fn() {array_casts}, val: Value(Scalar(<ZST>)) }
}
- bb6 (cleanup): {
- drop(_21) -> bb8; // scope 7 at $DIR/retag.rs:47:24: 47:25
+ bb6: {
+ StorageDead(_27); // scope 8 at $DIR/retag.rs:52:18: 52:19
+ _0 = const (); // scope 0 at $DIR/retag.rs:29:11: 53:2
+ StorageDead(_25); // scope 7 at $DIR/retag.rs:53:1: 53:2
+ StorageDead(_15); // scope 6 at $DIR/retag.rs:53:1: 53:2
+ StorageDead(_13); // scope 1 at $DIR/retag.rs:53:1: 53:2
+ StorageDead(_1); // scope 0 at $DIR/retag.rs:53:1: 53:2
+ return; // scope 0 at $DIR/retag.rs:53:2: 53:2
}
bb7 (cleanup): {
- drop(_5) -> bb8; // scope 1 at $DIR/retag.rs:32:36: 32:37
+ drop(_21) -> bb9; // scope 7 at $DIR/retag.rs:47:24: 47:25
}
bb8 (cleanup): {
- resume; // scope 0 at $DIR/retag.rs:29:1: 51:2
+ drop(_5) -> bb9; // scope 1 at $DIR/retag.rs:32:36: 32:37
+ }
+
+ bb9 (cleanup): {
+ resume; // scope 0 at $DIR/retag.rs:29:1: 53:2
}
}
// escape-to-raw (shr)
let _w = _w as *const _;
+
+ array_casts();
+}
+
+/// Casting directly to an array should also go through `&raw` and thus add appropriate retags.
+// EMIT_MIR retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
+fn array_casts() {
+ let mut x: [usize; 2] = [0, 0];
+ let p = &mut x as *mut usize;
+ unsafe { *p.add(1) = 1; }
+
+ let x: [usize; 2] = [0, 1];
+ let p = &x as *const usize;
+ assert_eq!(unsafe { *p.add(1) }, 1);
}
12| 1| if b {
13| 1| println!("non_async_func println in block");
14| 1| }
- ^0
15| 1|}
16| |
17| |
5| 1| if true {
6| 1| countdown = 10;
7| 1| }
- ^0
8| |
9| | const B: u32 = 100;
10| 1| let x = if countdown > 7 {
24| 1| if true {
25| 1| countdown = 10;
26| 1| }
- ^0
27| |
28| 1| if countdown > 7 {
29| 1| countdown -= 4;
41| 1| if true {
42| 1| countdown = 10;
43| 1| }
- ^0
44| |
45| 1| if countdown > 7 {
46| 1| countdown -= 4;
53| | } else {
54| 0| return;
55| | }
- 56| 0| }
- 57| |
+ 56| | } // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal
+ 57| | // `true` was const-evaluated. The compiler knows the `if` block will be executed.
58| |
59| 1| let mut countdown = 0;
60| 1| if true {
61| 1| countdown = 1;
62| 1| }
- ^0
63| |
64| 1| let z = if countdown > 7 {
^0
8| 1|//! assert_eq!(1, 1);
9| |//! } else {
10| |//! // this is not!
- 11| 0|//! assert_eq!(1, 2);
+ 11| |//! assert_eq!(1, 2);
12| |//! }
13| 1|//! ```
14| |//!
74| 1| if true {
75| 1| assert_eq!(1, 1);
76| | } else {
- 77| 0| assert_eq!(1, 2);
+ 77| | assert_eq!(1, 2);
78| | }
79| 1|}
80| |
19| 1| if true {
20| 1| println!("Exiting with error...");
21| 1| return Err(1);
- 22| 0| }
- 23| 0|
- 24| 0| let _ = Firework { strength: 1000 };
- 25| 0|
- 26| 0| Ok(())
+ 22| | }
+ 23| |
+ 24| | let _ = Firework { strength: 1000 };
+ 25| |
+ 26| | Ok(())
27| 1|}
28| |
29| |// Expected program output:
30| 1| if true {
31| 1| println!("Exiting with error...");
32| 1| return Err(1);
- 33| 0| }
- 34| 0|
- 35| 0|
- 36| 0|
- 37| 0|
- 38| 0|
- 39| 0| let _ = Firework { strength: 1000 };
- 40| 0|
- 41| 0| Ok(())
+ 33| | } // The remaining lines below have no coverage because `if true` (with the constant literal
+ 34| | // `true`) is guaranteed to execute the `then` block, which is also guaranteed to `return`.
+ 35| | // Thankfully, in the normal case, conditions are not guaranteed ahead of time, and as shown
+ 36| | // in other tests, the lines below would have coverage (which would show they had `0`
+ 37| | // executions, assuming the condition still evaluated to `true`).
+ 38| |
+ 39| | let _ = Firework { strength: 1000 };
+ 40| |
+ 41| | Ok(())
42| 1|}
43| |
44| |// Expected program output:
9| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
10| 1| if true {
11| 1| if false {
- 12| 0| while true {
- 13| 0| }
+ 12| | while true {
+ 13| | }
14| 1| }
- 15| 1| write!(f, "cool")?;
- ^0
- 16| 0| } else {
- 17| 0| }
+ 15| 1| write!(f, "error")?;
+ ^0
+ 16| | } else {
+ 17| | }
18| |
19| 10| for i in 0..10 {
20| 10| if true {
21| 10| if false {
- 22| 0| while true {}
+ 22| | while true {}
23| 10| }
- 24| 10| write!(f, "cool")?;
- ^0
- 25| 0| } else {
- 26| 0| }
+ 24| 10| write!(f, "error")?;
+ ^0
+ 25| | } else {
+ 26| | }
27| | }
28| 1| Ok(())
29| 1| }
34| |impl std::fmt::Display for DisplayTest {
35| 1| fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
36| 1| if false {
- 37| 0| } else {
+ 37| | } else {
38| 1| if false {
- 39| 0| while true {}
+ 39| | while true {}
40| 1| }
- 41| 1| write!(f, "cool")?;
- ^0
+ 41| 1| write!(f, "error")?;
+ ^0
42| | }
43| 10| for i in 0..10 {
44| 10| if false {
- 45| 0| } else {
+ 45| | } else {
46| 10| if false {
- 47| 0| while true {}
+ 47| | while true {}
48| 10| }
- 49| 10| write!(f, "cool")?;
- ^0
+ 49| 10| write!(f, "error")?;
+ ^0
50| | }
51| | }
52| 1| Ok(())
1| 1|fn main() {
2| 1| if false {
- 3| 0| loop {}
+ 3| | loop {}
4| 1| }
5| 1|}
} else {
return;
}
- }
-
+ } // Note: closing brace shows uncovered (vs. `0` for implicit else) because condition literal
+ // `true` was const-evaluated. The compiler knows the `if` block will be executed.
let mut countdown = 0;
if true {
if true {
println!("Exiting with error...");
return Err(1);
- }
-
-
-
-
+ } // The remaining lines below have no coverage because `if true` (with the constant literal
+ // `true`) is guaranteed to execute the `then` block, which is also guaranteed to `return`.
+ // Thankfully, in the normal case, conditions are not guaranteed ahead of time, and as shown
+ // in other tests, the lines below would have coverage (which would show they had `0`
+ // executions, assuming the condition still evaluated to `true`).
let _ = Firework { strength: 1000 };
while true {
}
}
- write!(f, "cool")?;
+ write!(f, "error")?;
} else {
}
if false {
while true {}
}
- write!(f, "cool")?;
+ write!(f, "error")?;
} else {
}
}
if false {
while true {}
}
- write!(f, "cool")?;
+ write!(f, "error")?;
}
for i in 0..10 {
if false {
if false {
while true {}
}
- write!(f, "cool")?;
+ write!(f, "error")?;
}
}
Ok(())
metadata_module: None,
metadata,
windows_subsystem: None,
- linker_info: LinkerInfo::new(tcx),
+ linker_info: LinkerInfo::new(tcx, "fake_target_cpu".to_string()),
crate_info: CrateInfo::new(tcx),
})
}
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
click: ".srclink"
assert: (".line-numbers", 1)
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
assert: ("#functions")
goto: ./struct.Foo.html
assert: ("div.type-decl")
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
goto: ./fn.check_list_code_block.html
// If the codeblock is the first element of the docblock, the information tooltip must have
// have some top margin to avoid going over the toggle (the "[+]").
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
click: ".srclink"
click: "#sidebar-toggle"
wait-for: 500
// This test ensures that the element corresponding to the hash is displayed.
-goto: file://|DOC_PATH|/struct.Foo.html#method.borrow
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.borrow
// In the blanket implementations list, "Borrow" is the second one, hence the ":nth(2)".
assert: ("#blanket-implementations-list > details:nth-child(2)", "open", "")
// Please note the "\" below is needed because otherwise ".borrow" would be interpreted as
// This test ensures that the impl blocks are open by default.
-goto: file://|DOC_PATH|/struct.Foo.html
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
assert: ("#main > details.implementors-toggle", "open", "")
+++ /dev/null
-//! The point of this crate is to be able to have enough different "kinds" of
-//! documentation generated so we can test each different features.
-
-#![crate_name = "test_docs"]
-
-use std::fmt;
-
-/// Basic function with some code examples:
-///
-/// ```
-/// println!("nothing fancy");
-/// ```
-///
-/// A failing to compile one:
-///
-/// ```compile_fail
-/// println!("where did my argument {} go? :'(");
-/// ```
-///
-/// An ignored one:
-///
-/// ```ignore (it's a test)
-/// Let's say I'm just some text will ya?
-/// ```
-pub fn foo() {}
-
-/// Just a normal struct.
-pub struct Foo;
-
-impl Foo {
- #[must_use]
- pub fn must_use(&self) -> bool {
- true
- }
-}
-
-/// Just a normal enum.
-pub enum WhoLetTheDogOut {
- /// Woof!
- Woof,
- /// Meoooooooow...
- Meow,
-}
-
-/// Who doesn't love to wrap a `format!` call?
-pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
- format!("{:?}", t)
-}
-
-/// Woohoo! A trait!
-pub trait AnotherOne {
- /// Some func 3.
- fn func3();
-
- /// Some func 1.
- fn func1();
-
- fn another();
- fn why_not();
-
- /// Some func 2.
- fn func2();
-
- fn hello();
-}
-
-/// ```compile_fail
-/// whatever
-/// ```
-///
-/// Check for "i" signs in lists!
-///
-/// 1. elem 1
-/// 2. test 1
-/// ```compile_fail
-/// fn foo() {}
-/// ```
-/// 3. elem 3
-/// 4. ```ignore (it's a test)
-/// fn foo() {}
-/// ```
-/// 5. elem 5
-///
-/// Final one:
-///
-/// ```ignore (still a test)
-/// let x = 12;
-/// ```
-pub fn check_list_code_block() {}
-
-pub enum AnEnum {
- WithVariants { and: usize, sub: usize, variants: usize },
-}
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
goto: ./fn.check_list_code_block.html
assert: ("pre.rust.fn")
// Test to ensure that you can click on the search input, whatever the width.
// The PR which fixed it is: https://github.com/rust-lang/rust/pull/81592
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
size: (463, 700)
// We first check that the search input isn't already focused.
assert-false: ("input.search-input:focus")
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
write: (".search-input", "Foo")
// Waiting for the search results to appear...
wait-for: "#titles"
assert: ("#titles > button:nth-of-type(1)", "class", "selected")
// To go back to the original "state"
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
write: (".search-input", "-> String")
// Waiting for the search results to appear...
wait-for: "#titles"
assert: ("#titles > button:nth-of-type(3)", "class", "selected")
// To go back to the original "state"
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
write: (".search-input", "-> Something")
// Waiting for the search results to appear...
wait-for: "#titles"
// Check that the various shortcuts are working.
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
// We first check that the search input isn't already focused.
assert-false: "input.search-input:focus"
press-key: "s"
-goto: file://|DOC_PATH|/../src/test_docs/lib.rs.html
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
// Check that we can click on the line number.
click: (40, 224) // This is the position of the span for line 4.
// Unfortunately, "#4" isn't a valid query selector, so we have to go around that limitation
// by instead getting the nth span.
assert: (".line-numbers > span:nth-child(4)", "class", "line-highlighted")
// We now check that the good spans are highlighted
-goto: file://|DOC_PATH|/../src/test_docs/lib.rs.html#4-6
+goto: file://|DOC_PATH|/src/test_docs/lib.rs.html#4-6
assert-false: (".line-numbers > span:nth-child(3)", "class", "line-highlighted")
assert: (".line-numbers > span:nth-child(4)", "class", "line-highlighted")
assert: (".line-numbers > span:nth-child(5)", "class", "line-highlighted")
--- /dev/null
+//! The point of this crate is to be able to have enough different "kinds" of
+//! documentation generated so we can test each different features.
+
+#![crate_name = "test_docs"]
+
+use std::fmt;
+
+/// Basic function with some code examples:
+///
+/// ```
+/// println!("nothing fancy");
+/// ```
+///
+/// A failing to compile one:
+///
+/// ```compile_fail
+/// println!("where did my argument {} go? :'(");
+/// ```
+///
+/// An ignored one:
+///
+/// ```ignore (it's a test)
+/// Let's say I'm just some text will ya?
+/// ```
+pub fn foo() {}
+
+/// Just a normal struct.
+pub struct Foo;
+
+impl Foo {
+ #[must_use]
+ pub fn must_use(&self) -> bool {
+ true
+ }
+}
+
+/// Just a normal enum.
+pub enum WhoLetTheDogOut {
+ /// Woof!
+ Woof,
+ /// Meoooooooow...
+ Meow,
+}
+
+/// Who doesn't love to wrap a `format!` call?
+pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
+ format!("{:?}", t)
+}
+
+/// Woohoo! A trait!
+pub trait AnotherOne {
+ /// Some func 3.
+ fn func3();
+
+ /// Some func 1.
+ fn func1();
+
+ fn another();
+ fn why_not();
+
+ /// Some func 2.
+ fn func2();
+
+ fn hello();
+}
+
+/// ```compile_fail
+/// whatever
+/// ```
+///
+/// Check for "i" signs in lists!
+///
+/// 1. elem 1
+/// 2. test 1
+/// ```compile_fail
+/// fn foo() {}
+/// ```
+/// 3. elem 3
+/// 4. ```ignore (it's a test)
+/// fn foo() {}
+/// ```
+/// 5. elem 5
+///
+/// Final one:
+///
+/// ```ignore (still a test)
+/// let x = 12;
+/// ```
+pub fn check_list_code_block() {}
+
+pub enum AnEnum {
+ WithVariants { and: usize, sub: usize, variants: usize },
+}
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
click: "#theme-picker"
click: "#theme-choices > button:first-child"
wait-for: 500
-goto: file://|DOC_PATH|/index.html
+goto: file://|DOC_PATH|/test_docs/index.html
+assert: ("#main > details.top-doc", "open", "")
click: "#toggle-all-docs"
-wait-for: 5000
-assert: ("#main > div.docblock.hidden-by-usual-hider")
+wait-for: 1000
+// This is now collapsed so there shouldn't be the "open" attribute on details.
+assert-false: ("#main > details.top-doc", "open", "")
click: "#toggle-all-docs"
-wait-for: 5000
-assert: ("#main > div.docblock.hidden-by-usual-hider", 0)
+wait-for: 1000
+// Not collapsed anymore so the "open" attribute should be back.
+assert: ("#main > details.top-doc", "open", "")
-goto: file://|DOC_PATH|/trait.AnotherOne.html
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
assert: (".sidebar-links a:nth-of-type(1)", "another")
assert: (".sidebar-links a:nth-of-type(2)", "func1")
assert: (".sidebar-links a:nth-of-type(3)", "func2")
--- /dev/null
+// Tests that `--show-type-layout` is required in order to show layout info.
+
+// @!has type_layout_flag_required/struct.Foo.html 'Size: '
+pub struct Foo(usize);
--- /dev/null
+// compile-flags: --show-type-layout -Z unstable-options
+
+// @has type_layout/struct.Foo.html 'Size: '
+// @has - ' bytes'
+pub struct Foo {
+ pub a: usize,
+ b: Vec<String>,
+}
+
+// @has type_layout/enum.Bar.html 'Size: '
+// @has - ' bytes'
+pub enum Bar<'a> {
+ A(String),
+ B(&'a str, (std::collections::HashMap<String, usize>, Foo)),
+}
+
+// @has type_layout/union.Baz.html 'Size: '
+// @has - ' bytes'
+pub union Baz {
+ a: &'static str,
+ b: usize,
+ c: &'static [u8],
+}
+
+// @has type_layout/struct.X.html 'Size: '
+// @has - ' bytes'
+pub struct X(usize);
+
+// @has type_layout/struct.Y.html 'Size: '
+// @has - '1 byte'
+// @!has - ' bytes'
+pub struct Y(u8);
+
+// @has type_layout/struct.Z.html 'Size: '
+// @has - '0 bytes'
+pub struct Z;
+
+// We can't compute layout for generic types.
+// @has type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
+// @!has - 'Size: '
+pub struct Generic<T>(T);
+
+// We *can*, however, compute layout for types that are only generic over lifetimes,
+// because lifetimes are a type-system construct.
+// @has type_layout/struct.GenericLifetimes.html 'Size: '
+// @has - ' bytes'
+pub struct GenericLifetimes<'a>(&'a str);
+
+// @has type_layout/struct.Unsized.html 'Size: '
+// @has - '(unsized)'
+pub struct Unsized([u8]);
+
+// @!has type_layout/trait.MyTrait.html 'Size: '
+pub trait MyTrait {}
// edition:2018
async fn copy() -> Result<()>
-//~^ ERROR this enum takes 2 type arguments but only 1 type argument was supplied
+//~^ ERROR this enum takes 2 generic arguments
{
Ok(())
//~^ ERROR type annotations needed
-error[E0107]: this enum takes 2 type arguments but only 1 type argument was supplied
+error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/issue-65159.rs:5:20
|
LL | async fn copy() -> Result<()>
- | ^^^^^^ -- supplied 1 type argument
+ | ^^^^^^ -- supplied 1 generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | async fn copy() -> Result<(), E>
| ^^^
async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
//~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
- //~^^ ERROR this struct takes 1 type argument but 0 type arguments were supplied
+ //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
LockedMarket(generator.lock().unwrap().buy())
//~^ ERROR cannot return value referencing temporary value
}
LL | struct LockedMarket<T>(T);
| ^^^^^^^^^^^^
-error[E0107]: this struct takes 1 type argument but 0 type arguments were supplied
+error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59
|
LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> {
- | ^^^^^^^^^^^^ expected 1 type argument
+ | ^^^^^^^^^^^^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8
|
LL | struct LockedMarket<T>(T);
| ^^^^^^^^^^^^ -
-help: add missing type argument
+help: add missing generic argument
|
LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_, T> {
| ^^^
-error[E0107]: this function takes 2 const arguments but only 1 const argument was supplied
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/incorrect-number-of-const-args.rs:11:5
|
LL | foo::<0>();
- | ^^^ - supplied 1 const argument
+ | ^^^ - supplied 1 generic argument
| |
- | expected 2 const arguments
+ | expected 2 generic arguments
|
-note: function defined here, with 2 const parameters: `X`, `Y`
+note: function defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/incorrect-number-of-const-args.rs:6:4
|
LL | fn foo<const X: usize, const Y: usize>() -> usize {
| ^^^ - -
-help: add missing const argument
+help: add missing generic argument
|
LL | foo::<0, Y>();
| ^^^
-error[E0107]: this function takes 2 const arguments but 3 const arguments were supplied
+error[E0107]: this function takes 2 generic arguments but 3 generic arguments were supplied
--> $DIR/incorrect-number-of-const-args.rs:14:5
|
LL | foo::<0, 0, 0>();
- | ^^^ --- help: remove this const argument
+ | ^^^ - help: remove this generic argument
| |
- | expected 2 const arguments
+ | expected 2 generic arguments
|
-note: function defined here, with 2 const parameters: `X`, `Y`
+note: function defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/incorrect-number-of-const-args.rs:6:4
|
LL | fn foo<const X: usize, const Y: usize>() -> usize {
-error[E0107]: this function takes 2 const arguments but only 1 const argument was supplied
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/incorrect-number-of-const-args.rs:11:5
|
LL | foo::<0>();
- | ^^^ - supplied 1 const argument
+ | ^^^ - supplied 1 generic argument
| |
- | expected 2 const arguments
+ | expected 2 generic arguments
|
-note: function defined here, with 2 const parameters: `X`, `Y`
+note: function defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/incorrect-number-of-const-args.rs:6:4
|
LL | fn foo<const X: usize, const Y: usize>() -> usize {
| ^^^ - -
-help: add missing const argument
+help: add missing generic argument
|
LL | foo::<0, Y>();
| ^^^
-error[E0107]: this function takes 2 const arguments but 3 const arguments were supplied
+error[E0107]: this function takes 2 generic arguments but 3 generic arguments were supplied
--> $DIR/incorrect-number-of-const-args.rs:14:5
|
LL | foo::<0, 0, 0>();
- | ^^^ --- help: remove this const argument
+ | ^^^ - help: remove this generic argument
| |
- | expected 2 const arguments
+ | expected 2 generic arguments
|
-note: function defined here, with 2 const parameters: `X`, `Y`
+note: function defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/incorrect-number-of-const-args.rs:6:4
|
LL | fn foo<const X: usize, const Y: usize>() -> usize {
fn main() {
foo::<0>();
- //~^ ERROR this function takes 2 const arguments but only 1 const argument was supplied
+ //~^ ERROR this function takes 2
foo::<0, 0, 0>();
- //~^ ERROR this function takes 2 const arguments but 3 const arguments were supplied
+ //~^ ERROR this function takes 2
}
fn main() {
let _: u32 = 5i32.try_into::<32>().unwrap();
- //~^ ERROR this associated function takes 0 const arguments but 1 const argument was supplied
+ //~^ ERROR this associated function takes
S.f::<0>();
//~^ ERROR no method named `f`
S::<0>;
- //~^ ERROR this struct takes 0 const arguments but 1 const argument was supplied
+ //~^ ERROR this struct takes 0
}
-error[E0107]: this associated function takes 0 const arguments but 1 const argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/invalid-const-arg-for-type-param.rs:6:23
|
LL | let _: u32 = 5i32.try_into::<32>().unwrap();
| ^^^^^^^^------ help: remove these generics
| |
- | expected 0 const arguments
+ | expected 0 generic arguments
|
-note: associated function defined here, with 0 const parameters
+note: associated function defined here, with 0 generic parameters
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
LL | fn try_into(self) -> Result<T, Self::Error>;
LL | S.f::<0>();
| ^ method not found in `S`
-error[E0107]: this struct takes 0 const arguments but 1 const argument was supplied
+error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/invalid-const-arg-for-type-param.rs:12:5
|
LL | S::<0>;
| ^----- help: remove these generics
| |
- | expected 0 const arguments
+ | expected 0 generic arguments
|
-note: struct defined here, with 0 const parameters
+note: struct defined here, with 0 generic parameters
--> $DIR/invalid-const-arg-for-type-param.rs:3:8
|
LL | struct S;
--> $DIR/invalid-constant-in-args.rs:4:12
|
LL | let _: Cell<&str, "a"> = Cell::new("");
- | ^^^^ ----- help: remove this generic argument
+ | ^^^^ --- help: remove this generic argument
| |
| expected 1 generic argument
|
fn main() {
test::<2>();
- //~^ ERROR this function takes 2 generic arguments but only 1 generic argument was supplied
+ //~^ ERROR this function takes 2 generic arguments
}
-error[E0107]: this function takes 2 generic arguments but only 1 generic argument was supplied
+error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/issue-76595.rs:15:5
|
LL | test::<2>();
fn main() {
S(&0, &0); // OK
S::<'static>(&0, &0);
- //~^ ERROR this struct takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this struct takes 2 lifetime arguments
S::<'static, 'static, 'static>(&0, &0);
- //~^ ERROR this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
+ //~^ ERROR this struct takes 2 lifetime arguments
E::V(&0); // OK
E::V::<'static>(&0);
- //~^ ERROR this enum takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this enum takes 2 lifetime arguments
E::V::<'static, 'static, 'static>(&0);
- //~^ ERROR this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
+ //~^ ERROR this enum takes 2 lifetime arguments
}
-error[E0107]: this struct takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/constructor-lifetime-args.rs:17:5
|
LL | S::<'static>(&0, &0);
--> $DIR/constructor-lifetime-args.rs:19:5
|
LL | S::<'static, 'static, 'static>(&0, &0);
- | ^ --------- help: remove this lifetime argument
+ | ^ ------- help: remove this lifetime argument
| |
| expected 2 lifetime arguments
|
LL | struct S<'a, 'b>(&'a u8, &'b u8);
| ^ -- --
-error[E0107]: this enum takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this enum takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/constructor-lifetime-args.rs:22:8
|
LL | E::V::<'static>(&0);
--> $DIR/constructor-lifetime-args.rs:24:8
|
LL | E::V::<'static, 'static, 'static>(&0);
- | ^ --------- help: remove this lifetime argument
+ | ^ ------- help: remove this lifetime argument
| |
| expected 2 lifetime arguments
|
| ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
- --> $DIR/deprecation-lint.rs:18:9
+ --> $DIR/deprecation-lint.rs:18:14
|
LL | Foo::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text
- --> $DIR/deprecation-lint.rs:19:9
+ --> $DIR/deprecation-lint.rs:19:16
|
LL | <Foo>::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
--> $DIR/deprecation-lint.rs:20:13
| ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:22:9
+ --> $DIR/deprecation-lint.rs:22:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
--> $DIR/deprecation-lint.rs:26:13
| ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:27:9
+ --> $DIR/deprecation-lint.rs:27:14
|
LL | ... Foo::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:28:9
+ --> $DIR/deprecation-lint.rs:28:16
|
LL | ... <Foo>::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
--> $DIR/deprecation-lint.rs:29:13
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:31:9
+ --> $DIR/deprecation-lint.rs:31:16
|
LL | ... <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text
--> $DIR/deprecation-lint.rs:35:13
| ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:66:9
+ --> $DIR/deprecation-lint.rs:66:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
--> $DIR/deprecation-lint.rs:68:13
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:70:9
+ --> $DIR/deprecation-lint.rs:70:16
|
LL | ... <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
--> $DIR/deprecation-lint.rs:75:13
| ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
- --> $DIR/deprecation-lint.rs:247:9
+ --> $DIR/deprecation-lint.rs:247:14
|
LL | Foo::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
- --> $DIR/deprecation-lint.rs:248:9
+ --> $DIR/deprecation-lint.rs:248:16
|
LL | <Foo>::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
--> $DIR/deprecation-lint.rs:249:13
| ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:251:9
+ --> $DIR/deprecation-lint.rs:251:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
--> $DIR/deprecation-lint.rs:255:13
| ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:256:9
+ --> $DIR/deprecation-lint.rs:256:14
|
LL | ... Foo::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:257:9
+ --> $DIR/deprecation-lint.rs:257:16
|
LL | ... <Foo>::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
--> $DIR/deprecation-lint.rs:258:13
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:260:9
+ --> $DIR/deprecation-lint.rs:260:16
|
LL | <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated field `this_crate::DeprecatedStruct::i`: text
--> $DIR/deprecation-lint.rs:269:13
| ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:293:9
+ --> $DIR/deprecation-lint.rs:293:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
--> $DIR/deprecation-lint.rs:295:13
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:297:9
+ --> $DIR/deprecation-lint.rs:297:16
|
LL | <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
--> $DIR/deprecation-lint.rs:302:13
--- /dev/null
+// run-rustfix
+
+#![deny(deprecated)]
+
+fn main() {
+ let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+
+ let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+}
--- /dev/null
+// run-rustfix
+
+#![deny(deprecated)]
+
+fn main() {
+ let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+
+ let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated]
+}
--- /dev/null
+error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start`
+ --> $DIR/issue-84637-deprecated-associated-function.rs:6:21
+ |
+LL | let _foo = str::trim_left(" aoeu");
+ | ^^^^^^^^^ help: replace the use of the deprecated associated function: `trim_start`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-84637-deprecated-associated-function.rs:3:9
+ |
+LL | #![deny(deprecated)]
+ | ^^^^^^^^^^
+
+error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start`
+ --> $DIR/issue-84637-deprecated-associated-function.rs:8:26
+ |
+LL | let _bar = " aoeu".trim_left();
+ | ^^^^^^^^^ help: replace the use of the deprecated associated function: `trim_start`
+
+error: aborting due to 2 previous errors
+
struct Baz<'a, 'b, 'c> {
buzz: Buzz<'a>,
- //~^ ERROR this struct takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this struct takes 2 lifetime arguments
//~| HELP add missing lifetime argument
bar: Bar<'a>,
- //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+ //~^ ERROR this enum takes 0 lifetime arguments
//~| HELP remove these generics
foo2: Foo<'a, 'b, 'c>,
- //~^ ERROR this struct takes 1 lifetime argument but 3 lifetime arguments were supplied
+ //~^ ERROR this struct takes 1 lifetime argument
//~| HELP remove these lifetime arguments
}
-error[E0107]: this struct takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/E0107.rs:11:11
|
LL | buzz: Buzz<'a>,
| ^^^^ -- --
help: add missing lifetime argument
|
-LL | buzz: Buzz<'a, 'b>,
+LL | buzz: Buzz<'a, 'a>,
| ^^^^
error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/E0107.rs:19:11
|
LL | foo2: Foo<'a, 'b, 'c>,
- | ^^^ -------- help: remove these lifetime arguments
+ | ^^^ ------ help: remove these lifetime arguments
| |
| expected 1 lifetime argument
|
+++ /dev/null
-// Test use of advanced const fn without the `const_fn` feature gate.
-
-const fn foo() -> usize { 0 } // ok
-
-trait Foo {
- const fn foo() -> u32; //~ ERROR functions in traits cannot be declared const
- const fn bar() -> u32 { 0 } //~ ERROR functions in traits cannot be declared const
-}
-
-impl Foo for u32 {
- const fn foo() -> u32 { 0 } //~ ERROR functions in traits cannot be declared const
-}
-
-trait Bar {}
-
-impl dyn Bar {
- const fn baz() -> u32 { 0 } // ok
-}
-
-static FOO: usize = foo();
-const BAR: usize = foo();
-
-macro_rules! constant {
- ($n:ident: $t:ty = $v:expr) => {
- const $n: $t = $v;
- }
-}
-
-constant! {
- BAZ: usize = foo()
-}
-
-fn main() {
- let x: [usize; foo()] = [];
-}
+++ /dev/null
-error[E0379]: functions in traits cannot be declared const
- --> $DIR/feature-gate-const_fn.rs:6:5
- |
-LL | const fn foo() -> u32;
- | ^^^^^ functions in traits cannot be const
-
-error[E0379]: functions in traits cannot be declared const
- --> $DIR/feature-gate-const_fn.rs:7:5
- |
-LL | const fn bar() -> u32 { 0 }
- | ^^^^^ functions in traits cannot be const
-
-error[E0379]: functions in traits cannot be declared const
- --> $DIR/feature-gate-const_fn.rs:11:5
- |
-LL | const fn foo() -> u32 { 0 }
- | ^^^^^ functions in traits cannot be const
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0379`.
// Test internal const fn feature gate.
-#![feature(const_fn)]
-
#[rustc_const_unstable(feature="fzzzzzt")] //~ stability attributes may not be used outside
pub const fn bazinga() {}
error[E0734]: stability attributes may not be used outside of the standard library
- --> $DIR/feature-gate-rustc_const_unstable.rs:5:1
+ --> $DIR/feature-gate-rustc_const_unstable.rs:3:1
|
LL | #[rustc_const_unstable(feature="fzzzzzt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
trait X {
type Y<'a>;
- //~^ ERROR missing generics for
- //~| ERROR missing generics for
fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
}
impl<T> X for T {
fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ //~^ ERROR missing generics for associated type
+ //~^^ ERROR missing generics for associated type
t
}
}
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0107]: missing generics for associated type `X::Y`
- --> $DIR/gat-trait-path-missing-lifetime.rs:5:8
+ --> $DIR/gat-trait-path-missing-lifetime.rs:11:20
|
-LL | type Y<'a>;
- | ^ expected 1 lifetime argument
+LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ | ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
LL | type Y<'a>;
| ^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type Y<'a><'a>;
- | ^^^^
+LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
+ | ^^^^^
error[E0107]: missing generics for associated type `X::Y`
- --> $DIR/gat-trait-path-missing-lifetime.rs:5:8
+ --> $DIR/gat-trait-path-missing-lifetime.rs:11:20
|
-LL | type Y<'a>;
- | ^ expected 1 lifetime argument
+LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ | ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/gat-trait-path-missing-lifetime.rs:5:8
|
LL | type Y<'a>;
| ^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type Y<'a><'a>;
- | ^^^^
+LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
+ | ^^^^^
error: aborting due to 2 previous errors; 1 warning emitted
trait X {
type Y<'a>;
- //~^ ERROR this associated type
- //~| ERROR this associated type
}
fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
//~^ ERROR: lifetime in trait object type must be followed by `+`
//~| ERROR: parenthesized generic arguments cannot be used
+ //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+ //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
//~| WARNING: trait objects without an explicit `dyn` are deprecated
//~| WARNING: this was previously accepted by the compiler
error: lifetime in trait object type must be followed by `+`
- --> $DIR/gat-trait-path-parenthesised-args.rs:10:29
+ --> $DIR/gat-trait-path-parenthesised-args.rs:8:29
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^^
error: parenthesized generic arguments cannot be used in associated type constraints
- --> $DIR/gat-trait-path-parenthesised-args.rs:10:27
+ --> $DIR/gat-trait-path-parenthesised-args.rs:8:27
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^^^^^
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/gat-trait-path-parenthesised-args.rs:10:29
+ --> $DIR/gat-trait-path-parenthesised-args.rs:8:29
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
| ^^ help: use `dyn`: `dyn 'a`
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/gat-trait-path-parenthesised-args.rs:5:8
+ --> $DIR/gat-trait-path-parenthesised-args.rs:8:27
|
-LL | type Y<'a>;
- | ^ expected 1 lifetime argument
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
| ^ --
help: add missing lifetime argument
|
-LL | fn foo<'a>(arg: Box<dyn X<Y('a'a) = &'a ()>>) {}
- | ^^
+LL | fn foo<'a>(arg: Box<dyn X<Y('a, 'a) = &'a ()>>) {}
+ | ^^^
-error[E0107]: this associated type takes 0 type arguments but 1 type argument was supplied
- --> $DIR/gat-trait-path-parenthesised-args.rs:5:8
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/gat-trait-path-parenthesised-args.rs:8:27
|
-LL | type Y<'a>;
- | ________^-
- | | |
- | | expected 0 type arguments
-LL | |
-LL | |
-LL | | }
-LL | |
-LL | | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
- | |_________________________________________- help: remove these generics
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^-------------- help: remove these generics
+ | |
+ | expected 0 generic arguments
|
-note: associated type defined here, with 0 type parameters
+note: associated type defined here, with 0 generic parameters
--> $DIR/gat-trait-path-parenthesised-args.rs:5:8
|
LL | type Y<'a>;
trait Provider {
type A<'a>;
- //~^ ERROR: missing generics for associated type
}
impl Provider for () {
struct Holder<B> {
inner: Box<dyn Provider<A = B>>,
+ //~^ ERROR: missing generics for associated type
}
fn main() {
error[E0107]: missing generics for associated type `Provider::A`
- --> $DIR/issue-71176.rs:5:10
+ --> $DIR/issue-71176.rs:13:27
|
-LL | type A<'a>;
- | ^ expected 1 lifetime argument
+LL | inner: Box<dyn Provider<A = B>>,
+ | ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-71176.rs:5:10
|
LL | type A<'a>;
| ^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type A<'a><'a>;
- | ^^^^
+LL | inner: Box<dyn Provider<A<'a> = B>>,
+ | ^^^^^
error: aborting due to previous error
pub trait SuperTrait {
type SubType<'a>: SubTrait;
- //~^ ERROR missing generics for associated
fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
}
fn main() {
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
- //~^ ERROR the trait `SuperTrait` cannot be made into an object
- //~^^ ERROR the trait `SuperTrait` cannot be made into an object
+ //~^ ERROR missing generics for associated type
+ //~^^ ERROR the trait
+ //~| ERROR the trait
}
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0107]: missing generics for associated type `SuperTrait::SubType`
- --> $DIR/issue-76535.rs:7:10
+ --> $DIR/issue-76535.rs:37:33
|
-LL | type SubType<'a>: SubTrait;
- | ^^^^^^^ expected 1 lifetime argument
+LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-76535.rs:7:10
|
LL | type SubType<'a>: SubTrait;
| ^^^^^^^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type SubType<'a><'a>: SubTrait;
- | ^^^^
+LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^^^^^
error[E0038]: the trait `SuperTrait` cannot be made into an object
- --> $DIR/issue-76535.rs:38:14
+ --> $DIR/issue-76535.rs:37:14
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
| ^^^^^^^ ...because it contains the generic associated type `SubType`
error[E0038]: the trait `SuperTrait` cannot be made into an object
- --> $DIR/issue-76535.rs:38:57
+ --> $DIR/issue-76535.rs:37:57
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
trait CollectionFamily {
type Member<T>;
- //~^ ERROR: missing generics for associated type
}
fn floatify() {
Box::new(Family) as &dyn CollectionFamily<Member=usize>
- //~^ the trait `CollectionFamily` cannot be made into an object
+ //~^ ERROR: missing generics for associated type
+ //~| ERROR: the trait `CollectionFamily` cannot be made into an object
}
struct Family;
error[E0107]: missing generics for associated type `CollectionFamily::Member`
- --> $DIR/issue-78671.rs:5:10
+ --> $DIR/issue-78671.rs:8:47
|
-LL | type Member<T>;
- | ^^^^^^ expected 1 type argument
+LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
+ | ^^^^^^ expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `T`
+note: associated type defined here, with 1 generic parameter: `T`
--> $DIR/issue-78671.rs:5:10
|
LL | type Member<T>;
| ^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
-LL | type Member<T><T>;
- | ^^^
+LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
+ | ^^^^^^^^^
error[E0038]: the trait `CollectionFamily` cannot be made into an object
- --> $DIR/issue-78671.rs:9:25
+ --> $DIR/issue-78671.rs:8:25
|
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
trait MapLike<K, V> {
type VRefCont<'a>: RefCont<'a, V>;
- //~^ ERROR missing generics
fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
}
fn main() {
let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
- //~^^ the trait `MapLike` cannot be made into an object
- //~^^ the trait `MapLike` cannot be made into an object
+ //~^ ERROR missing generics for associated type
+ //~^^ ERROR the trait
+ //~^^^^ ERROR the trait
}
error[E0107]: missing generics for associated type `MapLike::VRefCont`
- --> $DIR/issue-79422.rs:21:10
+ --> $DIR/issue-79422.rs:43:36
|
-LL | type VRefCont<'a>: RefCont<'a, V>;
- | ^^^^^^^^ expected 1 lifetime argument
+LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
+ | ^^^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-79422.rs:21:10
|
LL | type VRefCont<'a>: RefCont<'a, V>;
| ^^^^^^^^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type VRefCont<'a><'a>: RefCont<'a, V>;
- | ^^^^
+LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
+ | ^^^^^^^^^^^^
error[E0038]: the trait `MapLike` cannot be made into an object
- --> $DIR/issue-79422.rs:44:12
+ --> $DIR/issue-79422.rs:43:12
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
error[E0038]: the trait `MapLike` cannot be made into an object
- --> $DIR/issue-79422.rs:43:13
+ --> $DIR/issue-79422.rs:42:13
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
trait Monad {
type Unwrapped;
type Wrapped<B>;
- //~^ ERROR: missing generics for associated type `Monad::Wrapped`
fn bind<B, F>(self, f: F) -> Self::Wrapped<B> {
todo!()
where
MOuter: Monad<Unwrapped = MInner>,
MInner: Monad<Unwrapped = A, Wrapped = MOuter::Wrapped<A>>,
+ //~^ ERROR: missing generics for associated type `Monad::Wrapped`
{
outer.bind(|inner| inner)
}
error[E0107]: missing generics for associated type `Monad::Wrapped`
- --> $DIR/issue-79636-1.rs:6:10
+ --> $DIR/issue-79636-1.rs:16:34
|
-LL | type Wrapped<B>;
- | ^^^^^^^ expected 1 type argument
+LL | MInner: Monad<Unwrapped = A, Wrapped = MOuter::Wrapped<A>>,
+ | ^^^^^^^ expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `B`
+note: associated type defined here, with 1 generic parameter: `B`
--> $DIR/issue-79636-1.rs:6:10
|
LL | type Wrapped<B>;
| ^^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
-LL | type Wrapped<B><B>;
- | ^^^
+LL | MInner: Monad<Unwrapped = A, Wrapped<B> = MOuter::Wrapped<A>>,
+ | ^^^^^^^^^^
error: aborting due to previous error
trait SomeTrait {
type Wrapped<A>: SomeTrait;
- //~^ ERROR: missing generics for associated type `SomeTrait::Wrapped`
fn f() -> ();
}
fn program<W>() -> ()
where
W: SomeTrait<Wrapped = W>,
+ //~^ ERROR: missing generics for associated type `SomeTrait::Wrapped`
{
return W::f();
}
error[E0107]: missing generics for associated type `SomeTrait::Wrapped`
- --> $DIR/issue-79636-2.rs:5:10
+ --> $DIR/issue-79636-2.rs:12:18
|
-LL | type Wrapped<A>: SomeTrait;
- | ^^^^^^^ expected 1 type argument
+LL | W: SomeTrait<Wrapped = W>,
+ | ^^^^^^^ expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `A`
+note: associated type defined here, with 1 generic parameter: `A`
--> $DIR/issue-79636-2.rs:5:10
|
LL | type Wrapped<A>: SomeTrait;
| ^^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
-LL | type Wrapped<A><A>: SomeTrait;
- | ^^^
+LL | W: SomeTrait<Wrapped<A> = W>,
+ | ^^^^^^^^^^
error: aborting due to previous error
trait TestMut {
type Output<'a>;
- //~^ ERROR missing generics
fn test_mut<'a>(&'a mut self) -> Self::Output<'a>;
}
}
fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
+ //~^ ERROR missing generics for associated type
{
for n in 0i16..100 {
*dst.test_mut() = n.into();
error[E0107]: missing generics for associated type `TestMut::Output`
- --> $DIR/issue-80433.rs:10:10
+ --> $DIR/issue-80433.rs:24:47
|
-LL | type Output<'a>;
- | ^^^^^^ expected 1 lifetime argument
+LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
+ | ^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-80433.rs:10:10
|
LL | type Output<'a>;
| ^^^^^^ --
-help: use angle brackets to add missing lifetime argument
+help: add missing lifetime argument
|
-LL | type Output<'a><'a>;
- | ^^^^
+LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output<'a> = &'a mut f32>)
+ | ^^^^^^^^^^
error: aborting due to previous error
}
trait C {
type DType<T>: D<T, CType = Self>;
- //~^ ERROR: missing generics for associated type `C::DType` [E0107]
}
trait D<T> {
type CType: C<DType = Self>;
+ //~^ ERROR missing generics for associated type
}
fn main() {}
error[E0107]: missing generics for associated type `C::DType`
- --> $DIR/issue-81712-cyclic-traits.rs:14:10
+ --> $DIR/issue-81712-cyclic-traits.rs:17:19
|
-LL | type DType<T>: D<T, CType = Self>;
- | ^^^^^ expected 1 type argument
+LL | type CType: C<DType = Self>;
+ | ^^^^^ expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `T`
+note: associated type defined here, with 1 generic parameter: `T`
--> $DIR/issue-81712-cyclic-traits.rs:14:10
|
LL | type DType<T>: D<T, CType = Self>;
| ^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
-LL | type DType<T><T>: D<T, CType = Self>;
- | ^^^
+LL | type CType: C<DType<T> = Self>;
+ | ^^^^^^^^
error: aborting due to previous error
--- /dev/null
+#![allow(incomplete_features)]
+#![feature(generic_associated_types)]
+
+trait StreamingIterator {
+ type Item<'a>;
+ fn next(&mut self) -> Option<Self::Item>;
+ //~^ ERROR missing generics for associated type
+}
+
+fn main() {}
+
+// call stack from back to front:
+// create_substs_for_assoc_ty -> qpath_to_ty -> res_to_ty -> ast_ty_to_ty -> ty_of_fn
--- /dev/null
+error[E0107]: missing generics for associated type `StreamingIterator::Item`
+ --> $DIR/issue-81862.rs:6:40
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-81862.rs:5:10
+ |
+LL | type Item<'a>;
+ | ^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn next(&mut self) -> Option<Self::Item<'_>>;
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
--- /dev/null
+#![feature(generic_associated_types)]
+//~^ WARNING the feature `generic_associated_types`
+
+trait X {
+ type Y<'a, 'b>;
+}
+
+struct Foo<'a, 'b, 'c> {
+ a: &'a u32,
+ b: &'b str,
+ c: &'c str,
+}
+
+fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
+//~^ ERROR missing generics for associated type
+
+fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
+//~^ ERROR this struct takes 3 lifetime arguments but 2 lifetime
+
+fn f<'a>(_arg: Foo<'a>) {}
+//~^ ERROR this struct takes 3 lifetime arguments but 1 lifetime
+
+fn main() {}
--- /dev/null
+warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/missing_lifetime_args.rs:1:12
+ |
+LL | #![feature(generic_associated_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+
+error[E0107]: missing generics for associated type `X::Y`
+ --> $DIR/missing_lifetime_args.rs:14:32
+ |
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
+ | ^ expected 2 lifetime arguments
+ |
+note: associated type defined here, with 2 lifetime parameters: `'a`, `'b`
+ --> $DIR/missing_lifetime_args.rs:5:10
+ |
+LL | type Y<'a, 'b>;
+ | ^ -- --
+help: add missing lifetime arguments
+ |
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'c, 'd> = (&'c u32, &'d u32)>>) {}
+ | ^^^^^^^^^
+
+error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+ --> $DIR/missing_lifetime_args.rs:17:26
+ |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
+ | ^^^ -- -- supplied 2 lifetime arguments
+ | |
+ | expected 3 lifetime arguments
+ |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+ --> $DIR/missing_lifetime_args.rs:8:8
+ |
+LL | struct Foo<'a, 'b, 'c> {
+ | ^^^ -- -- --
+help: add missing lifetime argument
+ |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
+ | ^^^^
+
+error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied
+ --> $DIR/missing_lifetime_args.rs:20:16
+ |
+LL | fn f<'a>(_arg: Foo<'a>) {}
+ | ^^^ -- supplied 1 lifetime argument
+ | |
+ | expected 3 lifetime arguments
+ |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+ --> $DIR/missing_lifetime_args.rs:8:8
+ |
+LL | struct Foo<'a, 'b, 'c> {
+ | ^^^ -- -- --
+help: add missing lifetime arguments
+ |
+LL | fn f<'a>(_arg: Foo<'a, 'b, 'c>) {}
+ | ^^^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0107`.
--- /dev/null
+#![feature(generic_associated_types)]
+//~^ WARNING the feature
+
+trait Foo {
+ type Assoc<'a, const N: usize>;
+}
+
+fn foo<T: Foo>() {
+ let _: <T as Foo>::Assoc<3>;
+ //~^ ERROR this associated type
+}
+
+fn main() {}
--- /dev/null
+warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/missing_lifetime_const.rs:1:12
+ |
+LL | #![feature(generic_associated_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/missing_lifetime_const.rs:9:24
+ |
+LL | let _: <T as Foo>::Assoc<3>;
+ | ^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/missing_lifetime_const.rs:5:10
+ |
+LL | type Assoc<'a, const N: usize>;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | let _: <T as Foo>::Assoc<'a, 3>;
+ | ^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0107`.
type FOk<T> = Self::E<'static, T>;
type FErr1 = Self::E<'static, 'static>;
//~^ ERROR this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
- //~| ERROR this associated type takes 1 type argument but 0 type arguments were supplied
+ //~| ERROR this associated type takes 1
type FErr2<T> = Self::E<'static, T, u32>;
- //~^ ERROR this associated type takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this associated type takes 1
}
fn main() {}
--> $DIR/parameter_number_and_kind.rs:13:24
|
LL | type FErr1 = Self::E<'static, 'static>;
- | ^ --------- help: remove this lifetime argument
+ | ^ ------- help: remove this lifetime argument
| |
| expected 1 lifetime argument
|
LL | type E<'a, T>;
| ^ --
-error[E0107]: this associated type takes 1 type argument but 0 type arguments were supplied
+error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/parameter_number_and_kind.rs:13:24
|
LL | type FErr1 = Self::E<'static, 'static>;
- | ^ expected 1 type argument
+ | ^ expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `T`
+note: associated type defined here, with 1 generic parameter: `T`
--> $DIR/parameter_number_and_kind.rs:10:10
|
LL | type E<'a, T>;
| ^ -
-help: add missing type argument
+help: add missing generic argument
|
LL | type FErr1 = Self::E<'static, 'static, T>;
| ^^^
-error[E0107]: this associated type takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/parameter_number_and_kind.rs:16:27
|
LL | type FErr2<T> = Self::E<'static, T, u32>;
- | ^ ----- help: remove this type argument
+ | ^ --- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: associated type defined here, with 1 type parameter: `T`
+note: associated type defined here, with 1 generic parameter: `T`
--> $DIR/parameter_number_and_kind.rs:10:10
|
LL | type E<'a, T>;
trait X {
type Y<'a>;
- //~^ ERROR this associated type
- //~| ERROR this associated type
}
const _: () = {
fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+ //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
};
fn main() {}
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
- --> $DIR/trait-path-type-error-once-implemented.rs:5:10
+ --> $DIR/trait-path-type-error-once-implemented.rs:9:29
|
-LL | type Y<'a>;
- | ^ expected 1 lifetime argument
+LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
| ^ --
help: add missing lifetime argument
|
-LL | fn f2<'a>(arg : Box<dyn X<Y<'a1> = &'a ()>>) {}
- | ^^
+LL | fn f2<'a>(arg : Box<dyn X<Y<'a, 1> = &'a ()>>) {}
+ | ^^^
-error[E0107]: this associated type takes 0 const arguments but 1 const argument was supplied
- --> $DIR/trait-path-type-error-once-implemented.rs:5:10
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/trait-path-type-error-once-implemented.rs:9:29
+ |
+LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^--- help: remove these generics
+ | |
+ | expected 0 generic arguments
|
-LL | type Y<'a>;
- | __________^-
- | | |
- | | expected 0 const arguments
-LL | |
-LL | |
-LL | | }
-LL | |
-LL | | const _: () = {
-LL | | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
- | |________________________________- help: remove these generics
- |
-note: associated type defined here, with 0 const parameters
+note: associated type defined here, with 0 generic parameters
--> $DIR/trait-path-type-error-once-implemented.rs:5:10
|
LL | type Y<'a>;
fn foo<'a>() {
let _ = S::new::<isize,f64>(1, 1.0);
- //~^ ERROR this associated function takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this associated function takes 1
let _ = S::<'a,isize>::new::<f64>(1, 1.0);
//~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
let _: S2 = Trait::new::<isize,f64>(1, 1.0);
- //~^ ERROR this associated function takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this associated function takes 1
let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
- //~| ERROR this associated function takes 1 type argument but 2 type arguments were supplied
+ //~| ERROR this associated function takes 1
}
fn main() {}
-error[E0107]: this associated function takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/bad-mid-path-type-params.rs:30:16
|
LL | let _ = S::new::<isize,f64>(1, 1.0);
- | ^^^ ---- help: remove this type argument
+ | ^^^ --- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: associated function defined here, with 1 type parameter: `U`
+note: associated function defined here, with 1 generic parameter: `U`
--> $DIR/bad-mid-path-type-params.rs:6:8
|
LL | fn new<U>(x: T, _: U) -> S<T> {
--> $DIR/bad-mid-path-type-params.rs:33:13
|
LL | let _ = S::<'a,isize>::new::<f64>(1, 1.0);
- | ^ --- help: remove this lifetime argument
+ | ^ -- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
LL | struct S<T> {
| ^
-error[E0107]: this associated function takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/bad-mid-path-type-params.rs:36:24
|
LL | let _: S2 = Trait::new::<isize,f64>(1, 1.0);
- | ^^^ ---- help: remove this type argument
+ | ^^^ --- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: associated function defined here, with 1 type parameter: `U`
+note: associated function defined here, with 1 generic parameter: `U`
--> $DIR/bad-mid-path-type-params.rs:14:8
|
LL | fn new<U>(x: T, y: U) -> Self;
--> $DIR/bad-mid-path-type-params.rs:39:17
|
LL | let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
- | ^^^^^ --- help: remove this lifetime argument
+ | ^^^^^ -- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
LL | trait Trait<T> {
| ^^^^^
-error[E0107]: this associated function takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/bad-mid-path-type-params.rs:39:36
|
LL | let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0);
- | ^^^ ---- help: remove this type argument
+ | ^^^ --- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: associated function defined here, with 1 type parameter: `U`
+note: associated function defined here, with 1 generic parameter: `U`
--> $DIR/bad-mid-path-type-params.rs:14:8
|
LL | fn new<U>(x: T, y: U) -> Self;
Bar::<'static, 'static, ()>(&());
//~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
- //~| ERROR this struct takes 0 type arguments but 1 type argument was supplied
+ //~| ERROR this struct takes 0
}
--> $DIR/generic-arg-mismatch-recover.rs:6:5
|
LL | Foo::<'static, 'static, ()>(&0);
- | ^^^ --------- help: remove this lifetime argument
+ | ^^^ ------- help: remove this lifetime argument
| |
| expected 1 lifetime argument
|
--> $DIR/generic-arg-mismatch-recover.rs:9:5
|
LL | Bar::<'static, 'static, ()>(&());
- | ^^^ --------- help: remove this lifetime argument
+ | ^^^ ------- help: remove this lifetime argument
| |
| expected 1 lifetime argument
|
LL | struct Bar<'a>(&'a ());
| ^^^ --
-error[E0107]: this struct takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/generic-arg-mismatch-recover.rs:9:5
|
LL | Bar::<'static, 'static, ()>(&());
- | ^^^ ---- help: remove this type argument
+ | ^^^ -- help: remove this generic argument
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: struct defined here, with 0 type parameters
+note: struct defined here, with 0 generic parameters
--> $DIR/generic-arg-mismatch-recover.rs:3:8
|
LL | struct Bar<'a>(&'a ());
fn main() {
Foo::<isize>::new();
- //~^ ERROR this struct takes at least 2 type arguments but only 1 type argument was supplied
+ //~^ ERROR this struct takes at least 2 generic arguments but 1 generic argument
}
-error[E0107]: this struct takes at least 2 type arguments but only 1 type argument was supplied
+error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
--> $DIR/generic-impl-less-params-with-defaults.rs:11:5
|
LL | Foo::<isize>::new();
- | ^^^ ----- supplied 1 type argument
+ | ^^^ ----- supplied 1 generic argument
| |
- | expected at least 2 type arguments
+ | expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `A`, `B`
+note: struct defined here, with at least 2 generic parameters: `A`, `B`
--> $DIR/generic-impl-less-params-with-defaults.rs:3:8
|
LL | struct Foo<A, B, C = (A, B)>(
| ^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | Foo::<isize, B>::new();
| ^^^
fn main() {
Vec::<isize, Heap, bool>::new();
- //~^ ERROR this struct takes at most 2 type arguments but 3 type arguments were supplied
+ //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments were supplied
}
-error[E0107]: this struct takes at most 2 type arguments but 3 type arguments were supplied
+error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
--> $DIR/generic-impl-more-params-with-defaults.rs:13:5
|
LL | Vec::<isize, Heap, bool>::new();
- | ^^^ ------ help: remove this type argument
+ | ^^^ ---- help: remove this generic argument
| |
- | expected at most 2 type arguments
+ | expected at most 2 generic arguments
|
-note: struct defined here, with at most 2 type parameters: `T`, `A`
+note: struct defined here, with at most 2 generic parameters: `T`, `A`
--> $DIR/generic-impl-more-params-with-defaults.rs:5:8
|
LL | struct Vec<T, A = Heap>(
--> $DIR/generic-type-less-params-with-defaults.rs:9:12
|
LL | let _: Vec;
- | ^^^ expected at least 1 type argument
+ | ^^^ expected at least 1 generic argument
|
-note: struct defined here, with at least 1 type parameter: `T`
+note: struct defined here, with at least 1 generic parameter: `T`
--> $DIR/generic-type-less-params-with-defaults.rs:5:8
|
LL | struct Vec<T, A = Heap>(
| ^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | let _: Vec<T>;
- | ^^^
+ | ^^^^^^
error: aborting due to previous error
fn main() {
let _: Vec<isize, Heap, bool>;
- //~^ ERROR this struct takes at most 2 type arguments but 3 type arguments were supplied
+ //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments
}
-error[E0107]: this struct takes at most 2 type arguments but 3 type arguments were supplied
+error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied
--> $DIR/generic-type-more-params-with-defaults.rs:9:12
|
LL | let _: Vec<isize, Heap, bool>;
- | ^^^ ------ help: remove this type argument
+ | ^^^ ---- help: remove this generic argument
| |
- | expected at most 2 type arguments
+ | expected at most 2 generic arguments
|
-note: struct defined here, with at most 2 type parameters: `T`, `A`
+note: struct defined here, with at most 2 generic parameters: `T`, `A`
--> $DIR/generic-type-more-params-with-defaults.rs:5:8
|
LL | struct Vec<T, A = Heap>(
type A = Ty;
type B = Ty<'static>;
- //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+ //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
//~| HELP remove these generics
type C = Ty<'static, usize>;
- //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
- //~| ERROR this struct takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+ //~| ERROR this struct takes 0 generic arguments but 1 generic argument
//~| HELP remove this lifetime argument
- //~| HELP remove this type argument
+ //~| HELP remove this generic argument
type D = Ty<'static, usize, { 0 }>;
- //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
- //~| ERROR this struct takes 0 generic arguments but 2 generic arguments were supplied
+ //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
+ //~| ERROR this struct takes 0 generic arguments but 2 generic arguments
//~| HELP remove this lifetime argument
//~| HELP remove these generic arguments
}
type A = Ty;
//~^ ERROR missing generics for struct `type_and_type::Ty`
- //~| HELP use angle brackets
+ //~| HELP add missing
type B = Ty<usize>;
- //~^ ERROR this struct takes 2 type arguments but only 1 type argument was supplied
- //~| HELP add missing type argument
+ //~^ ERROR this struct takes 2 generic arguments but 1 generic argument
+ //~| HELP add missing
type C = Ty<usize, String>;
type D = Ty<usize, String, char>;
- //~^ ERROR this struct takes 2 type arguments but 3 type arguments were supplied
- //~| HELP remove this type argument
+ //~^ ERROR this struct takes 2 generic arguments but 3 generic arguments
+ //~| HELP remove this
}
mod lifetime_and_type {
struct Ty<'a, T>;
type A = Ty;
- //~^ ERROR missing generics for struct `lifetime_and_type::Ty`
+ //~^ ERROR missing generics for struct
//~| ERROR missing lifetime specifier
+ //~| HELP add missing
//~| HELP consider introducing
- //~| HELP use angle brackets
type B = Ty<'static>;
- //~^ ERROR this struct takes 1 type argument but 0 type arguments were supplied
- //~| HELP add missing type argument
+ //~^ ERROR this struct takes 1 generic argument but 0 generic arguments
+ //~| HELP add missing
type C = Ty<usize>;
//~^ ERROR missing lifetime specifier
type A = Ty;
//~^ ERROR missing generics for struct `type_and_type_and_type::Ty`
- //~| HELP use angle brackets
+ //~| HELP add missing
type B = Ty<usize>;
- //~^ ERROR this struct takes at least 2 type arguments but only 1 type argument was supplied
- //~| HELP add missing type argument
+ //~^ ERROR this struct takes at least 2
+ //~| HELP add missing
type C = Ty<usize, String>;
type D = Ty<usize, String, char>;
type E = Ty<usize, String, char, f64>;
- //~^ ERROR this struct takes at most 3 type arguments but 4 type arguments were supplied
+ //~^ ERROR this struct takes at most 3
//~| HELP remove
}
}
type A = Box<dyn NonGeneric<usize>>;
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
//~| HELP remove
type B = Box<dyn GenericLifetime>;
type D = Box<dyn GenericType>;
//~^ ERROR missing generics for trait `GenericType`
- //~| HELP use angle brackets
+ //~| HELP add missing
type E = Box<dyn GenericType<String, usize>>;
- //~^ ERROR this trait takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this trait takes 1 generic argument but 2 generic arguments
//~| HELP remove
}
type A = HashMap;
//~^ ERROR missing generics for struct `HashMap`
- //~| HELP use angle brackets
+ //~| HELP add missing
type B = HashMap<String>;
- //~^ ERROR this struct takes at least 2 type arguments but only 1 type argument was supplied
- //~| HELP add missing type argument
+ //~^ ERROR this struct takes at least
+ //~| HELP add missing
type C = HashMap<'static>;
- //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
+ //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument
//~| HELP remove these generics
- //~| ERROR this struct takes at least 2 type arguments but 0 type arguments were supplied
- //~| HELP add missing type arguments
+ //~| ERROR this struct takes at least 2
+ //~| HELP add missing
type D = HashMap<usize, String, char, f64>;
- //~^ ERROR this struct takes at most 3 type arguments but 4 type arguments were supplied
- //~| HELP remove this type argument
+ //~^ ERROR this struct takes at most 3
+ //~| HELP remove this
}
mod result {
type A = Result;
//~^ ERROR missing generics for enum `Result`
- //~| HELP use angle brackets
+ //~| HELP add missing
type B = Result<String>;
- //~^ ERROR this enum takes 2 type arguments but only 1 type argument was supplied
- //~| HELP add missing type argument
+ //~^ ERROR this enum takes 2 generic arguments but 1 generic argument
+ //~| HELP add missing
type C = Result<'static>;
- //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument was supplied
+ //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument
//~| HELP remove these generics
- //~| ERROR this enum takes 2 type arguments but 0 type arguments were supplied
- //~| HELP add missing type arguments
+ //~| ERROR this enum takes 2 generic arguments but 0 generic arguments
+ //~| HELP add missing
type D = Result<usize, String, char>;
- //~^ ERROR this enum takes 2 type arguments but 3 type arguments were supplied
+ //~^ ERROR this enum takes 2 generic arguments but 3 generic arguments
//~| HELP remove
}
}
--> $DIR/wrong-number-of-args.rs:10:14
|
LL | type C = Ty<'static, usize>;
- | ^^ --------- help: remove this lifetime argument
+ | ^^ ------- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
LL | struct Ty;
| ^^
-error[E0107]: this struct takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:10:14
|
LL | type C = Ty<'static, usize>;
- | ^^ ------- help: remove this type argument
+ | ^^ ----- help: remove this generic argument
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: struct defined here, with 0 type parameters
+note: struct defined here, with 0 generic parameters
--> $DIR/wrong-number-of-args.rs:2:12
|
LL | struct Ty;
--> $DIR/wrong-number-of-args.rs:16:14
|
LL | type D = Ty<'static, usize, { 0 }>;
- | ^^ --------- help: remove this lifetime argument
+ | ^^ ------- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
--> $DIR/wrong-number-of-args.rs:16:14
|
LL | type D = Ty<'static, usize, { 0 }>;
- | ^^ -------------- help: remove these generic arguments
+ | ^^ ------------ help: remove these generic arguments
| |
| expected 0 generic arguments
|
--> $DIR/wrong-number-of-args.rs:26:14
|
LL | type A = Ty;
- | ^^ expected 2 type arguments
+ | ^^ expected 2 generic arguments
|
-note: struct defined here, with 2 type parameters: `A`, `B`
+note: struct defined here, with 2 generic parameters: `A`, `B`
--> $DIR/wrong-number-of-args.rs:24:12
|
LL | struct Ty<A, B>;
| ^^ - -
-help: use angle brackets to add missing type arguments
+help: add missing generic arguments
|
LL | type A = Ty<A, B>;
- | ^^^^^^
+ | ^^^^^^^^
-error[E0107]: this struct takes 2 type arguments but only 1 type argument was supplied
+error[E0107]: this struct takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:30:14
|
LL | type B = Ty<usize>;
- | ^^ ----- supplied 1 type argument
+ | ^^ ----- supplied 1 generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: struct defined here, with 2 type parameters: `A`, `B`
+note: struct defined here, with 2 generic parameters: `A`, `B`
--> $DIR/wrong-number-of-args.rs:24:12
|
LL | struct Ty<A, B>;
| ^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | type B = Ty<usize, B>;
| ^^^
-error[E0107]: this struct takes 2 type arguments but 3 type arguments were supplied
+error[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:36:14
|
LL | type D = Ty<usize, String, char>;
- | ^^ ------ help: remove this type argument
+ | ^^ ---- help: remove this generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: struct defined here, with 2 type parameters: `A`, `B`
+note: struct defined here, with 2 generic parameters: `A`, `B`
--> $DIR/wrong-number-of-args.rs:24:12
|
LL | struct Ty<A, B>;
--> $DIR/wrong-number-of-args.rs:44:14
|
LL | type A = Ty;
- | ^^ expected 1 type argument
+ | ^^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/wrong-number-of-args.rs:42:12
|
LL | struct Ty<'a, T>;
| ^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | type A = Ty<T>;
- | ^^^
+ | ^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/wrong-number-of-args.rs:44:14
LL | type A<'a> = Ty<'a>;
| ^^^^ ^^^^^^
-error[E0107]: this struct takes 1 type argument but 0 type arguments were supplied
+error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:50:14
|
LL | type B = Ty<'static>;
- | ^^ expected 1 type argument
+ | ^^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/wrong-number-of-args.rs:42:12
|
LL | struct Ty<'a, T>;
| ^^ -
-help: add missing type argument
+help: add missing generic argument
|
LL | type B = Ty<'static, T>;
| ^^^
--> $DIR/wrong-number-of-args.rs:64:14
|
LL | type A = Ty;
- | ^^ expected at least 2 type arguments
+ | ^^ expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `A`, `B`
+note: struct defined here, with at least 2 generic parameters: `A`, `B`
--> $DIR/wrong-number-of-args.rs:62:12
|
LL | struct Ty<A, B, C = &'static str>;
| ^^ - -
-help: use angle brackets to add missing type arguments
+help: add missing generic arguments
|
LL | type A = Ty<A, B>;
- | ^^^^^^
+ | ^^^^^^^^
-error[E0107]: this struct takes at least 2 type arguments but only 1 type argument was supplied
+error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:68:14
|
LL | type B = Ty<usize>;
- | ^^ ----- supplied 1 type argument
+ | ^^ ----- supplied 1 generic argument
| |
- | expected at least 2 type arguments
+ | expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `A`, `B`
+note: struct defined here, with at least 2 generic parameters: `A`, `B`
--> $DIR/wrong-number-of-args.rs:62:12
|
LL | struct Ty<A, B, C = &'static str>;
| ^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | type B = Ty<usize, B>;
| ^^^
-error[E0107]: this struct takes at most 3 type arguments but 4 type arguments were supplied
+error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:76:14
|
LL | type E = Ty<usize, String, char, f64>;
- | ^^ ----- help: remove this type argument
+ | ^^ --- help: remove this generic argument
| |
- | expected at most 3 type arguments
+ | expected at most 3 generic arguments
|
-note: struct defined here, with at most 3 type parameters: `A`, `B`, `C`
+note: struct defined here, with at most 3 generic parameters: `A`, `B`, `C`
--> $DIR/wrong-number-of-args.rs:62:12
|
LL | struct Ty<A, B, C = &'static str>;
| ^^ - - -
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:96:22
|
LL | type A = Box<dyn NonGeneric<usize>>;
| ^^^^^^^^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/wrong-number-of-args.rs:84:11
|
LL | trait NonGeneric {
--> $DIR/wrong-number-of-args.rs:104:22
|
LL | type C = Box<dyn GenericLifetime<'static, 'static>>;
- | ^^^^^^^^^^^^^^^ --------- help: remove this lifetime argument
+ | ^^^^^^^^^^^^^^^ ------- help: remove this lifetime argument
| |
| expected 1 lifetime argument
|
--> $DIR/wrong-number-of-args.rs:108:22
|
LL | type D = Box<dyn GenericType>;
- | ^^^^^^^^^^^ expected 1 type argument
+ | ^^^^^^^^^^^ expected 1 generic argument
|
-note: trait defined here, with 1 type parameter: `A`
+note: trait defined here, with 1 generic parameter: `A`
--> $DIR/wrong-number-of-args.rs:92:11
|
LL | trait GenericType<A> {
| ^^^^^^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | type D = Box<dyn GenericType<A>>;
- | ^^^
+ | ^^^^^^^^^^^^^^
-error[E0107]: this trait takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:112:22
|
LL | type E = Box<dyn GenericType<String, usize>>;
- | ^^^^^^^^^^^ ------- help: remove this type argument
+ | ^^^^^^^^^^^ ----- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: trait defined here, with 1 type parameter: `A`
+note: trait defined here, with 1 generic parameter: `A`
--> $DIR/wrong-number-of-args.rs:92:11
|
LL | trait GenericType<A> {
--> $DIR/wrong-number-of-args.rs:121:18
|
LL | type A = HashMap;
- | ^^^^^^^ expected at least 2 type arguments
+ | ^^^^^^^ expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `K`, `V`
+note: struct defined here, with at least 2 generic parameters: `K`, `V`
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
LL | pub struct HashMap<K, V, S = RandomState> {
| ^^^^^^^ - -
-help: use angle brackets to add missing type arguments
+help: add missing generic arguments
|
LL | type A = HashMap<K, V>;
- | ^^^^^^
+ | ^^^^^^^^^^^^^
-error[E0107]: this struct takes at least 2 type arguments but only 1 type argument was supplied
+error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:125:18
|
LL | type B = HashMap<String>;
- | ^^^^^^^ ------ supplied 1 type argument
+ | ^^^^^^^ ------ supplied 1 generic argument
| |
- | expected at least 2 type arguments
+ | expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `K`, `V`
+note: struct defined here, with at least 2 generic parameters: `K`, `V`
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
LL | pub struct HashMap<K, V, S = RandomState> {
| ^^^^^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | type B = HashMap<String, V>;
| ^^^
LL | pub struct HashMap<K, V, S = RandomState> {
| ^^^^^^^
-error[E0107]: this struct takes at least 2 type arguments but 0 type arguments were supplied
+error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:129:18
|
LL | type C = HashMap<'static>;
- | ^^^^^^^ expected at least 2 type arguments
+ | ^^^^^^^ expected at least 2 generic arguments
|
-note: struct defined here, with at least 2 type parameters: `K`, `V`
+note: struct defined here, with at least 2 generic parameters: `K`, `V`
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
LL | pub struct HashMap<K, V, S = RandomState> {
| ^^^^^^^ - -
-help: add missing type arguments
+help: add missing generic arguments
|
LL | type C = HashMap<'static, K, V>;
| ^^^^^^
-error[E0107]: this struct takes at most 3 type arguments but 4 type arguments were supplied
+error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:135:18
|
LL | type D = HashMap<usize, String, char, f64>;
- | ^^^^^^^ ----- help: remove this type argument
+ | ^^^^^^^ --- help: remove this generic argument
| |
- | expected at most 3 type arguments
+ | expected at most 3 generic arguments
|
-note: struct defined here, with at most 3 type parameters: `K`, `V`, `S`
+note: struct defined here, with at most 3 generic parameters: `K`, `V`, `S`
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
|
LL | pub struct HashMap<K, V, S = RandomState> {
--> $DIR/wrong-number-of-args.rs:141:18
|
LL | type A = Result;
- | ^^^^^^ expected 2 type arguments
+ | ^^^^^^ expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: use angle brackets to add missing type arguments
+help: add missing generic arguments
|
LL | type A = Result<T, E>;
- | ^^^^^^
+ | ^^^^^^^^^^^^
-error[E0107]: this enum takes 2 type arguments but only 1 type argument was supplied
+error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/wrong-number-of-args.rs:145:18
|
LL | type B = Result<String>;
- | ^^^^^^ ------ supplied 1 type argument
+ | ^^^^^^ ------ supplied 1 generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | type B = Result<String, E>;
| ^^^
LL | pub enum Result<T, E> {
| ^^^^^^
-error[E0107]: this enum takes 2 type arguments but 0 type arguments were supplied
+error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:149:18
|
LL | type C = Result<'static>;
- | ^^^^^^ expected 2 type arguments
+ | ^^^^^^ expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: add missing type arguments
+help: add missing generic arguments
|
LL | type C = Result<'static, T, E>;
| ^^^^^^
-error[E0107]: this enum takes 2 type arguments but 3 type arguments were supplied
+error[E0107]: this enum takes 2 generic arguments but 3 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:155:18
|
LL | type D = Result<usize, String, char>;
- | ^^^^^^ ------ help: remove this type argument
+ | ^^^^^^ ---- help: remove this generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
/*
Expansions:
0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
-1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "foo")
+1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "foo", proc_macro: false }
SyntaxContexts:
#0: parent: #0, outer_mark: (ExpnId(0), Opaque)
#![stable(feature = "rust1", since = "1.0.0")]
#![feature(staged_api)]
-#![feature(const_transmute, const_fn)]
+#![feature(const_transmute)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
--> $DIR/issue-14092.rs:1:11
|
LL | fn fn1(0: Box) {}
- | ^^^ expected at least 1 type argument
+ | ^^^ expected at least 1 generic argument
|
-note: struct defined here, with at least 1 type parameter: `T`
+note: struct defined here, with at least 1 generic parameter: `T`
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
LL | pub struct Box<
| ^^^
LL | T: ?Sized,
| -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | fn fn1(0: Box<T>) {}
- | ^^^
+ | ^^^^^^
error: aborting due to previous error
--> $DIR/issue-18423.rs:4:8
|
LL | x: Box<'a, isize>
- | ^^^ ---- help: remove this lifetime argument
+ | ^^^ -- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
--> $DIR/issue-23024.rs:9:39
|
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
- | ^^ expected 1 type argument
+ | ^^ expected 1 generic argument
|
-note: trait defined here, with 1 type parameter: `Args`
+note: trait defined here, with 1 generic parameter: `Args`
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args>: FnMut<Args> {
| ^^ ----
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
- | ^^^^^^
+ | ^^^^^^^^
error[E0191]: the value of the associated type `Output` (from trait `FnOnce`) must be specified
--> $DIR/issue-23024.rs:9:39
}
impl<T> Drop for Foo<T> {
- //~^ ERROR this struct takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this struct takes 0 generic arguments but 1 generic argument
//~| ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates
fn drop(&mut self) {}
}
LL | x: T,
| ^ use of generic parameter from outer function
-error[E0107]: this struct takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-3214.rs:6:22
|
LL | impl<T> Drop for Foo<T> {
| ^^^--- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: struct defined here, with 0 type parameters
+note: struct defined here, with 0 generic parameters
--> $DIR/issue-3214.rs:2:12
|
LL | struct Foo {
$(
fn $n() {
S::f::<i64>();
- //~^ ERROR this associated function takes 0 type arguments but 1 type argument was supplied
- //~| ERROR this associated function takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this associated function takes 0 generic
+ //~| ERROR this associated function takes 0 generic
}
)*
}
-error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-53251.rs:11:20
|
LL | S::f::<i64>();
| ^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
...
LL | impl_add!(a b);
| --------------- in this macro invocation
|
-note: associated function defined here, with 0 type parameters
+note: associated function defined here, with 0 generic parameters
--> $DIR/issue-53251.rs:4:8
|
LL | fn f() {}
| ^
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-53251.rs:11:20
|
LL | S::f::<i64>();
| ^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
...
LL | impl_add!(a b);
| --------------- in this macro invocation
|
-note: associated function defined here, with 0 type parameters
+note: associated function defined here, with 0 generic parameters
--> $DIR/issue-53251.rs:4:8
|
LL | fn f() {}
-#![feature(const_fn)]
-
const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
//~^ ERROR type annotations needed
error[E0379]: functions in traits cannot be declared const
- --> $DIR/issue-54954.rs:7:5
+ --> $DIR/issue-54954.rs:5:5
|
LL | const fn const_val<T: Sized>() -> usize {
| ^^^^^ functions in traits cannot be const
error[E0283]: type annotations needed
- --> $DIR/issue-54954.rs:3:24
+ --> $DIR/issue-54954.rs:1:24
|
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
fn run_wild<T>(b: &Borked) {
b.a::<'_, T>();
//~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
- //~| ERROR this associated function takes 0 type arguments but 1 type argument was supplied
+ //~| ERROR this associated function takes 0 generic arguments but 1 generic argument
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
}
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
-error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/issue-60622.rs:10:7
|
LL | b.a::<'_, T>();
- | ^ --- help: remove this type argument
+ | ^ - help: remove this generic argument
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: associated function defined here, with 0 type parameters
+note: associated function defined here, with 0 generic parameters
--> $DIR/issue-60622.rs:6:8
|
LL | fn a(&self) {}
| ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:26:9
+ --> $DIR/lint-stability-deprecated.rs:26:14
|
LL | Foo::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:27:9
+ --> $DIR/lint-stability-deprecated.rs:27:16
|
LL | <Foo>::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
--> $DIR/lint-stability-deprecated.rs:28:13
| ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:30:9
+ --> $DIR/lint-stability-deprecated.rs:30:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:34:13
| ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:35:9
+ --> $DIR/lint-stability-deprecated.rs:35:14
|
LL | ... Foo::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:36:9
+ --> $DIR/lint-stability-deprecated.rs:36:16
|
LL | ... <Foo>::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:37:13
| ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:39:9
+ --> $DIR/lint-stability-deprecated.rs:39:16
|
LL | ... <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
--> $DIR/lint-stability-deprecated.rs:43:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:44:9
+ --> $DIR/lint-stability-deprecated.rs:44:14
|
LL | ... Foo::method_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:45:9
+ --> $DIR/lint-stability-deprecated.rs:45:16
|
LL | ... <Foo>::method_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
--> $DIR/lint-stability-deprecated.rs:46:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:48:9
+ --> $DIR/lint-stability-deprecated.rs:48:16
|
LL | ... <Foo>::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
--> $DIR/lint-stability-deprecated.rs:52:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:53:9
+ --> $DIR/lint-stability-deprecated.rs:53:14
|
LL | ... Foo::method_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:54:9
+ --> $DIR/lint-stability-deprecated.rs:54:16
|
LL | ... <Foo>::method_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
--> $DIR/lint-stability-deprecated.rs:55:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:57:9
+ --> $DIR/lint-stability-deprecated.rs:57:16
|
LL | ... <Foo>::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text
--> $DIR/lint-stability-deprecated.rs:109:13
| ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:146:9
+ --> $DIR/lint-stability-deprecated.rs:146:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:148:13
| ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:150:9
+ --> $DIR/lint-stability-deprecated.rs:150:16
|
LL | ... <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
--> $DIR/lint-stability-deprecated.rs:152:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:154:9
+ --> $DIR/lint-stability-deprecated.rs:154:16
|
LL | ... <Foo>::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
--> $DIR/lint-stability-deprecated.rs:156:13
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:158:9
+ --> $DIR/lint-stability-deprecated.rs:158:16
|
LL | ... <Foo>::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
--> $DIR/lint-stability-deprecated.rs:175:13
| ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:332:9
+ --> $DIR/lint-stability-deprecated.rs:332:14
|
LL | Foo::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:333:9
+ --> $DIR/lint-stability-deprecated.rs:333:16
|
LL | <Foo>::method_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
--> $DIR/lint-stability-deprecated.rs:334:13
| ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:336:9
+ --> $DIR/lint-stability-deprecated.rs:336:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:340:13
| ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:341:9
+ --> $DIR/lint-stability-deprecated.rs:341:14
|
LL | ... Foo::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:342:9
+ --> $DIR/lint-stability-deprecated.rs:342:16
|
LL | ... <Foo>::method_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:343:13
| ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:345:9
+ --> $DIR/lint-stability-deprecated.rs:345:16
|
LL | <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text
--> $DIR/lint-stability-deprecated.rs:386:13
| ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:407:9
+ --> $DIR/lint-stability-deprecated.rs:407:16
|
LL | <Foo>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:409:13
| ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:411:9
+ --> $DIR/lint-stability-deprecated.rs:411:16
|
LL | <Foo>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
--> $DIR/lint-stability-deprecated.rs:428:13
}
};
- // Check that all spans are equal.
- // FIXME: `quote!` gives def-site spans to idents and literals,
- // but leaves (default) call-site spans on groups and punctuation.
- let mut span_call = None;
- let mut span_def = None;
- for tt in result.clone() {
- match tt {
- TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
- None => span_def = Some(tt.span()),
- Some(span) => assert_same_span(tt.span(), span),
- }
- TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
- None => span_call = Some(tt.span()),
- Some(span) => assert_same_span(tt.span(), span),
- }
- }
-
- }
-
result
}
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
--> $DIR/same-sequence-span.rs:19:1
|
-LL | proc_macro_sequence::make_foo!();
- | ---------------------------------^^^^^^^^^^^^^
+LL | proc_macro_sequence::make_foo!();
+ | ^--------------------------------
+ | |
+ | _in this macro invocation
| |
- | not allowed after `expr` fragments
- | in this macro invocation
+LL | |
+LL | |
+LL | | fn main() {}
+ | |_________________________________^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
fn method_call() {
S.early(); // OK
S.early::<'static>();
- //~^ ERROR this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument
S.early::<'static, 'static, 'static>();
//~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
let _: &u8 = S.life_and_type::<'static>();
S::early(S); // OK
S::early::<'static>(S);
- //~^ ERROR this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument
S::early::<'static, 'static, 'static>(S);
//~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
let _: &u8 = S::life_and_type::<'static>(S);
-error[E0107]: this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/method-call-lifetime-args-fail.rs:16:7
|
LL | S.early::<'static>();
--> $DIR/method-call-lifetime-args-fail.rs:18:7
|
LL | S.early::<'static, 'static, 'static>();
- | ^^^^^ --------- help: remove this lifetime argument
+ | ^^^^^ ------- help: remove this lifetime argument
| |
| expected 2 lifetime arguments
|
LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} }
| ^^
-error[E0107]: this associated function takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/method-call-lifetime-args-fail.rs:63:8
|
LL | S::early::<'static>(S);
--> $DIR/method-call-lifetime-args-fail.rs:65:8
|
LL | S::early::<'static, 'static, 'static>(S);
- | ^^^^^ --------- help: remove this lifetime argument
+ | ^^^^^ ------- help: remove this lifetime argument
| |
| expected 2 lifetime arguments
|
-#![feature(const_fn)]
-
trait Foo {
fn f() -> u32;
const fn g(); //~ ERROR cannot be declared const
error[E0379]: functions in traits cannot be declared const
- --> $DIR/const-fn-in-trait.rs:5:5
+ --> $DIR/const-fn-in-trait.rs:3:5
|
LL | const fn g();
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
- --> $DIR/const-fn-in-trait.rs:9:5
+ --> $DIR/const-fn-in-trait.rs:7:5
|
LL | const fn f() -> u32 { 22 }
| ^^^^^ functions in traits cannot be const
--- /dev/null
+/* Checks whether primitive type names are formatted correctly in the
+ * error messages about mismatched types (#84976).
+ */
+
+fn foo(length: &u32) -> i32 {
+ 0
+}
+
+fn bar(length: &f32) -> f64 {
+ 0.0
+}
+
+fn main() {
+ let mut length = 0;
+ length = { foo(&length) };
+ //~^ ERROR mismatched types [E0308]
+ length = foo(&length);
+ //~^ ERROR mismatched types [E0308]
+
+ let mut float_length = 0.0;
+ float_length = { bar(&float_length) };
+ //~^ ERROR mismatched types [E0308]
+ float_length = bar(&float_length);
+ //~^ ERROR mismatched types [E0308]
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:15:16
+ |
+LL | length = { foo(&length) };
+ | ^^^^^^^^^^^^ expected `u32`, found `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:17:14
+ |
+LL | length = foo(&length);
+ | ^^^^^^^^^^^^ expected `u32`, found `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:21:22
+ |
+LL | float_length = { bar(&float_length) };
+ | ^^^^^^^^^^^^^^^^^^ expected `f32`, found `f64`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-84976.rs:23:20
+ |
+LL | float_length = bar(&float_length);
+ | ^^^^^^^^^^^^^^^^^^ expected `f32`, found `f64`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
// edition:2018
#![feature(const_extern_fn)]
-#![feature(const_fn)]
fn main() {
async fn ff1() {} // OK.
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:13:5
+ --> $DIR/fn-header-semantic-fail.rs:12:5
|
LL | const async unsafe extern "C" fn ff5() {} // OK.
| ^^^^^-^^^^^------------------------------
| `const` because of this
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:17:9
+ --> $DIR/fn-header-semantic-fail.rs:16:9
|
LL | async fn ft1();
| -----^^^^^^^^^^
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:19:9
+ --> $DIR/fn-header-semantic-fail.rs:18:9
|
LL | const fn ft3();
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:21:9
+ --> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^ functions in traits cannot be const
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:21:9
+ --> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:21:9
+ --> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^-^^^^^----------------------------
| `const` because of this
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:29:9
+ --> $DIR/fn-header-semantic-fail.rs:28:9
|
LL | async fn ft1() {}
| -----^^^^^^^^^^^^
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:32:9
+ --> $DIR/fn-header-semantic-fail.rs:31:9
|
LL | const fn ft3() {}
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^ functions in traits cannot be const
error[E0706]: functions in traits cannot be declared `async`
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:34:9
+ --> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^-^^^^^------------------------------
| `const` because of this
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:46:9
+ --> $DIR/fn-header-semantic-fail.rs:45:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^-^^^^^------------------------------
| `const` because of this
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:51:18
+ --> $DIR/fn-header-semantic-fail.rs:50:18
|
LL | extern "C" {
| ---------- in this `extern` block
| ^^
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:52:19
+ --> $DIR/fn-header-semantic-fail.rs:51:19
|
LL | extern "C" {
| ---------- in this `extern` block
| ^^
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:53:18
+ --> $DIR/fn-header-semantic-fail.rs:52:18
|
LL | extern "C" {
| ---------- in this `extern` block
| ^^
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:54:23
+ --> $DIR/fn-header-semantic-fail.rs:53:23
|
LL | extern "C" {
| ---------- in this `extern` block
| ^^
error: functions in `extern` blocks cannot have qualifiers
- --> $DIR/fn-header-semantic-fail.rs:55:42
+ --> $DIR/fn-header-semantic-fail.rs:54:42
|
LL | extern "C" {
| ---------- in this `extern` block
| ^^
error: functions cannot be both `const` and `async`
- --> $DIR/fn-header-semantic-fail.rs:55:9
+ --> $DIR/fn-header-semantic-fail.rs:54:9
|
LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^----------------------------
| `const` because of this
error[E0053]: method `ft1` has an incompatible type for trait
- --> $DIR/fn-header-semantic-fail.rs:29:24
+ --> $DIR/fn-header-semantic-fail.rs:28:24
|
LL | async fn ft1();
| - type in trait
found fn pointer `fn() -> impl Future`
error[E0053]: method `ft5` has an incompatible type for trait
- --> $DIR/fn-header-semantic-fail.rs:34:48
+ --> $DIR/fn-header-semantic-fail.rs:33:48
|
LL | const async unsafe extern "C" fn ft5();
| - type in trait
--- /dev/null
+// run-rustfix
+#![allow(dead_code)]
+
+enum E {
+ A,
+}
+
+struct S {
+ field1: i32, //~ ERROR default values on `struct` fields aren't supported
+ field2: E, //~ ERROR default values on `struct` fields aren't supported
+ field3: i32, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32, //~ ERROR default values on `struct` fields aren't supported
+ field5: E, //~ ERROR default values on `struct` fields aren't supported
+ field6: E, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S1 {
+ field1: i32, //~ ERROR expected `,`, or `}`, found `field2`
+ field2: E, //~ ERROR expected `,`, or `}`, found `field3`
+ field3: i32, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32, //~ ERROR default values on `struct` fields aren't supported
+ field5: E, //~ ERROR default values on `struct` fields aren't supported
+ field6: E, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S2 {
+ field1 : i32, //~ ERROR expected `:`, found `=`
+ field2: E, //~ ERROR expected `:`, found `;`
+}
+
+const fn foo(_: i32) -> E {
+ E::A
+}
+
+fn main() {}
--- /dev/null
+// run-rustfix
+#![allow(dead_code)]
+
+enum E {
+ A,
+}
+
+struct S {
+ field1: i32 = 42, //~ ERROR default values on `struct` fields aren't supported
+ field2: E = E::A, //~ ERROR default values on `struct` fields aren't supported
+ field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported
+ field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported
+ field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S1 {
+ field1: i32 //~ ERROR expected `,`, or `}`, found `field2`
+ field2: E //~ ERROR expected `,`, or `}`, found `field3`
+ field3: i32 = 1 + 2, //~ ERROR default values on `struct` fields aren't supported
+ field4: i32 = { 1 + 2 }, //~ ERROR default values on `struct` fields aren't supported
+ field5: E = foo(42), //~ ERROR default values on `struct` fields aren't supported
+ field6: E = { foo(42) }, //~ ERROR default values on `struct` fields aren't supported
+}
+
+struct S2 {
+ field1 = i32, //~ ERROR expected `:`, found `=`
+ field2; E, //~ ERROR expected `:`, found `;`
+}
+
+const fn foo(_: i32) -> E {
+ E::A
+}
+
+fn main() {}
--- /dev/null
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:9:16
+ |
+LL | field1: i32 = 42,
+ | ^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:10:14
+ |
+LL | field2: E = E::A,
+ | ^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:11:16
+ |
+LL | field3: i32 = 1 + 2,
+ | ^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:12:16
+ |
+LL | field4: i32 = { 1 + 2 },
+ | ^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:13:14
+ |
+LL | field5: E = foo(42),
+ | ^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:14:14
+ |
+LL | field6: E = { foo(42) },
+ | ^^^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: expected `,`, or `}`, found `field2`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:18:16
+ |
+LL | field1: i32
+ | ^ help: try adding a comma: `,`
+
+error: expected `,`, or `}`, found `field3`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:19:14
+ |
+LL | field2: E
+ | ^ help: try adding a comma: `,`
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:20:16
+ |
+LL | field3: i32 = 1 + 2,
+ | ^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:21:16
+ |
+LL | field4: i32 = { 1 + 2 },
+ | ^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:22:14
+ |
+LL | field5: E = foo(42),
+ | ^^^^^^^^^^ help: remove this unsupported default value
+
+error: default values on `struct` fields aren't supported
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:23:14
+ |
+LL | field6: E = { foo(42) },
+ | ^^^^^^^^^^^^^^ help: remove this unsupported default value
+
+error: expected `:`, found `=`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:27:12
+ |
+LL | field1 = i32,
+ | ^
+ | |
+ | expected `:`
+ | help: field names and their types are separated with `:`
+
+error: expected `:`, found `;`
+ --> $DIR/struct-default-values-and-missing-field-separator.rs:28:11
+ |
+LL | field2; E,
+ | ^
+ | |
+ | expected `:`
+ | help: field names and their types are separated with `:`
+
+error: aborting due to 14 previous errors
+
--- /dev/null
+// force-host
+// no-prefer-dynamic
+// ignore-tidy-linelength
+
+#![feature(proc_macro_quote)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use std::str::FromStr;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn custom_quote(input: TokenStream) -> TokenStream {
+ let mut tokens: Vec<_> = input.into_iter().collect();
+ assert_eq!(tokens.len(), 1, "Unexpected input: {:?}", tokens);
+ match tokens.pop() {
+ Some(TokenTree::Ident(ident)) => {
+ assert_eq!(ident.to_string(), "my_ident");
+
+ let proc_macro_crate = TokenStream::from_str("::proc_macro").unwrap();
+ let quoted_span = proc_macro::quote_span(proc_macro_crate, ident.span());
+ let prefix = TokenStream::from_str(r#"let mut ident = proc_macro::Ident::new("my_ident", proc_macro::Span::call_site());"#).unwrap();
+ let set_span_method = TokenStream::from_str("ident.set_span").unwrap();
+ let set_span_arg = TokenStream::from(TokenTree::Group(Group::new(Delimiter::Parenthesis, quoted_span)));
+ let suffix = TokenStream::from_str(";proc_macro::TokenStream::from(proc_macro::TokenTree::Ident(ident))").unwrap();
+ let full_stream: TokenStream = std::array::IntoIter::new([prefix, set_span_method, set_span_arg, suffix]).collect();
+ full_stream
+ }
+ _ => unreachable!()
+ }
+}
--- /dev/null
+// force-host
+// no-prefer-dynamic
+
+#![feature(proc_macro_quote)]
+#![feature(proc_macro_internals)] // FIXME - this shouldn't be necessary
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+extern crate custom_quote;
+
+use proc_macro::{quote, TokenStream};
+
+macro_rules! expand_to_quote {
+ () => {
+ quote! {
+ let bang_error: bool = 25;
+ }
+ }
+}
+
+#[proc_macro]
+pub fn error_from_bang(_input: TokenStream) -> TokenStream {
+ expand_to_quote!()
+}
+
+#[proc_macro]
+pub fn other_error_from_bang(_input: TokenStream) -> TokenStream {
+ custom_quote::custom_quote! {
+ my_ident
+ }
+}
+
+#[proc_macro_attribute]
+pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream {
+ quote! {
+ struct AttributeError {
+ field: MissingType
+ }
+ }
+}
+
+#[proc_macro_derive(ErrorFromDerive)]
+pub fn error_from_derive(_input: TokenStream) -> TokenStream {
+ quote! {
+ enum DeriveError {
+ Variant(OtherMissingType)
+ }
+ }
+}
Expansions:
0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
-2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "produce_it")
+2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "produce_it", proc_macro: false }
3: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
-4: parent: ExpnId(2), call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "meta_macro::print_def_site")
-5: parent: ExpnId(4), call_site_ctxt: #5, def_site_ctxt: #0, kind: Macro(Bang, "$crate::dummy")
+4: parent: ExpnId(2), call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "meta_macro::print_def_site", proc_macro: true }
+5: parent: ExpnId(4), call_site_ctxt: #5, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "$crate::dummy", proc_macro: true }
SyntaxContexts:
#0: parent: #0, outer_mark: (ExpnId(0), Opaque)
Expansions:
0: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
1: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
-2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer")
+2: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "outer", proc_macro: false }
3: parent: ExpnId(0), call_site_ctxt: #0, def_site_ctxt: #0, kind: AstPass(StdImports)
-4: parent: ExpnId(2), call_site_ctxt: #4, def_site_ctxt: #4, kind: Macro(Bang, "inner")
-5: parent: ExpnId(4), call_site_ctxt: #6, def_site_ctxt: #0, kind: Macro(Bang, "print_bang")
+4: parent: ExpnId(2), call_site_ctxt: #4, def_site_ctxt: #4, kind: Macro { kind: Bang, name: "inner", proc_macro: false }
+5: parent: ExpnId(4), call_site_ctxt: #6, def_site_ctxt: #0, kind: Macro { kind: Bang, name: "print_bang", proc_macro: true }
SyntaxContexts:
#0: parent: #0, outer_mark: (ExpnId(0), Opaque)
--- /dev/null
+// check-pass
+// force-host
+// no-prefer-dynamic
+// compile-flags: -Z unpretty=expanded
+//
+// This file is not actually used as a proc-macro - instead,
+// it's just used to show the output of the `quote!` macro
+
+#![feature(proc_macro_quote)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+fn main() {
+ proc_macro::quote! {
+ let hello = "world";
+ }
+}
--- /dev/null
+#![feature(prelude_import)]
+#![no_std]
+// check-pass
+// force-host
+// no-prefer-dynamic
+// compile-flags: -Z unpretty=expanded
+//
+// This file is not actually used as a proc-macro - instead,
+// it's just used to show the output of the `quote!` macro
+
+#![feature(proc_macro_quote)]
+#![crate_type = "proc-macro"]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+extern crate proc_macro;
+
+fn main() {
+ [crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("let",
+ crate::Span::recover_proc_macro_span(0)))),
+ crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("hello",
+ crate::Span::recover_proc_macro_span(1)))),
+ crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3d}',
+ crate::Spacing::Alone))),
+ crate::TokenStream::from(crate::TokenTree::Literal({
+ let mut iter =
+ "\"world\"".parse::<crate::TokenStream>().unwrap().into_iter();
+ if let (Some(crate::TokenTree::Literal(mut lit)),
+ None) =
+ (iter.next(),
+ iter.next())
+ {
+ lit.set_span(crate::Span::recover_proc_macro_span(2));
+ lit
+ } else {
+ {
+ ::core::panicking::panic("internal error: entered unreachable code")
+ }
+ }
+ })),
+ crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}',
+ crate::Spacing::Alone)))].iter().cloned().collect::<crate::TokenStream>()
+}
+const _: () =
+ {
+ extern crate proc_macro;
+ #[rustc_proc_macro_decls]
+ #[allow(deprecated)]
+ static _DECLS: &[proc_macro::bridge::client::ProcMacro] = &[];
+ };
--- /dev/null
+// aux-build:custom-quote.rs
+// aux-build:span-from-proc-macro.rs
+// compile-flags: -Z macro-backtrace
+
+#[macro_use]
+extern crate span_from_proc_macro;
+
+#[error_from_attribute] //~ ERROR cannot find type `MissingType`
+struct ShouldBeRemoved;
+
+#[derive(ErrorFromDerive)] //~ ERROR cannot find type `OtherMissingType`
+struct Kept;
+
+fn main() {
+ error_from_bang!(); //~ ERROR mismatched types
+ other_error_from_bang!(); //~ ERROR cannot find value `my_ident`
+}
--- /dev/null
+error[E0412]: cannot find type `MissingType` in this scope
+ --> $DIR/auxiliary/span-from-proc-macro.rs:37:20
+ |
+LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream {
+ | ----------------------------------------------------------------------------------- in this expansion of procedural macro `#[error_from_attribute]`
+...
+LL | field: MissingType
+ | ^^^^^^^^^^^ not found in this scope
+ |
+ ::: $DIR/span-from-proc-macro.rs:8:1
+ |
+LL | #[error_from_attribute]
+ | ----------------------- in this macro invocation
+
+error[E0412]: cannot find type `OtherMissingType` in this scope
+ --> $DIR/auxiliary/span-from-proc-macro.rs:46:21
+ |
+LL | pub fn error_from_derive(_input: TokenStream) -> TokenStream {
+ | ------------------------------------------------------------ in this expansion of procedural macro `#[derive(ErrorFromDerive)]`
+...
+LL | Variant(OtherMissingType)
+ | ^^^^^^^^^^^^^^^^ not found in this scope
+ |
+ ::: $DIR/span-from-proc-macro.rs:11:10
+ |
+LL | #[derive(ErrorFromDerive)]
+ | --------------- in this macro invocation
+
+error[E0425]: cannot find value `my_ident` in this scope
+ --> $DIR/auxiliary/span-from-proc-macro.rs:29:9
+ |
+LL | pub fn other_error_from_bang(_input: TokenStream) -> TokenStream {
+ | ---------------------------------------------------------------- in this expansion of procedural macro `other_error_from_bang!`
+LL | custom_quote::custom_quote! {
+LL | my_ident
+ | ^^^^^^^^ not found in this scope
+ |
+ ::: $DIR/span-from-proc-macro.rs:16:5
+ |
+LL | other_error_from_bang!();
+ | ------------------------- in this macro invocation
+
+error[E0308]: mismatched types
+ --> $DIR/auxiliary/span-from-proc-macro.rs:16:36
+ |
+LL | let bang_error: bool = 25;
+ | ---- ^^ expected `bool`, found integer
+ | |
+ | expected due to this
+...
+LL | pub fn error_from_bang(_input: TokenStream) -> TokenStream {
+ | ---------------------------------------------------------- in this expansion of procedural macro `error_from_bang!`
+ |
+ ::: $DIR/span-from-proc-macro.rs:15:5
+ |
+LL | error_from_bang!();
+ | ------------------- in this macro invocation
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0412, E0425.
+For more information about an error, try `rustc --explain E0308`.
// run-pass
// compile-flags: -Z unleash-the-miri-inside-of-you
-#![feature(core_intrinsics, const_caller_location, const_fn)]
+#![feature(core_intrinsics, const_caller_location)]
type L = &'static std::panic::Location<'static>;
// revisions: default mir-opt
//[mir-opt] compile-flags: -Zmir-opt-level=4
-#![feature(const_caller_location, const_fn)]
+#![feature(const_caller_location)]
use std::panic::Location;
-#![feature(rustc_attrs, const_fn)]
+#![feature(rustc_attrs)]
#[rustc_args_required_const(0)]
fn foo(_a: i32) {
trait Seq { }
impl<T> Seq<T> for Vec<T> {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
/* ... */
}
impl Seq<bool> for u32 {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
/* Treat the integer as a sequence of bits */
}
}
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/seq-args.rs:4:13
|
LL | impl<T> Seq<T> for Vec<T> {
| ^^^--- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/seq-args.rs:2:11
|
LL | trait Seq { }
| ^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/seq-args.rs:9:10
|
LL | impl Seq<bool> for u32 {
| ^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/seq-args.rs:2:11
|
LL | trait Seq { }
// Various checks that stability attributes are used correctly, per RFC 507
-#![feature(const_fn, staged_api)]
+#![feature(staged_api)]
#![stable(feature = "rust1", since = "1.0.0")]
-#![feature(const_fn)]
-
struct WithDtor;
impl Drop for WithDtor {
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:9:60
+ --> $DIR/static-drop-scope.rs:7:60
|
LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
| ^^^^^^^^- value is dropped here
| statics cannot evaluate destructors
error[E0716]: temporary value dropped while borrowed
- --> $DIR/static-drop-scope.rs:9:60
+ --> $DIR/static-drop-scope.rs:7:60
|
LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
| ------^^^^^^^^-
| using this value as a static requires that borrow lasts for `'static`
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:13:59
+ --> $DIR/static-drop-scope.rs:11:59
|
LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
| ^^^^^^^^- value is dropped here
| constants cannot evaluate destructors
error[E0716]: temporary value dropped while borrowed
- --> $DIR/static-drop-scope.rs:13:59
+ --> $DIR/static-drop-scope.rs:11:59
|
LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
| ------^^^^^^^^-
| using this value as a constant requires that borrow lasts for `'static`
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:17:28
+ --> $DIR/static-drop-scope.rs:15:28
|
LL | static EARLY_DROP_S: i32 = (WithDtor, 0).1;
| ^^^^^^^^^^^^^ - value is dropped here
| statics cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:20:27
+ --> $DIR/static-drop-scope.rs:18:27
|
LL | const EARLY_DROP_C: i32 = (WithDtor, 0).1;
| ^^^^^^^^^^^^^ - value is dropped here
| constants cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:23:24
+ --> $DIR/static-drop-scope.rs:21:24
|
LL | const fn const_drop<T>(_: T) {}
| ^ - value is dropped here
| constant functions cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:27:5
+ --> $DIR/static-drop-scope.rs:25:5
|
LL | (x, ()).1
| ^^^^^^^ constant functions cannot evaluate destructors
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:31:34
+ --> $DIR/static-drop-scope.rs:29:34
|
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
| ^^^^^^^^^^^^^^^^^^^ - value is dropped here
| constants cannot evaluate destructors
error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/static-drop-scope.rs:36:43
+ --> $DIR/static-drop-scope.rs:34:43
|
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
| ^^^^^^^^^^^ - value is dropped here
y: 8,
};
- let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 type arguments but 1 type argument was supplied
+ let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
x: 9, //~ ERROR mismatched types
y: 10, //~ ERROR mismatched types
};
match (Point { x: 1, y: 2 }) {
- PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 type arguments but 1 type argument was supplied
+ PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 generic arguments but 1 generic argument
//~^ ERROR mismatched types
}
| expected `f32`, found integer
| help: use a float literal: `7.0`
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/structure-constructor-type-mismatch.rs:48:15
|
LL | let pt3 = PointF::<i32> {
| ^^^^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/structure-constructor-type-mismatch.rs:6:6
|
LL | type PointF = Point<f32>;
| expected `f32`, found integer
| help: use a float literal: `10.0`
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/structure-constructor-type-mismatch.rs:54:9
|
LL | PointF::<u32> { .. } => {}
| ^^^^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/structure-constructor-type-mismatch.rs:6:6
|
LL | type PointF = Point<f32>;
--- /dev/null
+use std::alloc::{GlobalAlloc, Layout};
+
+struct Test(u32);
+
+unsafe impl GlobalAlloc for Test {
+ unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
+ self.0 += 1; //~ ERROR cannot assign
+ 0 as *mut u8
+ }
+
+ unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
+ unimplemented!();
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+ --> $DIR/issue-68049-1.rs:7:9
+ |
+LL | self.0 += 1;
+ | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0594`.
--- /dev/null
+trait Hello {
+ fn example(&self, input: &i32); // should suggest here
+}
+
+struct Test1(i32);
+
+impl Hello for Test1 {
+ fn example(&self, input: &i32) { // should not suggest here
+ *input = self.0; //~ ERROR cannot assign
+ }
+}
+
+struct Test2(i32);
+
+impl Hello for Test2 {
+ fn example(&self, input: &i32) { // should not suggest here
+ self.0 += *input; //~ ERROR cannot assign
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0594]: cannot assign to `*input` which is behind a `&` reference
+ --> $DIR/issue-68049-2.rs:9:7
+ |
+LL | fn example(&self, input: &i32); // should suggest here
+ | ---- help: consider changing that to be a mutable reference: `&mut i32`
+...
+LL | *input = self.0;
+ | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
+
+error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+ --> $DIR/issue-68049-2.rs:17:5
+ |
+LL | fn example(&self, input: &i32); // should suggest here
+ | ----- help: consider changing that to be a mutable reference: `&mut self`
+...
+LL | self.0 += *input;
+ | ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0594`.
thread_local! {
static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
- //~^ ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
+ //~^ ERROR missing lifetime specifiers
+ //~| ERROR missing lifetime specifiers
}
thread_local! {
static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
- //~^ ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
+ //~^ ERROR missing lifetime specifier
+ //~| ERROR missing lifetime specifier
+ //~| ERROR missing lifetime specifier
+ //~| ERROR missing lifetime specifier
}
thread_local! {
static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
- //~^ ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
+ //~^ ERROR missing lifetime
+ //~| ERROR missing lifetime
}
thread_local! {
static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
- //~^ ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
+ //~^ ERROR missing lifetime
+ //~| ERROR missing lifetime
+ //~| ERROR missing lifetime
+ //~| ERROR missing lifetime
}
thread_local! {
static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
- //~^ ERROR this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
+ //~^ ERROR this union takes 2 lifetime arguments but 1 lifetime argument
+ //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied
}
thread_local! {
static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
- //~^ ERROR this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
- //~| ERROR missing lifetime specifier
- //~| ERROR missing lifetime specifier
+ //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
+ //~| ERROR missing lifetime
+ //~| ERROR missing lifetime
}
fn main() {}
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
-error[E0107]: this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
+LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
-error[E0107]: this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
-error[E0107]: this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
-error[E0107]: this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
+LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
-error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
+LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
error[E0106]: missing lifetime specifier
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
-error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
-error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
-error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
+error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^ -- --
help: add missing lifetime argument
|
-LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
+LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, '_, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^
error: aborting due to 22 previous errors
pub struct Foo {
i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
//~^ ERROR must be specified
- //~| ERROR this trait takes 2 type arguments but 4 type arguments were supplied
+ //~| ERROR this trait takes 2 generic arguments but 4 generic arguments were supplied
}
-error[E0107]: this trait takes 2 type arguments but 4 type arguments were supplied
+error[E0107]: this trait takes 2 generic arguments but 4 generic arguments were supplied
--> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
|
LL | i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
- | ^ -------------- help: remove these type arguments
+ | ^ ------------ help: remove these generic arguments
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: trait defined here, with 2 type parameters: `X`, `Y`
+note: trait defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/use-type-argument-instead-of-assoc-type.rs:1:11
|
LL | pub trait T<X, Y> {
--> $DIR/tag-type-args.rs:3:11
|
LL | fn foo(c: Quux) { assert!((false)); }
- | ^^^^ expected 1 type argument
+ | ^^^^ expected 1 generic argument
|
-note: enum defined here, with 1 type parameter: `T`
+note: enum defined here, with 1 generic parameter: `T`
--> $DIR/tag-type-args.rs:1:6
|
LL | enum Quux<T> { Bar }
| ^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | fn foo(c: Quux<T>) { assert!((false)); }
- | ^^^
+ | ^^^^^^^
error: aborting due to previous error
-#![feature(const_fn, thread_local)]
+#![feature(thread_local)]
#[thread_local]
static A: u32 = 1;
-#![feature(cfg_target_thread_local, const_fn, thread_local)]
+#![feature(cfg_target_thread_local, thread_local)]
#![crate_type = "lib"]
#[cfg(target_thread_local)]
-#![feature(const_fn)]
#![feature(thread_local)]
#![feature(cfg_target_thread_local, thread_local_internals)]
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:18:5
+ --> $DIR/issue-43733.rs:17:5
|
LL | __KEY.get(Default::default)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/issue-43733.rs:22:5
+ --> $DIR/issue-43733.rs:21:5
|
LL | std::thread::LocalKey::new(__getit);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
//~^ at least one trait is required for an object type
let _: S<'static, 'static>;
//~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied
- //~| ERROR this struct takes 1 type argument but 0 type arguments were supplied
+ //~| ERROR this struct takes 1 generic argument but 0 generic arguments were supplied
let _: S<dyn 'static +, 'static>;
//~^ ERROR type provided when a lifetime was expected
//~| ERROR at least one trait is required for an object type
--> $DIR/vs-lifetime.rs:11:12
|
LL | let _: S<'static, 'static>;
- | ^ --------- help: remove this lifetime argument
+ | ^ ------- help: remove this lifetime argument
| |
| expected 1 lifetime argument
|
LL | struct S<'a, T>(&'a u8, T);
| ^ --
-error[E0107]: this struct takes 1 type argument but 0 type arguments were supplied
+error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/vs-lifetime.rs:11:12
|
LL | let _: S<'static, 'static>;
- | ^ expected 1 type argument
+ | ^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/vs-lifetime.rs:4:8
|
LL | struct S<'a, T>(&'a u8, T);
| ^ -
-help: add missing type argument
+help: add missing generic argument
|
LL | let _: S<'static, 'static, T>;
| ^^^
fn main() {
10.dup::<i32>();
- //~^ ERROR this associated function takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this associated function takes 0 generic arguments but 1
10.blah::<i32, i32>();
- //~^ ERROR this associated function takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this associated function takes 1 generic argument but 2
(box 10 as Box<dyn bar>).dup();
//~^ ERROR E0038
//~| ERROR E0038
-error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/test-2.rs:9:8
|
LL | 10.dup::<i32>();
| ^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: associated function defined here, with 0 type parameters
+note: associated function defined here, with 0 generic parameters
--> $DIR/test-2.rs:4:16
|
LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
| ^^^
-error[E0107]: this associated function takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/test-2.rs:11:8
|
LL | 10.blah::<i32, i32>();
- | ^^^^ ----- help: remove this type argument
+ | ^^^^ --- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: associated function defined here, with 1 type parameter: `X`
+note: associated function defined here, with 1 generic parameter: `X`
--> $DIR/test-2.rs:4:39
|
LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
AliasFixed::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::<()>::TSVariant(());
- //~^ ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::TSVariant::<()>(());
//~^ ERROR type arguments are not allowed for this type [E0109]
- //~| ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
// Struct variant
AliasFixed::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::<()>::SVariant { v: () };
- //~^ ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::SVariant::<()> { v: () };
//~^ ERROR type arguments are not allowed for this type [E0109]
- //~| ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
// Unit variant
AliasFixed::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::<()>::UVariant;
- //~^ ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
AliasFixed::<()>::UVariant::<()>;
//~^ ERROR type arguments are not allowed for this type [E0109]
- //~| ERROR this type alias takes 0 type arguments but 1 type argument was supplied [E0107]
+ //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107]
}
LL | AliasFixed::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:64:5
|
LL | AliasFixed::<()>::TSVariant(());
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:66:5
|
LL | AliasFixed::<()>::TSVariant::<()>(());
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
LL | AliasFixed::SVariant::<()> { v: () };
| ^^ type argument not allowed
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:82:5
|
LL | AliasFixed::<()>::SVariant { v: () };
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:84:5
|
LL | AliasFixed::<()>::SVariant::<()> { v: () };
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
LL | AliasFixed::UVariant::<()>;
| ^^ type argument not allowed
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:100:5
|
LL | AliasFixed::<()>::UVariant;
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
| ^^^^^^^^^^
-error[E0107]: this type alias takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/enum-variant-generic-args.rs:102:5
|
LL | AliasFixed::<()>::UVariant::<()>;
| ^^^^^^^^^^------ help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: type alias defined here, with 0 type parameters
+note: type alias defined here, with 0 generic parameters
--> $DIR/enum-variant-generic-args.rs:9:6
|
LL | type AliasFixed = Enum<()>;
--> $DIR/issue-34255-1.rs:7:22
|
LL | input_cells: Vec::new()
- | ^^^ expected at least 1 type argument
+ | ^^^ expected at least 1 generic argument
|
-note: struct defined here, with at least 1 type parameter: `T`
+note: struct defined here, with at least 1 generic parameter: `T`
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| ^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | input_cells: Vec<T>::new()
- | ^^^
+ | ^^^^^^
error: aborting due to 3 previous errors
impl UI {
pub fn run() -> Result<_> {
- //~^ ERROR: this enum takes 2 type arguments but only 1 type argument was supplied
+ //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
//~| ERROR: the type placeholder `_` is not allowed within types on item signatures
let mut ui = UI {};
ui.interact();
}
pub fn interact(&mut self) -> Result<_> {
- //~^ ERROR: this enum takes 2 type arguments but only 1 type argument was supplied
+ //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied
//~| ERROR: the type placeholder `_` is not allowed within types on item signatures
unimplemented!();
}
-error[E0107]: this enum takes 2 type arguments but only 1 type argument was supplied
+error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/issue-75883.rs:6:21
|
LL | pub fn run() -> Result<_> {
- | ^^^^^^ - supplied 1 type argument
+ | ^^^^^^ - supplied 1 generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | pub fn run() -> Result<_, E> {
| ^^^
-error[E0107]: this enum takes 2 type arguments but only 1 type argument was supplied
+error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/issue-75883.rs:15:35
|
LL | pub fn interact(&mut self) -> Result<_> {
- | ^^^^^^ - supplied 1 type argument
+ | ^^^^^^ - supplied 1 generic argument
| |
- | expected 2 type arguments
+ | expected 2 generic arguments
|
-note: enum defined here, with 2 type parameters: `T`, `E`
+note: enum defined here, with 2 generic parameters: `T`, `E`
--> $SRC_DIR/core/src/result.rs:LL:COL
|
LL | pub enum Result<T, E> {
| ^^^^^^ - -
-help: add missing type argument
+help: add missing generic argument
|
LL | pub fn interact(&mut self) -> Result<_, E> {
| ^^^
fn foo1<T:Copy<U>, U>(x: T) {}
-//~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
trait Trait: Copy<dyn Send> {}
-//~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
struct MyStruct1<T: Copy<T>>;
-//~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
struct MyStruct2<'a, T: Copy<'a>>;
//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
-//~| ERROR this trait takes 0 type arguments but 1 type argument was supplied
+//~| ERROR this trait takes 0 generic arguments but 1 generic argument was supplied
fn main() { }
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/typeck-builtin-bound-type-parameters.rs:1:11
|
LL | fn foo1<T:Copy<U>, U>(x: T) {}
| ^^^^--- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
| ^^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/typeck-builtin-bound-type-parameters.rs:4:14
|
LL | trait Trait: Copy<dyn Send> {}
| ^^^^---------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
| ^^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/typeck-builtin-bound-type-parameters.rs:7:21
|
LL | struct MyStruct1<T: Copy<T>>;
| ^^^^--- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
--> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
|
LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
- | ^^^^ ---- help: remove this lifetime argument
+ | ^^^^ -- help: remove this lifetime argument
| |
| expected 0 lifetime arguments
|
LL | pub trait Copy: Clone {
| ^^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/typeck-builtin-bound-type-parameters.rs:13:15
|
LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
- | ^^^^ --- help: remove this type argument
+ | ^^^^ - help: remove this generic argument
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
LL | pub trait Copy: Clone {
pub fn main() {
let c: Foo<_, _> = Foo { r: &5 };
- //~^ ERROR this struct takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
}
-error[E0107]: this struct takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/typeck_type_placeholder_lifetime_1.rs:9:12
|
LL | let c: Foo<_, _> = Foo { r: &5 };
- | ^^^ --- help: remove this type argument
+ | ^^^ - help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/typeck_type_placeholder_lifetime_1.rs:4:8
|
LL | struct Foo<'a, T:'a> {
pub fn main() {
let c: Foo<_, usize> = Foo { r: &5 };
- //~^ ERROR this struct takes 1 type argument but 2 type arguments were supplied
+ //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied
}
-error[E0107]: this struct takes 1 type argument but 2 type arguments were supplied
+error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/typeck_type_placeholder_lifetime_2.rs:9:12
|
LL | let c: Foo<_, usize> = Foo { r: &5 };
- | ^^^ ------- help: remove this type argument
+ | ^^^ ----- help: remove this generic argument
| |
- | expected 1 type argument
+ | expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `T`
+note: struct defined here, with 1 generic parameter: `T`
--> $DIR/typeck_type_placeholder_lifetime_2.rs:4:8
|
LL | struct Foo<'a, T:'a> {
fn main() {
<String as IntoCow>::into_cow("foo".to_string());
- //~^ ERROR missing generics for trait `IntoCow`
+ //~^ ERROR missing generics for
<String as IntoCow>::into_cow::<str>("foo".to_string());
- //~^ ERROR missing generics for trait `IntoCow`
- //~| ERROR this associated function takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this associated function takes 0 generic arguments but 1
+ //~| ERROR missing generics for
}
--> $DIR/ufcs-qpath-missing-params.rs:14:16
|
LL | <String as IntoCow>::into_cow("foo".to_string());
- | ^^^^^^^ expected 1 type argument
+ | ^^^^^^^ expected 1 generic argument
|
-note: trait defined here, with 1 type parameter: `B`
+note: trait defined here, with 1 generic parameter: `B`
--> $DIR/ufcs-qpath-missing-params.rs:3:11
|
LL | pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
| ^^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | <String as IntoCow<B>>::into_cow("foo".to_string());
- | ^^^
+ | ^^^^^^^^^^
error[E0107]: missing generics for trait `IntoCow`
--> $DIR/ufcs-qpath-missing-params.rs:17:16
|
LL | <String as IntoCow>::into_cow::<str>("foo".to_string());
- | ^^^^^^^ expected 1 type argument
+ | ^^^^^^^ expected 1 generic argument
|
-note: trait defined here, with 1 type parameter: `B`
+note: trait defined here, with 1 generic parameter: `B`
--> $DIR/ufcs-qpath-missing-params.rs:3:11
|
LL | pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
| ^^^^^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | <String as IntoCow<B>>::into_cow::<str>("foo".to_string());
- | ^^^
+ | ^^^^^^^^^^
-error[E0107]: this associated function takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/ufcs-qpath-missing-params.rs:17:26
|
LL | <String as IntoCow>::into_cow::<str>("foo".to_string());
| ^^^^^^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: associated function defined here, with 0 type parameters
+note: associated function defined here, with 0 generic parameters
--> $DIR/ufcs-qpath-missing-params.rs:4:8
|
LL | fn into_cow(self) -> Cow<'a, B>;
--> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
|
LL | let x: Box<Bar()> = panic!();
- | ^^^ expected 1 type argument
+ | ^^^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `A`
+note: struct defined here, with 1 generic parameter: `A`
--> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:3:8
|
LL | struct Bar<A> {
| ^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | let x: Box<Bar<A>()> = panic!();
- | ^^^
+ | ^^^^^^
error: aborting due to 2 previous errors
--> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
|
LL | fn foo(b: Box<Bar()>) {
- | ^^^ expected 1 type argument
+ | ^^^ expected 1 generic argument
|
-note: struct defined here, with 1 type parameter: `A`
+note: struct defined here, with 1 generic parameter: `A`
--> $DIR/unboxed-closure-sugar-used-on-struct.rs:3:8
|
LL | struct Bar<A> {
| ^^^ -
-help: use angle brackets to add missing type argument
+help: add missing generic argument
|
LL | fn foo(b: Box<Bar<A>()>) {
- | ^^^
+ | ^^^^^^
error: aborting due to 2 previous errors
trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
fn foo(_: &dyn Three())
-//~^ ERROR this trait takes 3 type arguments but only 1 type argument was supplied
+//~^ ERROR this trait takes 3 generic arguments but 1 generic argument
//~| ERROR associated type `Output` not found
{}
-error[E0107]: this trait takes 3 type arguments but only 1 type argument was supplied
+error[E0107]: this trait takes 3 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
|
LL | fn foo(_: &dyn Three())
- | ^^^^^-- supplied 1 type argument
+ | ^^^^^-- supplied 1 generic argument
| |
- | expected 3 type arguments
+ | expected 3 generic arguments
|
-note: trait defined here, with 3 type parameters: `A`, `B`, `C`
+note: trait defined here, with 3 generic parameters: `A`, `B`, `C`
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:3:7
|
LL | trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); }
trait Zero { fn dummy(&self); }
fn foo1(_: dyn Zero()) {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
//~| ERROR associated type `Output` not found for `Zero`
}
fn foo2(_: dyn Zero<usize>) {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
}
fn foo3(_: dyn Zero < usize >) {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
}
fn foo4(_: dyn Zero(usize)) {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
//~| ERROR associated type `Output` not found for `Zero`
}
fn foo5(_: dyn Zero ( usize )) {
- //~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+ //~^ ERROR this trait takes 0 generic arguments but 1 generic argument
//~| ERROR associated type `Output` not found for `Zero`
}
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:16
|
LL | fn foo1(_: dyn Zero()) {
| ^^^^-- help: remove these parenthetical generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:3:7
|
LL | trait Zero { fn dummy(&self); }
LL | fn foo1(_: dyn Zero()) {
| ^^^^^^ associated type `Output` not found
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:10:16
|
LL | fn foo2(_: dyn Zero<usize>) {
| ^^^^------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:3:7
|
LL | trait Zero { fn dummy(&self); }
| ^^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:14:16
|
LL | fn foo3(_: dyn Zero < usize >) {
| ^^^^-------------- help: remove these generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:3:7
|
LL | trait Zero { fn dummy(&self); }
| ^^^^
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:18:16
|
LL | fn foo4(_: dyn Zero(usize)) {
| ^^^^------- help: remove these parenthetical generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:3:7
|
LL | trait Zero { fn dummy(&self); }
LL | fn foo4(_: dyn Zero(usize)) {
| ^^^^^^^^^^^ associated type `Output` not found
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:23:16
|
LL | fn foo5(_: dyn Zero ( usize )) {
| ^^^^-------------- help: remove these parenthetical generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:3:7
|
LL | trait Zero { fn dummy(&self); }
trait Trait {}
fn f<F:Trait(isize) -> isize>(x: F) {}
-//~^ ERROR this trait takes 0 type arguments but 1 type argument was supplied
+//~^ ERROR this trait takes 0 generic arguments but 1 generic argument
//~| ERROR associated type `Output` not found for `Trait`
fn main() {}
-error[E0107]: this trait takes 0 type arguments but 1 type argument was supplied
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:8
|
LL | fn f<F:Trait(isize) -> isize>(x: F) {}
| ^^^^^------- help: remove these parenthetical generics
| |
- | expected 0 type arguments
+ | expected 0 generic arguments
|
-note: trait defined here, with 0 type parameters
+note: trait defined here, with 0 generic parameters
--> $DIR/unboxed-closure-sugar-wrong-trait.rs:3:7
|
LL | trait Trait {}
// run-pass
-#![feature(const_fn)]
-
type Field1 = (i32, u32);
type Field2 = f32;
type Field3 = i64;
#![stable(feature = "foo", since = "1.33.0")]
#![feature(staged_api)]
#![feature(const_raw_ptr_deref)]
-#![feature(const_fn)]
#[stable(feature = "foo", since = "1.33.0")]
#[rustc_const_unstable(feature = "const_foo", issue = "none")]
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
- --> $DIR/unsafe-unstable-const-fn.rs:9:5
+ --> $DIR/unsafe-unstable-const-fn.rs:8:5
|
LL | *a == b
| ^^ dereference of raw pointer
-Subproject commit e51522ab3db23b0d8f1de54eb1f0113924896331
+Subproject commit 070e459c2d8b79c5b2ac5218064e7603329c92ae
impl MacroRefData {
pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self {
- let mut path = cx.sess().source_map().span_to_filename(callee).to_string();
+ let mut path = cx.sess().source_map().span_to_filename(callee).prefer_local().to_string();
// std lib paths are <::std::module::file type>
// so remove brackets, space and type.
let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
if let Some(callee) = span.source_callee() {
if !self.collected.contains(&call_site) {
- self.mac_refs
- .push(MacroRefData::new(name.to_string(), callee.def_site, cx));
+ self.mac_refs.push(MacroRefData::new(name.to_string(), callee.def_site, cx));
self.collected.insert(call_site);
}
}
.push((*item).to_string());
check_dup.push((*item).to_string());
}
- },
+ }
[root, rest @ ..] => {
if rest.iter().all(|item| !check_dup.contains(&(*item).to_string())) {
let filtered = rest
.push(rest.join("::"));
check_dup.extend(rest.iter().map(ToString::to_string));
}
- },
+ }
}
}
}
use rustc_span::hygiene::MacroKind;
if expr.span.from_expansion() {
let data = expr.span.ctxt().outer_expn_data();
- matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _))
+ matches!(data.kind, ExpnKind::Macro { kind: MacroKind::Attr, name: _, proc_macro: _ })
} else {
false
}
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
if expr.span.from_expansion() {
if let Some(callee) = expr.span.source_callee() {
- if let ExpnKind::Macro(MacroKind::Bang, symbol) = callee.kind {
+ if let ExpnKind::Macro { kind: MacroKind::Bang, name: symbol, proc_macro: _ } = callee.kind {
if let ExprKind::Binary(ref cmp, left, _) = expr.kind {
let op = cmp.node;
if op.is_comparison() && cx.typeck_results().expr_ty(left).is_unit() {
let data = span.ctxt().outer_expn_data();
let new_span = data.call_site;
- if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
+ if let ExpnKind::Macro { kind: MacroKind::Bang, name: mac_name, proc_macro: _ } = data.kind {
if mac_name.as_str() == name {
return Some(new_span);
}
let data = span.ctxt().outer_expn_data();
let new_span = data.call_site;
- if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind {
+ if let ExpnKind::Macro { kind: MacroKind::Bang, name: mac_name, proc_macro: _ } = data.kind {
if mac_name.as_str() == name {
return Some(new_span);
}
-#![feature(const_fn)]
#![allow(dead_code, clippy::missing_safety_doc)]
#![warn(clippy::new_without_default)]
error: you should consider adding a `Default` implementation for `Foo`
- --> $DIR/new_without_default.rs:8:5
+ --> $DIR/new_without_default.rs:7:5
|
LL | / pub fn new() -> Foo {
LL | | Foo
|
error: you should consider adding a `Default` implementation for `Bar`
- --> $DIR/new_without_default.rs:16:5
+ --> $DIR/new_without_default.rs:15:5
|
LL | / pub fn new() -> Self {
LL | | Bar
|
error: you should consider adding a `Default` implementation for `LtKo<'c>`
- --> $DIR/new_without_default.rs:80:5
+ --> $DIR/new_without_default.rs:79:5
|
LL | / pub fn new() -> LtKo<'c> {
LL | | unimplemented!()
|
error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
- --> $DIR/new_without_default.rs:157:5
+ --> $DIR/new_without_default.rs:156:5
|
LL | / pub fn new() -> Self {
LL | | NewNotEqualToDerive { foo: 1 }
|
error: you should consider adding a `Default` implementation for `FooGenerics<T>`
- --> $DIR/new_without_default.rs:165:5
+ --> $DIR/new_without_default.rs:164:5
|
LL | / pub fn new() -> Self {
LL | | Self(Default::default())
|
error: you should consider adding a `Default` implementation for `BarGenerics<T>`
- --> $DIR/new_without_default.rs:172:5
+ --> $DIR/new_without_default.rs:171:5
|
LL | / pub fn new() -> Self {
LL | | Self(Default::default())
.join("library");
normalize_path(&src_dir, "$SRC_DIR");
+ if let Some(virtual_rust_source_base_dir) =
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
+ {
+ normalize_path(&virtual_rust_source_base_dir.join("library"), "$SRC_DIR");
+ }
+
// Paths into the build directory
let test_build_dir = &self.config.build_base;
let parent_build_dir = test_build_dir.parent().unwrap().parent().unwrap().parent().unwrap();
"md-5",
"measureme",
"memchr",
- "memmap",
"memmap2",
"memoffset",
"miniz_oxide",