diff options
359 files changed, 8412 insertions, 3132 deletions
diff --git a/Cargo.lock b/Cargo.lock index bb37fee98e4..be95e63eb76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -854,7 +854,7 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", + "memoffset 0.7.1", "scopeguard", ] @@ -1242,6 +1242,16 @@ dependencies = [ ] [[package]] +name = "field-offset" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535" +dependencies = [ + "memoffset 0.8.0", + "rustc_version", +] + +[[package]] name = "filetime" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2190,6 +2200,15 @@ dependencies = [ [[package]] name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" @@ -2198,6 +2217,15 @@ dependencies = [ ] [[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3306,6 +3334,7 @@ dependencies = [ "rustc-hash", "rustc-rayon", "rustc-rayon-core", + "rustc_arena", "rustc_graphviz", "rustc_index", "rustc_macros", @@ -3781,6 +3810,7 @@ dependencies = [ "chalk-ir", "derive_more", "either", + "field-offset", "gsgdt", "measureme", "polonius-engine", @@ -3995,7 +4025,9 @@ dependencies = [ name = "rustc_query_impl" version = "0.0.0" dependencies = [ + "field-offset", "measureme", + "memoffset 0.6.5", "rustc-rayon-core", "rustc_ast", "rustc_data_structures", @@ -5122,9 +5154,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "ui_test" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95033b0e41b8018013d99a6f1486c1ae5bd080378ced60c5f797e93842423b33" +checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2" dependencies = [ "bstr 1.3.0", "cargo-platform", diff --git a/RELEASES.md b/RELEASES.md index e72905c15bd..85266a17550 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1481,7 +1481,7 @@ and related tools. [is_power_of_two_usize]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroUsize.html#method.is_power_of_two [stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266 -Version 1.58.1 (2022-01-19) +Version 1.58.1 (2022-01-20) =========================== * Fix race condition in `std::fs::remove_dir_all` ([CVE-2022-21658]) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index f0a6a5e0725..db296aa44db 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -48,14 +48,15 @@ pub enum TokenTree { Delimited(DelimSpan, Delimiter, TokenStream), } -// Ensure all fields of `TokenTree` is `Send` and `Sync`. +// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`. #[cfg(parallel_compiler)] fn _dummy() where - Token: Send + Sync, - DelimSpan: Send + Sync, - Delimiter: Send + Sync, - TokenStream: Send + Sync, + Token: sync::DynSend + sync::DynSync, + Spacing: sync::DynSend + sync::DynSync, + DelimSpan: sync::DynSend + sync::DynSync, + Delimiter: sync::DynSend + sync::DynSync, + TokenStream: sync::DynSend + sync::DynSync, { } @@ -118,7 +119,7 @@ where } } -pub trait ToAttrTokenStream: sync::Send + sync::Sync { +pub trait ToAttrTokenStream: sync::DynSend + sync::DynSync { fn to_attr_token_stream(&self) -> AttrTokenStream; } @@ -550,6 +551,10 @@ impl TokenStream { vec_mut.extend(stream_iter); } } + + pub fn chunks(&self, chunk_size: usize) -> core::slice::Chunks<'_, TokenTree> { + self.0.chunks(chunk_size) + } } /// By-reference iterator over a [`TokenStream`], that produces `&TokenTree` diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 315303b25fe..eb25d454339 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -35,7 +35,7 @@ use rustc_middle::mir::{ use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; use rustc_middle::mir::{ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt}; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 58c972738c4..8f64e332861 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -63,7 +63,8 @@ pub fn expand_env<'cx>( Some(exprs) => exprs.into_iter(), }; - let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else { + let var_expr = exprs.next().unwrap(); + let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else { return DummyResult::any(sp); }; @@ -71,7 +72,7 @@ pub fn expand_env<'cx>( None => None, Some(second) => match expr_to_string(cx, second, "expected string literal") { None => return DummyResult::any(sp), - Some((s, _style)) => Some(s), + Some((s, _)) => Some(s), }, }; @@ -80,10 +81,15 @@ pub fn expand_env<'cx>( cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value)); let e = match value { None => { + // Use the string literal in the code in the diagnostic to avoid confusing diagnostics, + // e.g. when the literal contains escape sequences. + let ast::ExprKind::Lit(ast::token::Lit { kind: ast::token::LitKind::Str, symbol: original_var, ..}) = &var_expr.kind else { + unreachable!("`expr_to_string` ensures this is a string lit") + }; cx.emit_err(errors::EnvNotDefined { span: sp, msg: custom_msg, - var, + var: *original_var, help: custom_msg.is_none().then(|| help_for_missing_env_var(var.as_str())), }); return DummyResult::any(sp); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 1cabb05de97..442ce0ea542 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -80,8 +80,8 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMes use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_middle::ty::query::Providers; use rustc_session::config::{Lto, OptLevel, OutputFilenames}; use rustc_session::Session; use rustc_span::Symbol; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8305a0a4c28..6a86237d79e 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -37,7 +37,7 @@ use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, Subd use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest}; use rustc_session::Session; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 2fbdab9f8ce..994addf12eb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -155,12 +155,6 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2] ("x86", "rdrand") => smallvec!["rdrnd"], ("x86", "bmi1") => smallvec!["bmi"], ("x86", "cmpxchg16b") => smallvec!["cx16"], - // FIXME: These aliases are misleading, and should be removed before avx512_target_feature is - // stabilized. They must remain until std::arch switches off them. - // rust#100752 - ("x86", "avx512vaes") => smallvec!["vaes"], - ("x86", "avx512gfni") => smallvec!["gfni"], - ("x86", "avx512vpclmulqdq") => smallvec!["vpclmulqdq"], ("aarch64", "rcpc2") => smallvec!["rcpc-immo"], ("aarch64", "dpb") => smallvec!["ccpp"], ("aarch64", "dpb2") => smallvec!["ccdp"], diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 8f2f829c17c..14460efc1b0 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -11,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, }; use rustc_middle::query::LocalCrate; -use rustc_middle::ty::query::{ExternProviders, Providers}; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; use rustc_middle::ty::{self, SymbolName, TyCtxt}; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index ae45ae9d802..d9b0a152594 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -17,10 +17,7 @@ use rustc_ast::expand::allocator::AllocatorKind; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; - -use rustc_data_structures::sync::par_iter; -#[cfg(parallel_compiler)] -use rustc_data_structures::sync::ParallelIterator; +use rustc_data_structures::sync::par_map; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; @@ -30,8 +27,8 @@ use rustc_middle::middle::exported_symbols; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::middle::lang_items; use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem}; +use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; @@ -689,7 +686,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>( // This likely is a temporary measure. Once we don't have to support the // non-parallel compiler anymore, we can compile CGUs end-to-end in // parallel and get rid of the complicated scheduling logic. - let mut pre_compiled_cgus = if cfg!(parallel_compiler) { + let mut pre_compiled_cgus = if tcx.sess.threads() > 1 { tcx.sess.time("compile_first_CGU_batch", || { // Try to find one CGU to compile per thread. let cgus: Vec<_> = cgu_reuse @@ -702,12 +699,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>( // Compile the found CGUs in parallel. let start_time = Instant::now(); - let pre_compiled_cgus = par_iter(cgus) - .map(|(i, _)| { - let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); - (i, module) - }) - .collect(); + let pre_compiled_cgus = par_map(cgus, |(i, _)| { + let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); + (i, module) + }); total_codegen_time += start_time.elapsed(); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8dae5dab429..d6c23012762 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem}; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::{lint, parse::feature_err}; use rustc_span::symbol::Ident; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c3cc17c255b..f4b9d1dea58 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -30,7 +30,7 @@ use rustc_hir::def_id::CrateNum; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; -use rustc_middle::ty::query::{ExternProviders, Providers}; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_serialize::opaque::{FileEncoder, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 4e5e2dd5d50..bba2800fb05 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; -use rustc_target::abi::{Abi, FieldIdx, Size, VariantIdx}; +use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; @@ -41,6 +41,9 @@ pub struct PerLocalVarDebugInfo<'tcx, D> { /// `.place.projection` from `mir::VarDebugInfo`. pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>, + + /// `references` from `mir::VarDebugInfo`. + pub references: u8, } #[derive(Clone, Copy, Debug)] @@ -80,6 +83,7 @@ trait DebugInfoOffsetLocation<'tcx, Bx> { fn deref(&self, bx: &mut Bx) -> Self; fn layout(&self) -> TyAndLayout<'tcx>; fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self; + fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self; fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self; } @@ -98,6 +102,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> PlaceRef::project_field(*self, bx, field.index()) } + fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self { + let lloffset = bx.cx().const_usize(offset); + self.project_index(bx, lloffset) + } + fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { self.project_downcast(bx, variant) } @@ -120,6 +129,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> self.field(bx.cx(), field.index()) } + fn project_constant_index(&self, bx: &mut Bx, index: u64) -> Self { + self.field(bx.cx(), index as usize) + } + fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self { self.for_variant(bx.cx(), variant) } @@ -165,6 +178,18 @@ fn calculate_debuginfo_offset< mir::ProjectionElem::Downcast(_, variant) => { place = place.downcast(bx, variant); } + mir::ProjectionElem::ConstantIndex { + offset: index, + min_length: _, + from_end: false, + } => { + let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); + let FieldsShape::Array { stride, count: _ } = place.layout().fields else { + span_bug!(var.source_info.span, "ConstantIndex on non-array type {:?}", place.layout()) + }; + *offset += stride * index; + place = place.project_constant_index(bx, index); + } _ => { // Sanity check for `can_use_in_debuginfo`. debug_assert!(!elem.can_use_in_debuginfo()); @@ -293,6 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dbg_var, fragment: None, projection: ty::List::empty(), + references: 0, }) } } else { @@ -358,55 +384,74 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let vars = vars.iter().cloned().chain(fallback_var); for var in vars { - let Some(dbg_var) = var.dbg_var else { continue }; - let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; - - let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = - calculate_debuginfo_offset(bx, local, &var, base.layout); - - // When targeting MSVC, create extra allocas for arguments instead of pointing multiple - // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records - // not DWARF and LLVM doesn't support translating the resulting - // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView. - // Creating extra allocas on the stack makes the resulting debug info simple enough - // that LLVM can generate correct CodeView records and thus the values appear in the - // debugger. (#83709) - let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc - && self.mir.local_kind(local) == mir::LocalKind::Arg - // LLVM can handle simple things but anything more complex than just a direct - // offset or one indirect offset of 0 is too complex for it to generate CV records - // correctly. - && (direct_offset != Size::ZERO - || !matches!(&indirect_offsets[..], [Size::ZERO] | [])); - - if should_create_individual_allocas { - let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } = - calculate_debuginfo_offset(bx, local, &var, base); - - // Create a variable which will be a pointer to the actual value - let ptr_ty = bx - .tcx() - .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty }); - let ptr_layout = bx.layout_of(ptr_ty); - let alloca = PlaceRef::alloca(bx, ptr_layout); - bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill")); - - // Write the pointer to the variable - bx.store(place.llval, alloca.llval, alloca.align); - - // Point the debug info to `*alloca` for the current variable - bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None); - } else { - bx.dbg_var_addr( - dbg_var, - dbg_loc, - base.llval, - direct_offset, - &indirect_offsets, - None, - ); + self.debug_introduce_local_as_var(bx, local, base, var); + } + } + + fn debug_introduce_local_as_var( + &self, + bx: &mut Bx, + local: mir::Local, + mut base: PlaceRef<'tcx, Bx::Value>, + var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>, + ) { + let Some(dbg_var) = var.dbg_var else { return }; + let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return }; + + let DebugInfoOffset { mut direct_offset, indirect_offsets, result: _ } = + calculate_debuginfo_offset(bx, local, &var, base.layout); + let mut indirect_offsets = &indirect_offsets[..]; + + // When targeting MSVC, create extra allocas for arguments instead of pointing multiple + // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records + // not DWARF and LLVM doesn't support translating the resulting + // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView. + // Creating extra allocas on the stack makes the resulting debug info simple enough + // that LLVM can generate correct CodeView records and thus the values appear in the + // debugger. (#83709) + let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc + && self.mir.local_kind(local) == mir::LocalKind::Arg + // LLVM can handle simple things but anything more complex than just a direct + // offset or one indirect offset of 0 is too complex for it to generate CV records + // correctly. + && (direct_offset != Size::ZERO || !matches!(indirect_offsets, [Size::ZERO] | [])); + + let create_alloca = |bx: &mut Bx, place: PlaceRef<'tcx, Bx::Value>, refcount| { + // Create a variable which will be a pointer to the actual value + let ptr_ty = bx + .tcx() + .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty }); + let ptr_layout = bx.layout_of(ptr_ty); + let alloca = PlaceRef::alloca(bx, ptr_layout); + bx.set_var_name(alloca.llval, &format!("{}.ref{}.dbg.spill", var.name, refcount)); + + // Write the pointer to the variable + bx.store(place.llval, alloca.llval, alloca.align); + + // Point the debug info to `*alloca` for the current variable + alloca + }; + + if var.references > 0 { + base = calculate_debuginfo_offset(bx, local, &var, base).result; + + // Point the debug info to `&...&base == alloca` for the current variable + for refcount in 0..var.references { + base = create_alloca(bx, base, refcount); } + + direct_offset = Size::ZERO; + indirect_offsets = &[]; + } else if should_create_individual_allocas { + let place = calculate_debuginfo_offset(bx, local, &var, base).result; + + // Point the debug info to `*alloca` for the current variable + base = create_alloca(bx, place, 0); + direct_offset = Size::ZERO; + indirect_offsets = &[Size::ZERO]; } + + bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, indirect_offsets, None); } pub fn debug_introduce_locals(&self, bx: &mut Bx) { @@ -439,7 +484,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| { - let (var_ty, var_kind) = match var.value { + let (mut var_ty, var_kind) = match var.value { mir::VarDebugInfoContents::Place(place) => { let var_ty = self.monomorphized_place_ty(place.as_ref()); let var_kind = if let Some(arg_index) = var.argument_index @@ -476,6 +521,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; + for _ in 0..var.references { + var_ty = + bx.tcx().mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: var_ty }); + } + self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span) }); @@ -487,6 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { dbg_var, fragment: None, projection: place.projection, + references: var.references, }); } mir::VarDebugInfoContents::Const(c) => { @@ -540,6 +591,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(fragment_start..fragment_start + fragment_layout.size) }, projection: place.projection, + references: var.references, }); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 9efbb34b515..2301c3ef13e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -402,8 +402,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { indirect_dest: PlaceRef<'tcx, V>, ) { debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest); - let flags = MemFlags::empty(); - // `indirect_dest` must have `*mut T` type. We extract `T` out of it. let unsized_ty = indirect_dest .layout @@ -416,17 +414,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { bug!("store_unsized called with a sized value") }; - // FIXME: choose an appropriate alignment, or use dynamic align somehow - let max_align = Align::from_bits(128).unwrap(); - let min_align = Align::from_bits(8).unwrap(); - - // Allocate an appropriate region on the stack, and copy the value into it - let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); - let lldst = bx.byte_array_alloca(llsize, max_align); - bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags); + // Allocate an appropriate region on the stack, and copy the value into it. Since alloca + // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the + // pointer manually. + let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); + let one = bx.const_usize(1); + let align_minus_1 = bx.sub(align, one); + let size_extra = bx.add(size, align_minus_1); + let min_align = Align::ONE; + let alloca = bx.byte_array_alloca(size_extra, min_align); + let address = bx.ptrtoint(alloca, bx.type_isize()); + let neg_address = bx.neg(address); + let offset = bx.and(neg_address, align_minus_1); + let dst = bx.inbounds_gep(bx.type_i8(), alloca, &[offset]); + bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty()); // Store the allocated region and the extra to the indirect place. - let indirect_operand = OperandValue::Pair(lldst, llextra); + let indirect_operand = OperandValue::Pair(dst, llextra); indirect_operand.store(bx, indirect_dest); } } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 1cfc4b933a8..3719283cccc 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; use rustc_session::Session; @@ -173,16 +173,13 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[ ("avx512dq", Some(sym::avx512_target_feature)), ("avx512er", Some(sym::avx512_target_feature)), ("avx512f", Some(sym::avx512_target_feature)), - ("avx512gfni", Some(sym::avx512_target_feature)), ("avx512ifma", Some(sym::avx512_target_feature)), ("avx512pf", Some(sym::avx512_target_feature)), - ("avx512vaes", Some(sym::avx512_target_feature)), ("avx512vbmi", Some(sym::avx512_target_feature)), ("avx512vbmi2", Some(sym::avx512_target_feature)), ("avx512vl", Some(sym::avx512_target_feature)), ("avx512vnni", Some(sym::avx512_target_feature)), ("avx512vp2intersect", Some(sym::avx512_target_feature)), - ("avx512vpclmulqdq", Some(sym::avx512_target_feature)), ("avx512vpopcntdq", Some(sym::avx512_target_feature)), ("bmi1", None), ("bmi2", None), diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 64bebe50ddb..5c88368bc87 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -8,8 +8,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout}; -use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_session::{ config::{self, OutputFilenames, PrintRequest}, @@ -22,6 +22,7 @@ use rustc_target::spec::Target; pub use rustc_data_structures::sync::MetadataRef; +use rustc_data_structures::sync::{DynSend, DynSync}; use std::any::Any; pub trait BackendTypes { @@ -117,7 +118,9 @@ pub trait CodegenBackend { ) -> Result<(), ErrorGuaranteed>; } -pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync { +pub trait ExtraBackendMethods: + CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync +{ fn codegen_allocator<'tcx>( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index cdef3fb2339..5037c210e7d 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -169,14 +169,14 @@ impl<'tcx> ConstEvalErr<'tcx> { // See <https://github.com/rust-lang/rust/pull/63152>. let mut err = struct_error(tcx, &self.error.to_string()); self.decorate(&mut err, decorate); - ErrorHandled::Reported(err.emit()) + ErrorHandled::Reported(err.emit().into()) } _ => { // Report as hard error. let mut err = struct_error(tcx, message); err.span_label(self.span, self.error.to_string()); self.decorate(&mut err, decorate); - ErrorHandled::Reported(err.emit()) + ErrorHandled::Reported(err.emit().into()) } } } diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 088a824fd8f..fa8253d5e49 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -2,7 +2,7 @@ use rustc_attr as attr; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 814b67b46ec..58b5755af07 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -382,7 +382,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", ); - throw_inval!(AlreadyReported(guar)); + throw_inval!(AlreadyReported(guar.into())); } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, // so this should be unreachable. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index b2197a0aabb..2fa63dc8c93 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,7 @@ use either::{Either, Left, Right}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::IndexVec; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ErrorHandled, InterpError}; +use rustc_middle::mir::interpret::{ErrorHandled, InterpError, ReportedErrorInfo}; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -470,7 +470,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // do not continue if typeck errors occurred (can only occur in local crate) if let Some(err) = body.tainted_by_errors { - throw_inval!(AlreadyReported(err)); + throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err))); } Ok(body) } @@ -517,7 +517,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(None) => throw_inval!(TooGeneric), // FIXME(eddyb) this could be a bit more specific than `AlreadyReported`. - Err(error_reported) => throw_inval!(AlreadyReported(error_reported)), + Err(error_reported) => throw_inval!(AlreadyReported(error_reported.into())), } } @@ -905,7 +905,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| { match err { ErrorHandled::Reported(err) => { - if let Some(span) = span { + if !err.is_tainted_by_errors() && let Some(span) = span { // To make it easier to figure out where this error comes from, also add a note at the current location. self.tcx.sess.span_note_without_error(span, "erroneous constant used"); } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index a7f66071fe2..e30af165501 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -595,7 +595,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated ty::ConstKind::Expr(_) => throw_inval!(TooGeneric), ty::ConstKind::Error(reported) => { - throw_inval!(AlreadyReported(reported)) + throw_inval!(AlreadyReported(reported.into())) } ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 1b66eca97a5..c36282d5ed4 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -35,8 +35,8 @@ pub mod util; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; +use rustc_middle::query::Providers; use rustc_middle::ty; -use rustc_middle::ty::query::Providers; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index f46c2d00fe4..3c350e25ba6 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(root) = post_contract_node.get(&bb) { break *root; } - let parent = doms.immediate_dominator(bb); + let parent = doms.immediate_dominator(bb).unwrap(); dom_path.push(bb); if !self.body.basic_blocks[parent].is_cleanup { break bb; @@ -448,7 +448,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }; match debuginfo.value { VarDebugInfoContents::Const(_) => {} - VarDebugInfoContents::Place(place) => check_place(place), + VarDebugInfoContents::Place(place) => { + check_place(place); + if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) { + self.fail( + START_BLOCK.start_location(), + format!("debuginfo {:?}, has both ref and deref", debuginfo), + ); + } + } VarDebugInfoContents::Composite { ty, ref fragments } => { for f in fragments { check_place(f.contents); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index c815bb2d197..78f73d193e3 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -16,6 +16,7 @@ libc = "0.2" measureme = "10.0.0" rustc-rayon-core = { version = "0.5.0", optional = true } rustc-rayon = { version = "0.5.0", optional = true } +rustc_arena = { path = "../rustc_arena" } rustc_graphviz = { path = "../rustc_graphviz" } rustc-hash = "1.1.0" rustc_index = { path = "../rustc_index", package = "rustc_index" } diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index e76bdac2864..a7de709ba72 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -242,7 +242,9 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> { immediate_dominators[*node] = Some(pre_order_to_real[idom[idx]]); } - Dominators { post_order_rank, immediate_dominators } + let start_node = graph.start_node(); + immediate_dominators[start_node] = None; + Dominators { start_node, post_order_rank, immediate_dominators } } /// Evaluate the link-eval virtual forest, providing the currently minimum semi @@ -308,6 +310,7 @@ fn compress( /// Tracks the list of dominators for each node. #[derive(Clone, Debug)] pub struct Dominators<N: Idx> { + start_node: N, post_order_rank: IndexVec<N, usize>, // Even though we track only the immediate dominator of each node, it's // possible to get its full list of dominators by looking up the dominator @@ -316,14 +319,14 @@ pub struct Dominators<N: Idx> { } impl<Node: Idx> Dominators<Node> { - /// Whether the given Node has an immediate dominator. + /// Returns true if node is reachable from the start node. pub fn is_reachable(&self, node: Node) -> bool { - self.immediate_dominators[node].is_some() + node == self.start_node || self.immediate_dominators[node].is_some() } - pub fn immediate_dominator(&self, node: Node) -> Node { - assert!(self.is_reachable(node), "node {node:?} is not reachable"); - self.immediate_dominators[node].unwrap() + /// Returns the immediate dominator of node, if any. + pub fn immediate_dominator(&self, node: Node) -> Option<Node> { + self.immediate_dominators[node] } /// Provides an iterator over each dominator up the CFG, for the given Node. @@ -357,12 +360,7 @@ impl<'dom, Node: Idx> Iterator for Iter<'dom, Node> { fn next(&mut self) -> Option<Self::Item> { if let Some(node) = self.node { - let dom = self.dominators.immediate_dominator(node); - if dom == node { - self.node = None; // reached the root - } else { - self.node = Some(dom); - } + self.node = self.dominators.immediate_dominator(node); Some(node) } else { None diff --git a/compiler/rustc_data_structures/src/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs index ff31d8f7fdc..8b124516623 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/tests.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs @@ -8,7 +8,7 @@ fn diamond() { let dominators = dominators(&graph); let immediate_dominators = &dominators.immediate_dominators; - assert_eq!(immediate_dominators[0], Some(0)); + assert_eq!(immediate_dominators[0], None); assert_eq!(immediate_dominators[1], Some(0)); assert_eq!(immediate_dominators[2], Some(0)); assert_eq!(immediate_dominators[3], Some(0)); @@ -30,7 +30,7 @@ fn paper() { assert_eq!(immediate_dominators[3], Some(6)); assert_eq!(immediate_dominators[4], Some(6)); assert_eq!(immediate_dominators[5], Some(6)); - assert_eq!(immediate_dominators[6], Some(6)); + assert_eq!(immediate_dominators[6], None); } #[test] @@ -43,3 +43,13 @@ fn paper_slt() { dominators(&graph); } + +#[test] +fn immediate_dominator() { + let graph = TestGraph::new(1, &[(1, 2), (2, 3)]); + let dominators = dominators(&graph); + assert_eq!(dominators.immediate_dominator(0), None); + assert_eq!(dominators.immediate_dominator(1), None); + assert_eq!(dominators.immediate_dominator(2), Some(1)); + assert_eq!(dominators.immediate_dominator(3), Some(2)); +} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 004017ec5f3..5b9b0e106d2 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -26,6 +26,7 @@ #![feature(test)] #![feature(thread_id_value)] #![feature(vec_into_raw_parts)] +#![feature(allocator_api)] #![feature(get_mut_unchecked)] #![feature(lint_reasons)] #![feature(unwrap_infallible)] @@ -77,6 +78,7 @@ pub mod sorted_map; pub mod stable_hasher; mod atomic_ref; pub mod fingerprint; +pub mod marker; pub mod profiling; pub mod sharded; pub mod stack; diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs new file mode 100644 index 00000000000..f8c06f9a814 --- /dev/null +++ b/compiler/rustc_data_structures/src/marker.rs @@ -0,0 +1,257 @@ +cfg_if!( + if #[cfg(not(parallel_compiler))] { + pub auto trait DynSend {} + pub auto trait DynSync {} + + impl<T> DynSend for T {} + impl<T> DynSync for T {} + } else { + #[rustc_on_unimplemented( + message = "`{Self}` doesn't implement `DynSend`. \ + Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`" + )] + // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()` + // is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a + // `Send` type in `IntoDynSyncSend` will create a `DynSend` type. + pub unsafe auto trait DynSend {} + + #[rustc_on_unimplemented( + message = "`{Self}` doesn't implement `DynSync`. \ + Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`" + )] + // This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()` + // is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a + // `Sync` type in `IntoDynSyncSend` will create a `DynSync` type. + pub unsafe auto trait DynSync {} + + // Same with `Sync` and `Send`. + unsafe impl<T: DynSync + ?Sized> DynSend for &T {} + + macro_rules! impls_dyn_send_neg { + ($([$t1: ty $(where $($generics1: tt)*)?])*) => { + $(impl$(<$($generics1)*>)? !DynSend for $t1 {})* + }; + } + + // Consistent with `std` + impls_dyn_send_neg!( + [std::env::Args] + [std::env::ArgsOs] + [*const T where T: ?Sized] + [*mut T where T: ?Sized] + [std::ptr::NonNull<T> where T: ?Sized] + [std::rc::Rc<T> where T: ?Sized] + [std::rc::Weak<T> where T: ?Sized] + [std::sync::MutexGuard<'_, T> where T: ?Sized] + [std::sync::RwLockReadGuard<'_, T> where T: ?Sized] + [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized] + [std::io::StdoutLock<'_>] + [std::io::StderrLock<'_>] + ); + cfg_if!( + // Consistent with `std` + // `os_imp::Env` is `!Send` in these platforms + if #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))] { + impl !DynSend for std::env::VarsOs {} + } + ); + + macro_rules! already_send { + ($([$ty: ty])*) => { + $(unsafe impl DynSend for $ty where $ty: Send {})* + }; + } + + // These structures are already `Send`. + already_send!( + [std::backtrace::Backtrace] + [std::io::Stdout] + [std::io::Stderr] + [std::io::Error] + [std::fs::File] + [rustc_arena::DroplessArena] + [crate::memmap::Mmap] + [crate::profiling::SelfProfiler] + [crate::owned_slice::OwnedSlice] + ); + + macro_rules! impl_dyn_send { + ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => { + $(unsafe impl<$($generics2)*> DynSend for $ty {})* + }; + } + + impl_dyn_send!( + [std::sync::atomic::AtomicPtr<T> where T] + [std::sync::Mutex<T> where T: ?Sized+ DynSend] + [std::sync::mpsc::Sender<T> where T: DynSend] + [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend] + [std::sync::LazyLock<T, F> where T: DynSend, F: DynSend] + [std::collections::HashSet<K, S> where K: DynSend, S: DynSend] + [std::collections::HashMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend] + [std::collections::BTreeMap<K, V, A> where K: DynSend, V: DynSend, A: std::alloc::Allocator + Clone + DynSend] + [Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend] + [Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend] + [crate::sync::Lock<T> where T: DynSend] + [crate::sync::RwLock<T> where T: DynSend] + [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool] + [rustc_arena::TypedArena<T> where T: DynSend] + [indexmap::IndexSet<V, S> where V: DynSend, S: DynSend] + [indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend] + [thin_vec::ThinVec<T> where T: DynSend] + [smallvec::SmallVec<A> where A: smallvec::Array + DynSend] + ); + + macro_rules! impls_dyn_sync_neg { + ($([$t1: ty $(where $($generics1: tt)*)?])*) => { + $(impl$(<$($generics1)*>)? !DynSync for $t1 {})* + }; + } + + // Consistent with `std` + impls_dyn_sync_neg!( + [std::env::Args] + [std::env::ArgsOs] + [*const T where T: ?Sized] + [*mut T where T: ?Sized] + [std::cell::Cell<T> where T: ?Sized] + [std::cell::RefCell<T> where T: ?Sized] + [std::cell::UnsafeCell<T> where T: ?Sized] + [std::ptr::NonNull<T> where T: ?Sized] + [std::rc::Rc<T> where T: ?Sized] + [std::rc::Weak<T> where T: ?Sized] + [std::cell::OnceCell<T> where T] + [std::sync::mpsc::Receiver<T> where T] + [std::sync::mpsc::Sender<T> where T] + ); + cfg_if!( + // Consistent with `std` + // `os_imp::Env` is `!Sync` in these platforms + if #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))] { + impl !DynSync for std::env::VarsOs {} + } + ); + + macro_rules! already_sync { + ($([$ty: ty])*) => { + $(unsafe impl DynSync for $ty where $ty: Sync {})* + }; + } + + // These structures are already `Sync`. + already_sync!( + [std::sync::atomic::AtomicBool] + [std::sync::atomic::AtomicUsize] + [std::sync::atomic::AtomicU8] + [std::sync::atomic::AtomicU32] + [std::sync::atomic::AtomicU64] + [std::backtrace::Backtrace] + [std::io::Error] + [std::fs::File] + [jobserver_crate::Client] + [crate::memmap::Mmap] + [crate::profiling::SelfProfiler] + [crate::owned_slice::OwnedSlice] + ); + + macro_rules! impl_dyn_sync { + ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => { + $(unsafe impl<$($generics2)*> DynSync for $ty {})* + }; + } + + impl_dyn_sync!( + [std::sync::atomic::AtomicPtr<T> where T] + [std::sync::OnceLock<T> where T: DynSend + DynSync] + [std::sync::Mutex<T> where T: ?Sized + DynSend] + [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend] + [std::sync::LazyLock<T, F> where T: DynSend + DynSync, F: DynSend] + [std::collections::HashSet<K, S> where K: DynSync, S: DynSync] + [std::collections::HashMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync] + [std::collections::BTreeMap<K, V, A> where K: DynSync, V: DynSync, A: std::alloc::Allocator + Clone + DynSync] + [Vec<T, A> where T: DynSync, A: std::alloc::Allocator + DynSync] + [Box<T, A> where T: ?Sized + DynSync, A: std::alloc::Allocator + DynSync] + [crate::sync::Lock<T> where T: DynSend] + [crate::sync::RwLock<T> where T: DynSend + DynSync] + [crate::sync::OneThread<T> where T] + [crate::sync::WorkerLocal<T> where T: DynSend] + [crate::intern::Interned<'a, T> where 'a, T: DynSync] + [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool] + [parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend] + [parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync] + [indexmap::IndexSet<V, S> where V: DynSync, S: DynSync] + [indexmap::IndexMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync] + [smallvec::SmallVec<A> where A: smallvec::Array + DynSync] + [thin_vec::ThinVec<T> where T: DynSync] + ); + } +); + +pub fn assert_dyn_sync<T: ?Sized + DynSync>() {} +pub fn assert_dyn_send<T: ?Sized + DynSend>() {} +pub fn assert_dyn_send_val<T: ?Sized + DynSend>(_t: &T) {} +pub fn assert_dyn_send_sync_val<T: ?Sized + DynSync + DynSend>(_t: &T) {} + +#[derive(Copy, Clone)] +pub struct FromDyn<T>(T); + +impl<T> FromDyn<T> { + #[inline(always)] + pub fn from(val: T) -> Self { + // Check that `sync::is_dyn_thread_safe()` is true on creation so we can + // implement `Send` and `Sync` for this structure when `T` + // implements `DynSend` and `DynSync` respectively. + #[cfg(parallel_compiler)] + assert!(crate::sync::is_dyn_thread_safe()); + FromDyn(val) + } + + #[inline(always)] + pub fn into_inner(self) -> T { + self.0 + } +} + +// `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::is_dyn_thread_safe() is true. +#[cfg(parallel_compiler)] +unsafe impl<T: DynSend> Send for FromDyn<T> {} + +// `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::is_dyn_thread_safe() is true. +#[cfg(parallel_compiler)] +unsafe impl<T: DynSync> Sync for FromDyn<T> {} + +impl<T> std::ops::Deref for FromDyn<T> { + type Target = T; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// A wrapper to convert a struct that is already a `Send` or `Sync` into +// an instance of `DynSend` and `DynSync`, since the compiler cannot infer +// it automatically in some cases. (e.g. Box<dyn Send / Sync>) +#[derive(Copy, Clone)] +pub struct IntoDynSyncSend<T: ?Sized>(pub T); + +#[cfg(parallel_compiler)] +unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {} +#[cfg(parallel_compiler)] +unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {} + +impl<T> std::ops::Deref for IntoDynSyncSend<T> { + type Target = T; + + #[inline(always)] + fn deref(&self) -> &T { + &self.0 + } +} + +impl<T> std::ops::DerefMut for IntoDynSyncSend<T> { + #[inline(always)] + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} diff --git a/compiler/rustc_data_structures/src/owned_slice/tests.rs b/compiler/rustc_data_structures/src/owned_slice/tests.rs index e715fb55362..e151b8c2de0 100644 --- a/compiler/rustc_data_structures/src/owned_slice/tests.rs +++ b/compiler/rustc_data_structures/src/owned_slice/tests.rs @@ -69,6 +69,6 @@ fn drop_drops() { #[test] fn send_sync() { - crate::sync::assert_send::<OwnedSlice>(); - crate::sync::assert_sync::<OwnedSlice>(); + crate::sync::assert_dyn_send::<OwnedSlice>(); + crate::sync::assert_dyn_sync::<OwnedSlice>(); } diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index e73ca56efa0..8a778866a77 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -39,6 +39,7 @@ //! //! [^2] `MTLockRef` is a typedef. +pub use crate::marker::*; use crate::owned_slice::OwnedSlice; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; @@ -55,6 +56,42 @@ pub use vec::{AppendOnlyIndexVec, AppendOnlyVec}; mod vec; +mod mode { + use super::Ordering; + use std::sync::atomic::AtomicU8; + + const UNINITIALIZED: u8 = 0; + const DYN_NOT_THREAD_SAFE: u8 = 1; + const DYN_THREAD_SAFE: u8 = 2; + + static DYN_THREAD_SAFE_MODE: AtomicU8 = AtomicU8::new(UNINITIALIZED); + + // Whether thread safety is enabled (due to running under multiple threads). + #[inline] + pub fn is_dyn_thread_safe() -> bool { + match DYN_THREAD_SAFE_MODE.load(Ordering::Relaxed) { + DYN_NOT_THREAD_SAFE => false, + DYN_THREAD_SAFE => true, + _ => panic!("uninitialized dyn_thread_safe mode!"), + } + } + + // Only set by the `-Z threads` compile option + pub fn set_dyn_thread_safe_mode(mode: bool) { + let set: u8 = if mode { DYN_THREAD_SAFE } else { DYN_NOT_THREAD_SAFE }; + let previous = DYN_THREAD_SAFE_MODE.compare_exchange( + UNINITIALIZED, + set, + Ordering::Relaxed, + Ordering::Relaxed, + ); + + // Check that the mode was either uninitialized or was already set to the requested mode. + assert!(previous.is_ok() || previous == Err(set)); + } +} + +pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; cfg_if! { if #[cfg(not(parallel_compiler))] { pub unsafe auto trait Send {} @@ -149,7 +186,7 @@ cfg_if! { #[macro_export] macro_rules! parallel { - ($($blocks:tt),*) => { + ($($blocks:block),*) => { // We catch panics here ensuring that all the blocks execute. // This makes behavior consistent with the parallel compiler. let mut panic = None; @@ -168,12 +205,6 @@ cfg_if! { } } - pub use Iterator as ParallelIterator; - - pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter { - t.into_iter() - } - pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item) + Sync + Send) { // We catch panics here ensuring that all the loop iterations execute. // This makes behavior consistent with the parallel compiler. @@ -190,6 +221,29 @@ cfg_if! { } } + pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>( + t: T, + mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R, + ) -> C { + // We catch panics here ensuring that all the loop iterations execute. + let mut panic = None; + let r = t.into_iter().filter_map(|i| { + match catch_unwind(AssertUnwindSafe(|| map(i))) { + Ok(r) => Some(r), + Err(p) => { + if panic.is_none() { + panic = Some(p); + } + None + } + } + }).collect(); + if let Some(panic) = panic { + resume_unwind(panic); + } + r + } + pub type MetadataRef = OwnedSlice; pub use std::rc::Rc as Lrc; @@ -302,46 +356,165 @@ cfg_if! { use parking_lot::RwLock as InnerRwLock; use std::thread; - pub use rayon::{join, scope}; + + #[inline] + pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB) + where + A: FnOnce() -> RA + DynSend, + B: FnOnce() -> RB + DynSend, + { + if mode::is_dyn_thread_safe() { + let oper_a = FromDyn::from(oper_a); + let oper_b = FromDyn::from(oper_b); + let (a, b) = rayon::join(move || FromDyn::from(oper_a.into_inner()()), move || FromDyn::from(oper_b.into_inner()())); + (a.into_inner(), b.into_inner()) + } else { + (oper_a(), oper_b()) + } + } + + // This function only works when `mode::is_dyn_thread_safe()`. + pub fn scope<'scope, OP, R>(op: OP) -> R + where + OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend, + R: DynSend, + { + let op = FromDyn::from(op); + rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner() + } /// Runs a list of blocks in parallel. The first block is executed immediately on /// the current thread. Use that for the longest running block. #[macro_export] macro_rules! parallel { - (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { + (impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => { parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) }; - (impl $fblock:tt [$($blocks:tt,)*] []) => { + (impl $fblock:block [$($blocks:expr,)*] []) => { ::rustc_data_structures::sync::scope(|s| { + $(let block = rustc_data_structures::sync::FromDyn::from(|| $blocks); + s.spawn(move |_| block.into_inner()());)* + (|| $fblock)(); + }); + }; + ($fblock:block, $($blocks:block),*) => { + if rustc_data_structures::sync::is_dyn_thread_safe() { + // Reverse the order of the later blocks since Rayon executes them in reverse order + // when using a single thread. This ensures the execution order matches that + // of a single threaded rustc. + parallel!(impl $fblock [] [$($blocks),*]); + } else { + // We catch panics here ensuring that all the blocks execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + if let Err(p) = ::std::panic::catch_unwind( + ::std::panic::AssertUnwindSafe(|| $fblock) + ) { + if panic.is_none() { + panic = Some(p); + } + } $( - s.spawn(|_| $blocks); + if let Err(p) = ::std::panic::catch_unwind( + ::std::panic::AssertUnwindSafe(|| $blocks) + ) { + if panic.is_none() { + panic = Some(p); + } + } )* - $fblock; - }) - }; - ($fblock:tt, $($blocks:tt),*) => { - // Reverse the order of the later blocks since Rayon executes them in reverse order - // when using a single thread. This ensures the execution order matches that - // of a single threaded rustc - parallel!(impl $fblock [] [$($blocks),*]); + if let Some(panic) = panic { + ::std::panic::resume_unwind(panic); + } + } }; } - pub use rayon::iter::ParallelIterator; - use rayon::iter::IntoParallelIterator; + use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator}; + + pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>( + t: T, + for_each: impl Fn(I) + DynSync + DynSend + ) { + if mode::is_dyn_thread_safe() { + let for_each = FromDyn::from(for_each); + let panic: Lock<Option<_>> = Lock::new(None); + t.into_par_iter().for_each(|i| if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { + let mut l = panic.lock(); + if l.is_none() { + *l = Some(p) + } + }); - pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter { - t.into_par_iter() + if let Some(panic) = panic.into_inner() { + resume_unwind(panic); + } + } else { + // We catch panics here ensuring that all the loop iterations execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + t.into_iter().for_each(|i| { + if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { + if panic.is_none() { + panic = Some(p); + } + } + }); + if let Some(panic) = panic { + resume_unwind(panic); + } + } } - pub fn par_for_each_in<T: IntoParallelIterator>( + pub fn par_map< + I, + T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>, + R: std::marker::Send, + C: FromIterator<R> + FromParallelIterator<R> + >( t: T, - for_each: impl Fn(T::Item) + Sync + Send, - ) { - let ps: Vec<_> = t.into_par_iter().map(|i| catch_unwind(AssertUnwindSafe(|| for_each(i)))).collect(); - ps.into_iter().for_each(|p| if let Err(panic) = p { - resume_unwind(panic) - }); + map: impl Fn(I) -> R + DynSync + DynSend + ) -> C { + if mode::is_dyn_thread_safe() { + let panic: Lock<Option<_>> = Lock::new(None); + let map = FromDyn::from(map); + // We catch panics here ensuring that all the loop iterations execute. + let r = t.into_par_iter().filter_map(|i| { + match catch_unwind(AssertUnwindSafe(|| map(i))) { + Ok(r) => Some(r), + Err(p) => { + let mut l = panic.lock(); + if l.is_none() { + *l = Some(p); + } + None + }, + } + }).collect(); + + if let Some(panic) = panic.into_inner() { + resume_unwind(panic); + } + r + } else { + // We catch panics here ensuring that all the loop iterations execute. + let mut panic = None; + let r = t.into_iter().filter_map(|i| { + match catch_unwind(AssertUnwindSafe(|| map(i))) { + Ok(r) => Some(r), + Err(p) => { + if panic.is_none() { + panic = Some(p); + } + None + } + } + }).collect(); + if let Some(panic) = panic { + resume_unwind(panic); + } + r + } } pub type MetadataRef = OwnedSlice; @@ -352,11 +525,6 @@ cfg_if! { } } -pub fn assert_sync<T: ?Sized + Sync>() {} -pub fn assert_send<T: ?Sized + Send>() {} -pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {} -pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {} - #[derive(Default)] #[cfg_attr(parallel_compiler, repr(align(64)))] pub struct CacheAligned<T>(pub T); diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 9b16f246193..80a9dfd251a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -256,6 +256,9 @@ fn run_compiler( let sopts = config::build_session_options(&matches); + // Set parallel mode before thread pool creation, which will create `Lock`s. + interface::set_thread_safe_mode(&sopts.unstable_opts); + if let Some(ref code) = matches.opt_str("explain") { handle_explain(diagnostics_registry(), code, sopts.error_format); return Ok(()); diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6c3f677ab8e..0accb4ab96f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -11,7 +11,7 @@ extern crate tracing; use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_fluent_macro::fluent_messages; use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; @@ -37,16 +37,17 @@ pub use unic_langid::{langid, LanguageIdentifier}; fluent_messages! { "../messages.ftl" } -pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>; +pub type FluentBundle = + IntoDynSyncSend<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>; -#[cfg(parallel_compiler)] +#[cfg(not(parallel_compiler))] fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle { - FluentBundle::new_concurrent(locales) + IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new(locales)) } -#[cfg(not(parallel_compiler))] +#[cfg(parallel_compiler)] fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle { - FluentBundle::new(locales) + IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new_concurrent(locales)) } #[derive(Debug)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fcbd9a53b48..22c41f7b93f 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -32,7 +32,7 @@ use emitter::{is_case_difference, Emitter, EmitterWriter}; use registry::Registry; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; -use rustc_data_structures::sync::{self, Lock, Lrc}; +use rustc_data_structures::sync::{self, IntoDynSyncSend, Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, @@ -409,7 +409,7 @@ struct HandlerInner { err_count: usize, warn_count: usize, deduplicated_err_count: usize, - emitter: Box<dyn Emitter + sync::Send>, + emitter: IntoDynSyncSend<Box<dyn Emitter + sync::Send>>, delayed_span_bugs: Vec<DelayedDiagnostic>, delayed_good_path_bugs: Vec<DelayedDiagnostic>, /// This flag indicates that an expected diagnostic was emitted and suppressed. @@ -605,7 +605,7 @@ impl Handler { warn_count: 0, deduplicated_err_count: 0, deduplicated_warn_count: 0, - emitter, + emitter: IntoDynSyncSend(emitter), delayed_span_bugs: Vec::new(), delayed_good_path_bugs: Vec::new(), suppressed_expected_diag: false, diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs index 52103e46097..0e729b71680 100644 --- a/compiler/rustc_errors/src/tests.rs +++ b/compiler/rustc_errors/src/tests.rs @@ -2,7 +2,7 @@ use crate::error::{TranslateError, TranslateErrorKind}; use crate::fluent_bundle::*; use crate::translation::Translate; use crate::FluentBundle; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError}; use rustc_error_messages::langid; use rustc_error_messages::DiagnosticMessage; @@ -27,10 +27,14 @@ fn make_dummy(ftl: &'static str) -> Dummy { let langid_en = langid!("en-US"); #[cfg(parallel_compiler)] - let mut bundle = FluentBundle::new_concurrent(vec![langid_en]); + let mut bundle: FluentBundle = + IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![ + langid_en, + ])); #[cfg(not(parallel_compiler))] - let mut bundle = FluentBundle::new(vec![langid_en]); + let mut bundle: FluentBundle = + IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new(vec![langid_en])); bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle."); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c1cca89df8c..e03576c55f4 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -653,13 +653,13 @@ pub enum SyntaxExtensionKind { /// A token-based function-like macro. Bang( /// An expander with signature TokenStream -> TokenStream. - Box<dyn BangProcMacro + sync::Sync + sync::Send>, + Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>, ), /// An AST-based function-like macro. LegacyBang( /// An expander with signature TokenStream -> AST. - Box<dyn TTMacroExpander + sync::Sync + sync::Send>, + Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>, ), /// A token-based attribute macro. @@ -667,7 +667,7 @@ pub enum SyntaxExtensionKind { /// An expander with signature (TokenStream, TokenStream) -> TokenStream. /// The first TokenSteam is the attribute itself, the second is the annotated item. /// The produced TokenSteam replaces the input TokenSteam. - Box<dyn AttrProcMacro + sync::Sync + sync::Send>, + Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>, ), /// An AST-based attribute macro. @@ -675,7 +675,7 @@ pub enum SyntaxExtensionKind { /// An expander with signature (AST, AST) -> AST. /// The first AST fragment is the attribute itself, the second is the annotated item. /// The produced AST fragment replaces the input AST fragment. - Box<dyn MultiItemModifier + sync::Sync + sync::Send>, + Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), /// A trivial attribute "macro" that does nothing, @@ -692,14 +692,14 @@ pub enum SyntaxExtensionKind { /// is handled identically to `LegacyDerive`. It should be migrated to /// a token-based representation like `Bang` and `Attr`, instead of /// using `MultiItemModifier`. - Box<dyn MultiItemModifier + sync::Sync + sync::Send>, + Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), /// An AST-based derive macro. LegacyDerive( /// An expander with signature AST -> AST. /// The produced AST fragment is appended to the input AST fragment. - Box<dyn MultiItemModifier + sync::Sync + sync::Send>, + Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index fe8c630666b..57e55752027 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -338,7 +338,7 @@ declare_features! ( /// Allow conditional compilation depending on rust version (active, cfg_version, "1.45.0", Some(64796), None), /// Allows to use the `#[cfi_encoding = ""]` attribute. - (active, cfi_encoding, "1.69.0", Some(89653), None), + (active, cfi_encoding, "CURRENT_RUSTC_VERSION", Some(89653), None), /// Allows `for<...>` on closures and generators. (active, closure_lifetime_binder, "1.64.0", Some(97362), None), /// Allows `#[track_caller]` on closures and generators. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6ac1df6a079..7e591fd25bf 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -464,7 +464,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.astconv.ct_infer(ty, Some(param), inf.span).into() } else { self.inferred_params.push(inf.span); - tcx.const_error(ty).into() + tcx.const_error_misc(ty).into() } } _ => unreachable!(), @@ -518,7 +518,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .no_bound_vars() .expect("const parameter types cannot be generic"); if let Err(guar) = ty.error_reported() { - return tcx.const_error_with_guaranteed(ty, guar).into(); + return tcx.const_error(ty, guar).into(); } if !infer_args && has_default { tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() @@ -527,7 +527,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.astconv.ct_infer(ty, Some(param), self.span).into() } else { // We've already errored above about the mismatch. - tcx.const_error(ty).into() + tcx.const_error_misc(ty).into() } } } @@ -1387,7 +1387,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { term = match def_kind { hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(), hir::def::DefKind::AssocConst => tcx - .const_error_with_guaranteed( + .const_error( tcx.type_of(assoc_item_def_id) .subst(tcx, projection_ty.skip_binder().substs), reported, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 78ffe59679a..d3495d3dbd7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1514,8 +1514,8 @@ fn opaque_type_cycle_error( } if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = tcx.def_kind(closure_def_id) + && let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id) { - let generator_layout = tcx.mir_generator_witnesses(closure_def_id); for interior_ty in &generator_layout.field_tys { label_match(interior_ty.ty, interior_ty.source_info.span); } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 08154cdae47..3971a4c01d6 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -78,7 +78,7 @@ use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::parse::feature_err; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 862f0a9b0e2..8918553e5f9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -12,7 +12,7 @@ use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs}; use rustc_infer::infer::outlives::obligations::TypeOutlives; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index cd2ec2bef20..4524b87a418 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -8,7 +8,7 @@ use crate::errors; use rustc_errors::{error_code, struct_span_err}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 2f808d4ce73..9f00dc418ee 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -28,7 +28,7 @@ use rustc_hir::{GenericParamKind, Node}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 92ae93cf4cc..794812a5ce7 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -17,6 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_session::lint; use rustc_span::def_id::DefId; @@ -232,8 +233,8 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { type ScopeRef<'a> = &'a Scope<'a>; -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { resolve_bound_vars, named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 8269a6ddea5..e4c6e6e391a 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -4,7 +4,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits::{self, ObligationCtxt}; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index f070b4f9bae..612d4ff3df8 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::{Span, Symbol}; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 3fe34f23aef..5cd2cd50c11 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -104,7 +104,7 @@ use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::middle; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util; use rustc_session::{config::EntryFnType, parse::feature_err}; diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index 42612eed750..a8596c707f3 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -1,7 +1,7 @@ use hir::Node; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; use rustc_span::symbol::sym; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index e735b048d73..3ebd9e134bf 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -6,7 +6,7 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index dcc323493f4..54b222ade03 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -68,8 +68,8 @@ use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::check_abi; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_middle::query::Providers; use rustc_middle::traits; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config; use rustc_session::Session; diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 5963a1632c5..cf9290c1a48 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -18,6 +18,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_infer::infer::{self, InferOk}; +use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; @@ -28,7 +29,7 @@ use rustc_trait_selection::traits::{self, NormalizeExt}; use self::probe::{IsSuggestion, ProbeScope}; -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { probe::provide(providers); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 483e17460b3..f91f4f887c6 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -16,6 +16,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; use rustc_middle::middle::stability; +use rustc_middle::query::Providers; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; @@ -495,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { providers.method_autoderef_steps = method_autoderef_steps; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 486c217707e..550a87e6102 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2633,47 +2633,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Nothing, } let ast_generics = hir.get_generics(id.owner.def_id).unwrap(); - let (sp, mut introducer) = if let Some(span) = - ast_generics.bounds_span_for_suggestions(def_id) - { - (span, Introducer::Plus) - } else if let Some(colon_span) = param.colon_span { - (colon_span.shrink_to_hi(), Introducer::Nothing) - } else { - (param.span.shrink_to_hi(), Introducer::Colon) - }; - if matches!( - param.kind, - hir::GenericParamKind::Type { synthetic: true, .. }, - ) { - introducer = Introducer::Plus - } let trait_def_ids: FxHashSet<DefId> = ast_generics .bounds_for_param(def_id) .flat_map(|bp| bp.bounds.iter()) .filter_map(|bound| bound.trait_ref()?.trait_def_id()) .collect(); - if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { - err.span_suggestions( - sp, - message(format!( - "restrict type parameter `{}` with", - param.name.ident(), - )), + if candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { + return; + } + let msg = message(format!( + "restrict type parameter `{}` with", + param.name.ident(), + )); + let bounds_span = ast_generics.bounds_span_for_suggestions(def_id); + if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() { + err.multipart_suggestions( + msg, candidates.iter().map(|t| { - format!( - "{} {}", - match introducer { - Introducer::Plus => " +", - Introducer::Colon => ":", - Introducer::Nothing => "", - }, - self.tcx.def_path_str(t.def_id), - ) + vec![ + (param.span.shrink_to_lo(), "(".to_string()), + ( + bounds_span.unwrap(), + format!(" + {})", self.tcx.def_path_str(t.def_id)), + ), + ] }), Applicability::MaybeIncorrect, ); + return; } + + let (sp, introducer) = if let Some(span) = bounds_span { + (span, Introducer::Plus) + } else if let Some(colon_span) = param.colon_span { + (colon_span.shrink_to_hi(), Introducer::Nothing) + } else if param.is_impl_trait() { + (param.span.shrink_to_hi(), Introducer::Plus) + } else { + (param.span.shrink_to_hi(), Introducer::Colon) + }; + + err.span_suggestions( + sp, + msg, + candidates.iter().map(|t| { + format!( + "{} {}", + match introducer { + Introducer::Plus => " +", + Introducer::Colon => ":", + Introducer::Nothing => "", + }, + self.tcx.def_path_str(t.def_id) + ) + }), + Applicability::MaybeIncorrect, + ); return; } Node::Item(hir::Item { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index cf95d4f04bb..59bee69cfff 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -836,7 +836,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); let e = self.report_error(ct); self.replaced_with_error = Some(e); - self.interner().const_error_with_guaranteed(ct.ty(), e) + self.interner().const_error(ct.ty(), e) } } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 08eec0707c0..79fc02c6c79 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -26,24 +26,17 @@ use super::equate::Equate; use super::glb::Glb; use super::lub::Lub; use super::sub::Sub; -use super::type_variable::TypeVariableValue; -use super::{DefineOpaqueTypes, InferCtxt, MiscVariable, TypeTrace}; +use super::{DefineOpaqueTypes, InferCtxt, TypeTrace}; +use crate::infer::generalize::{self, CombineDelegate, Generalization}; use crate::traits::{Obligation, PredicateObligations}; -use rustc_data_structures::sso::SsoHashMap; -use rustc_hir::def_id::DefId; use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{ - self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, TypeVisitableExt, -}; +use rustc_middle::ty::relate::{RelateResult, TypeRelation}; +use rustc_middle::ty::{self, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{IntType, UintType}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::DUMMY_SP; #[derive(Clone)] pub struct CombineFields<'infcx, 'tcx> { @@ -55,13 +48,6 @@ pub struct CombineFields<'infcx, 'tcx> { pub define_opaque_types: DefineOpaqueTypes, } -#[derive(Copy, Clone, Debug)] -pub enum RelationDir { - SubtypeOf, - SupertypeOf, - EqTo, -} - impl<'tcx> InferCtxt<'tcx> { pub fn super_combine_tys<R>( &self, @@ -152,7 +138,7 @@ impl<'tcx> InferCtxt<'tcx> { Ok(a) } - _ => ty::relate::super_relate_tys(relation, a, b), + _ => ty::relate::structurally_relate_tys(relation, a, b), } } @@ -209,13 +195,13 @@ impl<'tcx> InferCtxt<'tcx> { // HACK: equating both sides with `[const error]` eagerly prevents us // from leaving unconstrained inference vars during things like impl // matching in the solver. - let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar); + let a_error = self.tcx.const_error(a.ty(), guar); if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() { - return self.unify_const_variable(vid, a_error); + return self.unify_const_variable(vid, a_error, relation.param_env()); } - let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar); + let b_error = self.tcx.const_error(b.ty(), guar); if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() { - return self.unify_const_variable(vid, b_error); + return self.unify_const_variable(vid, b_error, relation.param_env()); } return Ok(if relation.a_is_expected() { a_error } else { b_error }); @@ -237,11 +223,11 @@ impl<'tcx> InferCtxt<'tcx> { } (ty::ConstKind::Infer(InferConst::Var(vid)), _) => { - return self.unify_const_variable(vid, b); + return self.unify_const_variable(vid, b, relation.param_env()); } (_, ty::ConstKind::Infer(InferConst::Var(vid))) => { - return self.unify_const_variable(vid, a); + return self.unify_const_variable(vid, a, relation.param_env()); } (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => @@ -252,7 +238,7 @@ impl<'tcx> InferCtxt<'tcx> { _ => {} } - ty::relate::super_relate_consts(relation, a, b) + ty::relate::structurally_relate_consts(relation, a, b) } /// Unifies the const variable `target_vid` with the given constant. @@ -294,24 +280,17 @@ impl<'tcx> InferCtxt<'tcx> { &self, target_vid: ty::ConstVid<'tcx>, ct: ty::Const<'tcx>, + param_env: ty::ParamEnv<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - let (for_universe, span) = { - let mut inner = self.inner.borrow_mut(); - let variable_table = &mut inner.const_unification_table(); - let var_value = variable_table.probe_value(target_vid); - match var_value.val { - ConstVariableValue::Known { value } => { - bug!("instantiating {:?} which has a known value {:?}", target_vid, value) - } - ConstVariableValue::Unknown { universe } => (universe, var_value.origin.span), - } - }; - let value = ct.try_fold_with(&mut ConstInferUnifier { - infcx: self, - span, - for_universe, + let span = + self.inner.borrow_mut().const_unification_table().probe_value(target_vid).origin.span; + let Generalization { value, needs_wf: _ } = generalize::generalize( + self, + &mut CombineDelegate { infcx: self, span, param_env }, + ct, target_vid, - })?; + ty::Variance::Invariant, + )?; self.inner.borrow_mut().const_unification_table().union_value( target_vid, @@ -392,12 +371,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { pub fn instantiate( &mut self, a_ty: Ty<'tcx>, - dir: RelationDir, + ambient_variance: ty::Variance, b_vid: ty::TyVid, a_is_expected: bool, ) -> RelateResult<'tcx, ()> { - use self::RelationDir::*; - // Get the actual variable that b_vid has been inferred to debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown()); @@ -412,7 +389,18 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { // `'?2` and `?3` are fresh region/type inference // variables. (Down below, we will relate `a_ty <: b_ty`, // adding constraints like `'x: '?2` and `?1 <: ?3`.) - let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?; + let Generalization { value: b_ty, needs_wf } = generalize::generalize( + self.infcx, + &mut CombineDelegate { + infcx: self.infcx, + param_env: self.param_env, + span: self.trace.span(), + }, + a_ty, + b_vid, + ambient_variance, + )?; + debug!(?b_ty); self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty); @@ -431,78 +419,23 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { // relations wind up attributed to the same spans. We need // to associate causes/spans with each of the relations in // the stack to get this right. - match dir { - EqTo => self.equate(a_is_expected).relate(a_ty, b_ty), - SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty), - SupertypeOf => self.sub(a_is_expected).relate_with_variance( + match ambient_variance { + ty::Variance::Invariant => self.equate(a_is_expected).relate(a_ty, b_ty), + ty::Variance::Covariant => self.sub(a_is_expected).relate(a_ty, b_ty), + ty::Variance::Contravariant => self.sub(a_is_expected).relate_with_variance( ty::Contravariant, ty::VarianceDiagInfo::default(), a_ty, b_ty, ), + ty::Variance::Bivariant => { + unreachable!("no code should be generalizing bivariantly (currently)") + } }?; Ok(()) } - /// Attempts to generalize `ty` for the type variable `for_vid`. - /// This checks for cycle -- that is, whether the type `ty` - /// references `for_vid`. The `dir` is the "direction" for which we - /// a performing the generalization (i.e., are we producing a type - /// that can be used as a supertype etc). - /// - /// Preconditions: - /// - /// - `for_vid` is a "root vid" - #[instrument(skip(self), level = "trace", ret)] - fn generalize( - &self, - ty: Ty<'tcx>, - for_vid: ty::TyVid, - dir: RelationDir, - ) -> RelateResult<'tcx, Generalization<'tcx>> { - // Determine the ambient variance within which `ty` appears. - // The surrounding equation is: - // - // ty [op] ty2 - // - // where `op` is either `==`, `<:`, or `:>`. This maps quite - // naturally. - let ambient_variance = match dir { - RelationDir::EqTo => ty::Invariant, - RelationDir::SubtypeOf => ty::Covariant, - RelationDir::SupertypeOf => ty::Contravariant, - }; - - trace!(?ambient_variance); - - let for_universe = match self.infcx.inner.borrow_mut().type_variables().probe(for_vid) { - v @ TypeVariableValue::Known { .. } => { - bug!("instantiating {:?} which has a known value {:?}", for_vid, v,) - } - TypeVariableValue::Unknown { universe } => universe, - }; - - trace!(?for_universe); - trace!(?self.trace); - - let mut generalize = Generalizer { - infcx: self.infcx, - cause: &self.trace.cause, - for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid), - for_universe, - ambient_variance, - needs_wf: false, - root_ty: ty, - param_env: self.param_env, - cache: SsoHashMap::new(), - }; - - let ty = generalize.relate(ty, ty)?; - let needs_wf = generalize.needs_wf; - Ok(Generalization { ty, needs_wf }) - } - pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.obligations.extend(obligations.into_iter()); } @@ -514,313 +447,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { } } -struct Generalizer<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, - - /// The span, used when creating new type variables and things. - cause: &'cx ObligationCause<'tcx>, - - /// The vid of the type variable that is in the process of being - /// instantiated; if we find this within the type we are folding, - /// that means we would have created a cyclic type. - for_vid_sub_root: ty::TyVid, - - /// The universe of the type variable that is in the process of - /// being instantiated. Any fresh variables that we create in this - /// process should be in that same universe. - for_universe: ty::UniverseIndex, - - /// Track the variance as we descend into the type. - ambient_variance: ty::Variance, - - /// See the field `needs_wf` in `Generalization`. - needs_wf: bool, - - /// The root type that we are generalizing. Used when reporting cycles. - root_ty: Ty<'tcx>, - - param_env: ty::ParamEnv<'tcx>, - - cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>, -} - -/// Result from a generalization operation. This includes -/// not only the generalized type, but also a bool flag -/// indicating whether further WF checks are needed. -#[derive(Debug)] -struct Generalization<'tcx> { - ty: Ty<'tcx>, - - /// If true, then the generalized type may not be well-formed, - /// even if the source type is well-formed, so we should add an - /// additional check to enforce that it is. This arises in - /// particular around 'bivariant' type parameters that are only - /// constrained by a where-clause. As an example, imagine a type: - /// - /// struct Foo<A, B> where A: Iterator<Item = B> { - /// data: A - /// } - /// - /// here, `A` will be covariant, but `B` is - /// unconstrained. However, whatever it is, for `Foo` to be WF, it - /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`, - /// then after generalization we will wind up with a type like - /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C, - /// ?D>` (or `>:`), we will wind up with the requirement that `?A - /// <: ?C`, but no particular relationship between `?B` and `?D` - /// (after all, we do not know the variance of the normalized form - /// of `A::Item` with respect to `A`). If we do nothing else, this - /// may mean that `?D` goes unconstrained (as in #41677). So, in - /// this scenario where we create a new type variable in a - /// bivariant context, we set the `needs_wf` flag to true. This - /// will force the calling code to check that `WF(Foo<?C, ?D>)` - /// holds, which in turn implies that `?C::Item == ?D`. So once - /// `?C` is constrained, that should suffice to restrict `?D`. - needs_wf: bool, -} - -impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env - } - - fn tag(&self) -> &'static str { - "Generalizer" - } - - fn a_is_expected(&self) -> bool { - true - } - - fn binders<T>( - &mut self, - a: ty::Binder<'tcx, T>, - b: ty::Binder<'tcx, T>, - ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> - where - T: Relate<'tcx>, - { - Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) - } - - fn relate_item_substs( - &mut self, - item_def_id: DefId, - a_subst: SubstsRef<'tcx>, - b_subst: SubstsRef<'tcx>, - ) -> RelateResult<'tcx, SubstsRef<'tcx>> { - if self.ambient_variance == ty::Variance::Invariant { - // Avoid fetching the variance if we are in an invariant - // context; no need, and it can induce dependency cycles - // (e.g., #41849). - relate::relate_substs(self, a_subst, b_subst) - } else { - let tcx = self.tcx(); - let opt_variances = tcx.variances_of(item_def_id); - relate::relate_substs_with_variances( - self, - item_def_id, - &opt_variances, - a_subst, - b_subst, - true, - ) - } - } - - fn relate_with_variance<T: Relate<'tcx>>( - &mut self, - variance: ty::Variance, - _info: ty::VarianceDiagInfo<'tcx>, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - let old_ambient_variance = self.ambient_variance; - self.ambient_variance = self.ambient_variance.xform(variance); - - let result = self.relate(a, b); - self.ambient_variance = old_ambient_variance; - result - } - - fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be == - - if let Some(&result) = self.cache.get(&t) { - return Ok(result); - } - debug!("generalize: t={:?}", t); - - // Check to see whether the type we are generalizing references - // any other type variable related to `vid` via - // subtyping. This is basically our "occurs check", preventing - // us from creating infinitely sized types. - let result = match *t.kind() { - ty::Infer(ty::TyVar(vid)) => { - let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid); - let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid); - if sub_vid == self.for_vid_sub_root { - // If sub-roots are equal, then `for_vid` and - // `vid` are related via subtyping. - Err(TypeError::CyclicTy(self.root_ty)) - } else { - let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid); - match probe { - TypeVariableValue::Known { value: u } => { - debug!("generalize: known value {:?}", u); - self.relate(u, u) - } - TypeVariableValue::Unknown { universe } => { - match self.ambient_variance { - // Invariant: no need to make a fresh type variable. - ty::Invariant => { - if self.for_universe.can_name(universe) { - return Ok(t); - } - } - - // Bivariant: make a fresh var, but we - // may need a WF predicate. See - // comment on `needs_wf` field for - // more info. - ty::Bivariant => self.needs_wf = true, - - // Co/contravariant: this will be - // sufficiently constrained later on. - ty::Covariant | ty::Contravariant => (), - } - - let origin = - *self.infcx.inner.borrow_mut().type_variables().var_origin(vid); - let new_var_id = self - .infcx - .inner - .borrow_mut() - .type_variables() - .new_var(self.for_universe, origin); - let u = self.tcx().mk_ty_var(new_var_id); - - // Record that we replaced `vid` with `new_var_id` as part of a generalization - // operation. This is needed to detect cyclic types. To see why, see the - // docs in the `type_variables` module. - self.infcx.inner.borrow_mut().type_variables().sub(vid, new_var_id); - debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); - Ok(u) - } - } - } - } - ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { - // No matter what mode we are in, - // integer/floating-point types must be equal to be - // relatable. - Ok(t) - } - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { - let s = self.relate(substs, substs)?; - Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) }) - } - _ => relate::super_relate_tys(self, t, t), - }?; - - self.cache.insert(t, result); - Ok(result) - } - - fn regions( - &mut self, - r: ty::Region<'tcx>, - r2: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be == - - debug!("generalize: regions r={:?}", r); - - match *r { - // Never make variables for regions bound within the type itself, - // nor for erased regions. - ty::ReLateBound(..) | ty::ReErased => { - return Ok(r); - } - - ty::ReError(_) => { - return Ok(r); - } - - ty::RePlaceholder(..) - | ty::ReVar(..) - | ty::ReStatic - | ty::ReEarlyBound(..) - | ty::ReFree(..) => { - // see common code below - } - } - - // If we are in an invariant context, we can re-use the region - // as is, unless it happens to be in some universe that we - // can't name. (In the case of a region *variable*, we could - // use it if we promoted it into our universe, but we don't - // bother.) - if let ty::Invariant = self.ambient_variance { - let r_universe = self.infcx.universe_of_region(r); - if self.for_universe.can_name(r_universe) { - return Ok(r); - } - } - - // FIXME: This is non-ideal because we don't give a - // very descriptive origin for this region variable. - Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.cause.span), self.for_universe)) - } - - fn consts( - &mut self, - c: ty::Const<'tcx>, - c2: ty::Const<'tcx>, - ) -> RelateResult<'tcx, ty::Const<'tcx>> { - assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be == - - match c.kind() { - ty::ConstKind::Infer(InferConst::Var(vid)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let variable_table = &mut inner.const_unification_table(); - let var_value = variable_table.probe_value(vid); - match var_value.val { - ConstVariableValue::Known { value: u } => { - drop(inner); - self.relate(u, u) - } - ConstVariableValue::Unknown { universe } => { - if self.for_universe.can_name(universe) { - Ok(c) - } else { - let new_var_id = variable_table.new_key(ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { universe: self.for_universe }, - }); - Ok(self.tcx().mk_const(new_var_id, c.ty())) - } - } - } - } - ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { - let substs = self.relate_with_variance( - ty::Variance::Invariant, - ty::VarianceDiagInfo::default(), - substs, - substs, - )?; - Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty())) - } - _ => relate::super_relate_consts(self, c, c), - } - } -} - pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// Register obligations that must hold in order for this relation to hold fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>); @@ -873,135 +499,3 @@ fn float_unification_error<'tcx>( let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v; TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b)) } - -struct ConstInferUnifier<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, - - span: Span, - - for_universe: ty::UniverseIndex, - - /// The vid of the const variable that is in the process of being - /// instantiated; if we find this within the const we are folding, - /// that means we would have created a cyclic const. - target_vid: ty::ConstVid<'tcx>, -} - -impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ConstInferUnifier<'_, 'tcx> { - type Error = TypeError<'tcx>; - - fn interner(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - #[instrument(level = "debug", skip(self), ret)] - fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, TypeError<'tcx>> { - match t.kind() { - &ty::Infer(ty::TyVar(vid)) => { - let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid); - let probe = self.infcx.inner.borrow_mut().type_variables().probe(vid); - match probe { - TypeVariableValue::Known { value: u } => { - debug!("ConstOccursChecker: known value {:?}", u); - u.try_fold_with(self) - } - TypeVariableValue::Unknown { universe } => { - if self.for_universe.can_name(universe) { - return Ok(t); - } - - let origin = - *self.infcx.inner.borrow_mut().type_variables().var_origin(vid); - let new_var_id = self - .infcx - .inner - .borrow_mut() - .type_variables() - .new_var(self.for_universe, origin); - Ok(self.interner().mk_ty_var(new_var_id)) - } - } - } - ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => Ok(t), - _ => t.try_super_fold_with(self), - } - } - - #[instrument(level = "debug", skip(self), ret)] - fn try_fold_region( - &mut self, - r: ty::Region<'tcx>, - ) -> Result<ty::Region<'tcx>, TypeError<'tcx>> { - debug!("ConstInferUnifier: r={:?}", r); - - match *r { - // Never make variables for regions bound within the type itself, - // nor for erased regions. - ty::ReLateBound(..) | ty::ReErased | ty::ReError(_) => { - return Ok(r); - } - - ty::RePlaceholder(..) - | ty::ReVar(..) - | ty::ReStatic - | ty::ReEarlyBound(..) - | ty::ReFree(..) => { - // see common code below - } - } - - let r_universe = self.infcx.universe_of_region(r); - if self.for_universe.can_name(r_universe) { - return Ok(r); - } else { - // FIXME: This is non-ideal because we don't give a - // very descriptive origin for this region variable. - Ok(self.infcx.next_region_var_in_universe(MiscVariable(self.span), self.for_universe)) - } - } - - #[instrument(level = "debug", skip(self), ret)] - fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, TypeError<'tcx>> { - match c.kind() { - ty::ConstKind::Infer(InferConst::Var(vid)) => { - // Check if the current unification would end up - // unifying `target_vid` with a const which contains - // an inference variable which is unioned with `target_vid`. - // - // Not doing so can easily result in stack overflows. - if self - .infcx - .inner - .borrow_mut() - .const_unification_table() - .unioned(self.target_vid, vid) - { - return Err(TypeError::CyclicConst(c)); - } - - let var_value = - self.infcx.inner.borrow_mut().const_unification_table().probe_value(vid); - match var_value.val { - ConstVariableValue::Known { value: u } => u.try_fold_with(self), - ConstVariableValue::Unknown { universe } => { - if self.for_universe.can_name(universe) { - Ok(c) - } else { - let new_var_id = - self.infcx.inner.borrow_mut().const_unification_table().new_key( - ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { - universe: self.for_universe, - }, - }, - ); - Ok(self.interner().mk_const(new_var_id, c.ty())) - } - } - } - } - _ => c.try_super_fold_with(self), - } - } -} diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index f90f7674b55..793505e4ab2 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -1,7 +1,7 @@ use crate::infer::DefineOpaqueTypes; use crate::traits::PredicateObligations; -use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir}; +use super::combine::{CombineFields, ObligationEmittingRelation}; use super::Subtype; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; @@ -88,11 +88,11 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { } (&ty::Infer(TyVar(a_id)), _) => { - self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?; + self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?; } (_, &ty::Infer(TyVar(b_id))) => { - self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?; + self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?; } ( diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ce70f39cc40..ad4f5058b5e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2723,7 +2723,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { | (ty::Infer(ty::InferTy::TyVar(_)), _) | (_, ty::Infer(ty::InferTy::TyVar(_))) => Ok(a), (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Mismatch), - _ => relate::super_relate_tys(self, a, b), + _ => relate::structurally_relate_tys(self, a, b), } } diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs new file mode 100644 index 00000000000..d4a1dacde10 --- /dev/null +++ b/compiler/rustc_infer/src/infer/generalize.rs @@ -0,0 +1,479 @@ +use rustc_data_structures::sso::SsoHashMap; +use rustc_hir::def_id::DefId; +use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; +use rustc_middle::ty::error::TypeError; +use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::{self, InferConst, Term, Ty, TyCtxt, TypeVisitableExt}; +use rustc_span::Span; + +use crate::infer::nll_relate::TypeRelatingDelegate; +use crate::infer::type_variable::TypeVariableValue; +use crate::infer::{InferCtxt, RegionVariableOrigin}; + +/// Attempts to generalize `term` for the type variable `for_vid`. +/// This checks for cycles -- that is, whether the type `term` +/// references `for_vid`. +pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>( + infcx: &InferCtxt<'tcx>, + delegate: &mut D, + term: T, + for_vid: impl Into<ty::TermVid<'tcx>>, + ambient_variance: ty::Variance, +) -> RelateResult<'tcx, Generalization<T>> { + let (for_universe, root_vid) = match for_vid.into() { + ty::TermVid::Ty(ty_vid) => ( + infcx.probe_ty_var(ty_vid).unwrap_err(), + ty::TermVid::Ty(infcx.inner.borrow_mut().type_variables().sub_root_var(ty_vid)), + ), + ty::TermVid::Const(ct_vid) => ( + infcx.probe_const_var(ct_vid).unwrap_err(), + ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid)), + ), + }; + + let mut generalizer = Generalizer { + infcx, + delegate, + ambient_variance, + root_vid, + for_universe, + root_term: term.into(), + needs_wf: false, + cache: Default::default(), + }; + + assert!(!term.has_escaping_bound_vars()); + let value = generalizer.relate(term, term)?; + let needs_wf = generalizer.needs_wf; + Ok(Generalization { value, needs_wf }) +} + +/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking +/// in the generalizer code. +pub trait GeneralizerDelegate<'tcx> { + fn param_env(&self) -> ty::ParamEnv<'tcx>; + + fn forbid_inference_vars() -> bool; + + fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>; +} + +pub struct CombineDelegate<'cx, 'tcx> { + pub infcx: &'cx InferCtxt<'tcx>, + pub param_env: ty::ParamEnv<'tcx>, + pub span: Span, +} + +impl<'tcx> GeneralizerDelegate<'tcx> for CombineDelegate<'_, 'tcx> { + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } + + fn forbid_inference_vars() -> bool { + false + } + + fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { + // FIXME: This is non-ideal because we don't give a + // very descriptive origin for this region variable. + self.infcx + .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(self.span), universe) + } +} + +impl<'tcx, T> GeneralizerDelegate<'tcx> for T +where + T: TypeRelatingDelegate<'tcx>, +{ + fn param_env(&self) -> ty::ParamEnv<'tcx> { + <Self as TypeRelatingDelegate<'tcx>>::param_env(self) + } + + fn forbid_inference_vars() -> bool { + <Self as TypeRelatingDelegate<'tcx>>::forbid_inference_vars() + } + + fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { + <Self as TypeRelatingDelegate<'tcx>>::generalize_existential(self, universe) + } +} + +/// The "generalizer" is used when handling inference variables. +/// +/// The basic strategy for handling a constraint like `?A <: B` is to +/// apply a "generalization strategy" to the term `B` -- this replaces +/// all the lifetimes in the term `B` with fresh inference variables. +/// (You can read more about the strategy in this [blog post].) +/// +/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x +/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the +/// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which +/// establishes `'0: 'x` as a constraint. +/// +/// [blog post]: https://is.gd/0hKvIr +struct Generalizer<'me, 'tcx, D> { + infcx: &'me InferCtxt<'tcx>, + + /// This is used to abstract the behaviors of the three previous + /// generalizer-like implementations (`Generalizer`, `TypeGeneralizer`, + /// and `ConstInferUnifier`). See [`GeneralizerDelegate`] for more + /// information. + delegate: &'me mut D, + + /// After we generalize this type, we are going to relate it to + /// some other type. What will be the variance at this point? + ambient_variance: ty::Variance, + + /// The vid of the type variable that is in the process of being + /// instantiated. If we find this within the value we are folding, + /// that means we would have created a cyclic value. + root_vid: ty::TermVid<'tcx>, + + /// The universe of the type variable that is in the process of being + /// instantiated. If we find anything that this universe cannot name, + /// we reject the relation. + for_universe: ty::UniverseIndex, + + /// The root term (const or type) we're generalizing. Used for cycle errors. + root_term: Term<'tcx>, + + cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>, + + /// See the field `needs_wf` in `Generalization`. + needs_wf: bool, +} + +impl<'tcx, D> Generalizer<'_, 'tcx, D> { + /// Create an error that corresponds to the term kind in `root_term` + fn cyclic_term_error(&self) -> TypeError<'tcx> { + match self.root_term.unpack() { + ty::TermKind::Ty(ty) => TypeError::CyclicTy(ty), + ty::TermKind::Const(ct) => TypeError::CyclicConst(ct), + } + } +} + +impl<'tcx, D> TypeRelation<'tcx> for Generalizer<'_, 'tcx, D> +where + D: GeneralizerDelegate<'tcx>, +{ + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.delegate.param_env() + } + + fn tag(&self) -> &'static str { + "Generalizer" + } + + fn a_is_expected(&self) -> bool { + true + } + + fn relate_item_substs( + &mut self, + item_def_id: DefId, + a_subst: ty::SubstsRef<'tcx>, + b_subst: ty::SubstsRef<'tcx>, + ) -> RelateResult<'tcx, ty::SubstsRef<'tcx>> { + if self.ambient_variance == ty::Variance::Invariant { + // Avoid fetching the variance if we are in an invariant + // context; no need, and it can induce dependency cycles + // (e.g., #41849). + relate::relate_substs(self, a_subst, b_subst) + } else { + let tcx = self.tcx(); + let opt_variances = tcx.variances_of(item_def_id); + relate::relate_substs_with_variances( + self, + item_def_id, + opt_variances, + a_subst, + b_subst, + true, + ) + } + } + + #[instrument(level = "debug", skip(self, variance, b), ret)] + fn relate_with_variance<T: Relate<'tcx>>( + &mut self, + variance: ty::Variance, + _info: ty::VarianceDiagInfo<'tcx>, + a: T, + b: T, + ) -> RelateResult<'tcx, T> { + let old_ambient_variance = self.ambient_variance; + self.ambient_variance = self.ambient_variance.xform(variance); + debug!(?self.ambient_variance, "new ambient variance"); + let r = self.relate(a, b)?; + self.ambient_variance = old_ambient_variance; + Ok(r) + } + + #[instrument(level = "debug", skip(self, t2), ret)] + fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be == + + if let Some(&result) = self.cache.get(&t) { + return Ok(result); + } + + // Check to see whether the type we are generalizing references + // any other type variable related to `vid` via + // subtyping. This is basically our "occurs check", preventing + // us from creating infinitely sized types. + let g = match *t.kind() { + ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) + if D::forbid_inference_vars() => + { + bug!("unexpected inference variable encountered in NLL generalization: {t}"); + } + + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("unexpected infer type: {t}") + } + + ty::Infer(ty::TyVar(vid)) => { + let mut inner = self.infcx.inner.borrow_mut(); + let vid = inner.type_variables().root_var(vid); + let sub_vid = inner.type_variables().sub_root_var(vid); + + if ty::TermVid::Ty(sub_vid) == self.root_vid { + // If sub-roots are equal, then `root_vid` and + // `vid` are related via subtyping. + Err(self.cyclic_term_error()) + } else { + let probe = inner.type_variables().probe(vid); + match probe { + TypeVariableValue::Known { value: u } => { + drop(inner); + self.relate(u, u) + } + TypeVariableValue::Unknown { universe } => { + match self.ambient_variance { + // Invariant: no need to make a fresh type variable + // if we can name the universe. + ty::Invariant => { + if self.for_universe.can_name(universe) { + return Ok(t); + } + } + + // Bivariant: make a fresh var, but we + // may need a WF predicate. See + // comment on `needs_wf` field for + // more info. + ty::Bivariant => self.needs_wf = true, + + // Co/contravariant: this will be + // sufficiently constrained later on. + ty::Covariant | ty::Contravariant => (), + } + + let origin = *inner.type_variables().var_origin(vid); + let new_var_id = + inner.type_variables().new_var(self.for_universe, origin); + let u = self.tcx().mk_ty_var(new_var_id); + + // Record that we replaced `vid` with `new_var_id` as part of a generalization + // operation. This is needed to detect cyclic types. To see why, see the + // docs in the `type_variables` module. + inner.type_variables().sub(vid, new_var_id); + debug!("replacing original vid={:?} with new={:?}", vid, u); + Ok(u) + } + } + } + } + + ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { + // No matter what mode we are in, + // integer/floating-point types must be equal to be + // relatable. + Ok(t) + } + + ty::Placeholder(placeholder) => { + if self.for_universe.can_name(placeholder.universe) { + Ok(t) + } else { + debug!( + "root universe {:?} cannot name placeholder in universe {:?}", + self.for_universe, placeholder.universe + ); + Err(TypeError::Mismatch) + } + } + + _ => relate::structurally_relate_tys(self, t, t), + }?; + + self.cache.insert(t, g); + Ok(g) + } + + #[instrument(level = "debug", skip(self, r2), ret)] + fn regions( + &mut self, + r: ty::Region<'tcx>, + r2: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be == + + match *r { + // Never make variables for regions bound within the type itself, + // nor for erased regions. + ty::ReLateBound(..) | ty::ReErased => { + return Ok(r); + } + + // It doesn't really matter for correctness if we generalize ReError, + // since we're already on a doomed compilation path. + ty::ReError(_) => { + return Ok(r); + } + + ty::RePlaceholder(..) + | ty::ReVar(..) + | ty::ReStatic + | ty::ReEarlyBound(..) + | ty::ReFree(..) => { + // see common code below + } + } + + // If we are in an invariant context, we can re-use the region + // as is, unless it happens to be in some universe that we + // can't name. + if let ty::Invariant = self.ambient_variance { + let r_universe = self.infcx.universe_of_region(r); + if self.for_universe.can_name(r_universe) { + return Ok(r); + } + } + + Ok(self.delegate.generalize_region(self.for_universe)) + } + + #[instrument(level = "debug", skip(self, c2), ret)] + fn consts( + &mut self, + c: ty::Const<'tcx>, + c2: ty::Const<'tcx>, + ) -> RelateResult<'tcx, ty::Const<'tcx>> { + assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be == + + match c.kind() { + ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { + bug!("unexpected inference variable encountered in NLL generalization: {:?}", c); + } + ty::ConstKind::Infer(InferConst::Var(vid)) => { + // If root const vids are equal, then `root_vid` and + // `vid` are related and we'd be inferring an infinitely + // deep const. + if ty::TermVid::Const( + self.infcx.inner.borrow_mut().const_unification_table().find(vid), + ) == self.root_vid + { + return Err(self.cyclic_term_error()); + } + + let mut inner = self.infcx.inner.borrow_mut(); + let variable_table = &mut inner.const_unification_table(); + let var_value = variable_table.probe_value(vid); + match var_value.val { + ConstVariableValue::Known { value: u } => { + drop(inner); + self.relate(u, u) + } + ConstVariableValue::Unknown { universe } => { + if self.for_universe.can_name(universe) { + Ok(c) + } else { + let new_var_id = variable_table.new_key(ConstVarValue { + origin: var_value.origin, + val: ConstVariableValue::Unknown { universe: self.for_universe }, + }); + Ok(self.tcx().mk_const(new_var_id, c.ty())) + } + } + } + } + // FIXME: remove this branch once `structurally_relate_consts` is fully + // structural. + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { + let substs = self.relate_with_variance( + ty::Variance::Invariant, + ty::VarianceDiagInfo::default(), + substs, + substs, + )?; + Ok(self.tcx().mk_const(ty::UnevaluatedConst { def, substs }, c.ty())) + } + ty::ConstKind::Placeholder(placeholder) => { + if self.for_universe.can_name(placeholder.universe) { + Ok(c) + } else { + debug!( + "root universe {:?} cannot name placeholder in universe {:?}", + self.for_universe, placeholder.universe + ); + Err(TypeError::Mismatch) + } + } + _ => relate::structurally_relate_consts(self, c, c), + } + } + + #[instrument(level = "debug", skip(self), ret)] + fn binders<T>( + &mut self, + a: ty::Binder<'tcx, T>, + _: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> + where + T: Relate<'tcx>, + { + let result = self.relate(a.skip_binder(), a.skip_binder())?; + Ok(a.rebind(result)) + } +} + +/// Result from a generalization operation. This includes +/// not only the generalized type, but also a bool flag +/// indicating whether further WF checks are needed. +#[derive(Debug)] +pub struct Generalization<T> { + pub value: T, + + /// If true, then the generalized type may not be well-formed, + /// even if the source type is well-formed, so we should add an + /// additional check to enforce that it is. This arises in + /// particular around 'bivariant' type parameters that are only + /// constrained by a where-clause. As an example, imagine a type: + /// + /// struct Foo<A, B> where A: Iterator<Item = B> { + /// data: A + /// } + /// + /// here, `A` will be covariant, but `B` is + /// unconstrained. However, whatever it is, for `Foo` to be WF, it + /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`, + /// then after generalization we will wind up with a type like + /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C, + /// ?D>` (or `>:`), we will wind up with the requirement that `?A + /// <: ?C`, but no particular relationship between `?B` and `?D` + /// (after all, we do not know the variance of the normalized form + /// of `A::Item` with respect to `A`). If we do nothing else, this + /// may mean that `?D` goes unconstrained (as in #41677). So, in + /// this scenario where we create a new type variable in a + /// bivariant context, we set the `needs_wf` flag to true. This + /// will force the calling code to check that `WF(Foo<?C, ?D>)` + /// holds, which in turn implies that `?C::Item == ?D`. So once + /// `?C` is constrained, that should suffice to restrict `?D`. + pub needs_wf: bool, +} diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9a95a9c8375..f8329965c43 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -58,6 +58,7 @@ pub mod error_reporting; pub mod free_regions; mod freshen; mod fudge; +mod generalize; mod glb; mod higher_ranked; pub mod lattice; @@ -1533,7 +1534,7 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs)); if let Err(e) = ct.error_reported() { - return Err(ErrorHandled::Reported(e)); + return Err(ErrorHandled::Reported(e.into())); } else if ct.has_non_region_infer() || ct.has_non_region_param() { return Err(ErrorHandled::TooGeneric); } else { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 9c139d17c18..4ae6af5f5be 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -21,21 +21,20 @@ //! thing we relate in chalk are basically domain goals and their //! constituents) -use crate::infer::InferCtxt; -use crate::infer::{ConstVarValue, ConstVariableValue}; -use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::traits::{Obligation, PredicateObligations}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::FnMutDelegate; -use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; use rustc_span::{Span, Symbol}; use std::fmt::Debug; -use super::combine::ObligationEmittingRelation; +use crate::infer::combine::ObligationEmittingRelation; +use crate::infer::generalize::{self, Generalization}; +use crate::infer::InferCtxt; +use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::traits::{Obligation, PredicateObligations}; pub struct TypeRelating<'me, 'tcx, D> where @@ -198,7 +197,7 @@ where _ => (), } - let generalized_ty = self.generalize_value(value_ty, vid)?; + let generalized_ty = self.generalize(value_ty, vid)?; debug!("relate_ty_var: generalized_ty = {:?}", generalized_ty); if D::forbid_inference_vars() { @@ -217,26 +216,15 @@ where result } - fn generalize_value<T: Relate<'tcx>>( - &mut self, - value: T, - for_vid: ty::TyVid, - ) -> RelateResult<'tcx, T> { - let universe = self.infcx.probe_ty_var(for_vid).unwrap_err(); - - if value.has_escaping_bound_vars() { - bug!("trying to instantiate {for_vid:?} with escaping bound vars: {value:?}"); - } - - let mut generalizer = TypeGeneralizer { - infcx: self.infcx, - delegate: &mut self.delegate, - ambient_variance: self.ambient_variance, - for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables().sub_root_var(for_vid), - universe, - }; - - generalizer.relate(value, value) + fn generalize(&mut self, ty: Ty<'tcx>, for_vid: ty::TyVid) -> RelateResult<'tcx, Ty<'tcx>> { + let Generalization { value: ty, needs_wf: _ } = generalize::generalize( + self.infcx, + &mut self.delegate, + ty, + for_vid, + self.ambient_variance, + )?; + Ok(ty) } fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { @@ -716,235 +704,3 @@ where })]); } } - -/// The "type generalizer" is used when handling inference variables. -/// -/// The basic strategy for handling a constraint like `?A <: B` is to -/// apply a "generalization strategy" to the type `B` -- this replaces -/// all the lifetimes in the type `B` with fresh inference -/// variables. (You can read more about the strategy in this [blog -/// post].) -/// -/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x -/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the -/// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which -/// establishes `'0: 'x` as a constraint. -/// -/// [blog post]: https://is.gd/0hKvIr -struct TypeGeneralizer<'me, 'tcx, D> -where - D: TypeRelatingDelegate<'tcx>, -{ - infcx: &'me InferCtxt<'tcx>, - - delegate: &'me mut D, - - /// After we generalize this type, we are going to relate it to - /// some other type. What will be the variance at this point? - ambient_variance: ty::Variance, - - /// The vid of the type variable that is in the process of being - /// instantiated. If we find this within the value we are folding, - /// that means we would have created a cyclic value. - for_vid_sub_root: ty::TyVid, - - /// The universe of the type variable that is in the process of being - /// instantiated. If we find anything that this universe cannot name, - /// we reject the relation. - universe: ty::UniverseIndex, -} - -impl<'tcx, D> TypeRelation<'tcx> for TypeGeneralizer<'_, 'tcx, D> -where - D: TypeRelatingDelegate<'tcx>, -{ - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.delegate.param_env() - } - - fn tag(&self) -> &'static str { - "nll::generalizer" - } - - fn a_is_expected(&self) -> bool { - true - } - - fn relate_with_variance<T: Relate<'tcx>>( - &mut self, - variance: ty::Variance, - _info: ty::VarianceDiagInfo<'tcx>, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - debug!( - "TypeGeneralizer::relate_with_variance(variance={:?}, a={:?}, b={:?})", - variance, a, b - ); - - let old_ambient_variance = self.ambient_variance; - self.ambient_variance = self.ambient_variance.xform(variance); - - debug!( - "TypeGeneralizer::relate_with_variance: ambient_variance = {:?}", - self.ambient_variance - ); - - let r = self.relate(a, b)?; - - self.ambient_variance = old_ambient_variance; - - debug!("TypeGeneralizer::relate_with_variance: r={:?}", r); - - Ok(r) - } - - fn tys(&mut self, a: Ty<'tcx>, _: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - use crate::infer::type_variable::TypeVariableValue; - - debug!("TypeGeneralizer::tys(a={:?})", a); - - match *a.kind() { - ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) - if D::forbid_inference_vars() => - { - bug!("unexpected inference variable encountered in NLL generalization: {:?}", a); - } - - ty::Infer(ty::TyVar(vid)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let variables = &mut inner.type_variables(); - let vid = variables.root_var(vid); - let sub_vid = variables.sub_root_var(vid); - if sub_vid == self.for_vid_sub_root { - // If sub-roots are equal, then `for_vid` and - // `vid` are related via subtyping. - debug!("TypeGeneralizer::tys: occurs check failed"); - Err(TypeError::Mismatch) - } else { - match variables.probe(vid) { - TypeVariableValue::Known { value: u } => { - drop(inner); - self.relate(u, u) - } - TypeVariableValue::Unknown { universe: _universe } => { - if self.ambient_variance == ty::Bivariant { - // FIXME: we may need a WF predicate (related to #54105). - } - - let origin = *variables.var_origin(vid); - - // Replacing with a new variable in the universe `self.universe`, - // it will be unified later with the original type variable in - // the universe `_universe`. - let new_var_id = variables.new_var(self.universe, origin); - - let u = self.tcx().mk_ty_var(new_var_id); - debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); - Ok(u) - } - } - } - } - - ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { - // No matter what mode we are in, - // integer/floating-point types must be equal to be - // relatable. - Ok(a) - } - - ty::Placeholder(placeholder) => { - if self.universe.cannot_name(placeholder.universe) { - debug!( - "TypeGeneralizer::tys: root universe {:?} cannot name\ - placeholder in universe {:?}", - self.universe, placeholder.universe - ); - Err(TypeError::Mismatch) - } else { - Ok(a) - } - } - - _ => relate::super_relate_tys(self, a, a), - } - } - - fn regions( - &mut self, - a: ty::Region<'tcx>, - _: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("TypeGeneralizer::regions(a={:?})", a); - - if let ty::ReLateBound(..) = *a { - return Ok(a); - } - - // For now, we just always create a fresh region variable to - // replace all the regions in the source type. In the main - // type checker, we special case the case where the ambient - // variance is `Invariant` and try to avoid creating a fresh - // region variable, but since this comes up so much less in - // NLL (only when users use `_` etc) it is much less - // important. - // - // As an aside, since these new variables are created in - // `self.universe` universe, this also serves to enforce the - // universe scoping rules. - // - // FIXME(#54105) -- if the ambient variance is bivariant, - // though, we may however need to check well-formedness or - // risk a problem like #41677 again. - let replacement_region_vid = self.delegate.generalize_existential(self.universe); - - Ok(replacement_region_vid) - } - - fn consts( - &mut self, - a: ty::Const<'tcx>, - _: ty::Const<'tcx>, - ) -> RelateResult<'tcx, ty::Const<'tcx>> { - match a.kind() { - ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { - bug!("unexpected inference variable encountered in NLL generalization: {:?}", a); - } - ty::ConstKind::Infer(InferConst::Var(vid)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let variable_table = &mut inner.const_unification_table(); - let var_value = variable_table.probe_value(vid); - match var_value.val.known() { - Some(u) => self.relate(u, u), - None => { - let new_var_id = variable_table.new_key(ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { universe: self.universe }, - }); - Ok(self.tcx().mk_const(new_var_id, a.ty())) - } - } - } - ty::ConstKind::Unevaluated(..) if self.tcx().lazy_normalization() => Ok(a), - _ => relate::super_relate_consts(self, a, a), - } - } - - fn binders<T>( - &mut self, - a: ty::Binder<'tcx, T>, - _: ty::Binder<'tcx, T>, - ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> - where - T: Relate<'tcx>, - { - debug!("TypeGeneralizer::binders(a={:?})", a); - let result = self.relate(a.skip_binder(), a.skip_binder())?; - Ok(a.rebind(result)) - } -} diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 75ce0f83fd6..cd2462d3c31 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -187,7 +187,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { } else if pattern == value { Ok(pattern) } else { - relate::super_relate_tys(self, pattern, value) + relate::structurally_relate_tys(self, pattern, value) } } @@ -201,7 +201,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { if pattern == value { Ok(pattern) } else { - relate::super_relate_consts(self, pattern, value) + relate::structurally_relate_consts(self, pattern, value) } } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 3766c250a9c..e0f29a8de8f 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -1,4 +1,4 @@ -use super::combine::{CombineFields, RelationDir}; +use super::combine::CombineFields; use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin}; use crate::traits::{Obligation, PredicateObligations}; @@ -108,11 +108,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { Ok(a) } (&ty::Infer(TyVar(a_id)), _) => { - self.fields.instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?; + self.fields.instantiate(b, ty::Contravariant, a_id, !self.a_is_expected)?; Ok(a) } (_, &ty::Infer(TyVar(b_id))) => { - self.fields.instantiate(a, RelationDir::SubtypeOf, b_id, self.a_is_expected)?; + self.fields.instantiate(a, ty::Covariant, b_id, self.a_is_expected)?; Ok(a) } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 51354c2b127..c9e857141c9 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -9,6 +9,7 @@ use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_lint::LintStore; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::{bug, ty}; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; @@ -37,8 +38,7 @@ pub struct Compiler { pub(crate) sess: Lrc<Session>, codegen_backend: Lrc<Box<dyn CodegenBackend>>, pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>, - pub(crate) override_queries: - Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>, + pub(crate) override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>, } impl Compiler { @@ -60,6 +60,11 @@ impl Compiler { } } +#[allow(rustc::bad_opt_access)] +pub fn set_thread_safe_mode(sopts: &config::UnstableOptions) { + rustc_data_structures::sync::set_dyn_thread_safe_mode(sopts.threads > 1); +} + /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> { rustc_span::create_default_session_if_not_set_then(move |_| { @@ -270,8 +275,7 @@ pub struct Config { /// the list of queries. /// /// The second parameter is local providers and the third parameter is external providers. - pub override_queries: - Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::ExternProviders)>, + pub override_queries: Option<fn(&Session, &mut Providers, &mut ExternProviders)>, /// This is a callback from the driver that is called to create a codegen backend. pub make_codegen_backend: @@ -347,7 +351,7 @@ pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) { // state if it was responsible for triggering the panic. let i = ty::tls::with_context_opt(|icx| { if let Some(icx) = icx { - print_query_stack(QueryCtxt { tcx: icx.tcx }, icx.query, handler, num_frames) + print_query_stack(QueryCtxt::new(icx.tcx), icx.query, handler, num_frames) } else { 0 } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 48401eabd1e..cb10916abb1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -17,7 +17,7 @@ use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintSto use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; -use rustc_middle::ty::query::{ExternProviders, Providers}; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt}; use rustc_mir_build as mir_build; use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr}; @@ -700,9 +700,12 @@ pub fn create_global_ctxt<'tcx>( hir_arena, untracked, dep_graph, - query_result_on_disk_cache, rustc_query_impl::query_callbacks(arena), - rustc_query_impl::query_system_fns(local_providers, extern_providers), + rustc_query_impl::query_system( + local_providers, + extern_providers, + query_result_on_disk_cache, + ), ) }) }) diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 1c58caa0353..2c8014d8b3a 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -1,6 +1,6 @@ use rustc_ast::attr; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index c07dc19a0ac..d511d2b1280 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -582,34 +582,38 @@ impl Cursor<'_> { let mut base = Base::Decimal; if first_digit == '0' { // Attempt to parse encoding base. - let has_digits = match self.first() { + match self.first() { 'b' => { base = Base::Binary; self.bump(); - self.eat_decimal_digits() + if !self.eat_decimal_digits() { + return Int { base, empty_int: true }; + } } 'o' => { base = Base::Octal; self.bump(); - self.eat_decimal_digits() + if !self.eat_decimal_digits() { + return Int { base, empty_int: true }; + } } 'x' => { base = Base::Hexadecimal; self.bump(); - self.eat_hexadecimal_digits() + if !self.eat_hexadecimal_digits() { + return Int { base, empty_int: true }; + } } - // Not a base prefix. - '0'..='9' | '_' | '.' | 'e' | 'E' => { + // Not a base prefix; consume additional digits. + '0'..='9' | '_' => { self.eat_decimal_digits(); - true } + + // Also not a base prefix; nothing more to do here. + '.' | 'e' | 'E' => {} + // Just a 0. _ => return Int { base, empty_int: false }, - }; - // Base prefix was provided, but there were no digits - // after it, e.g. "0x". - if !has_digits { - return Int { base, empty_int: true }; } } else { // No base prefix, parse number in the usual way. diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b1c45eaf601..6601a80920b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -611,7 +611,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { declare_lint! { /// The `missing_copy_implementations` lint detects potentially-forgotten - /// implementations of [`Copy`]. + /// implementations of [`Copy`] for public types. /// /// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html /// @@ -647,7 +647,9 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS]) impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { - if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) { + if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) + && cx.tcx.local_visibility(item.owner_id.def_id).is_public()) + { return; } let (def, ty) = match item.kind { @@ -727,7 +729,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { declare_lint! { /// The `missing_debug_implementations` lint detects missing - /// implementations of [`fmt::Debug`]. + /// implementations of [`fmt::Debug`] for public types. /// /// [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html /// @@ -766,7 +768,9 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]); impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { - if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) { + if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) + && cx.tcx.local_visibility(item.owner_id.def_id).is_public()) + { return; } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 53d7cf74cde..1d0c43e95e0 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -49,9 +49,9 @@ use std::cell::Cell; use std::iter; use std::slice; -type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync; +type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync; type LateLintPassFactory = - dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::Send + sync::Sync; + dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync; /// Information about the registered lints. /// @@ -169,7 +169,7 @@ impl LintStore { pub fn register_early_pass( &mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync, ) { self.early_passes.push(Box::new(pass)); } @@ -182,7 +182,7 @@ impl LintStore { /// * See [rust-clippy#5518](https://github.com/rust-lang/rust-clippy/pull/5518) pub fn register_pre_expansion_pass( &mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::DynSend + sync::DynSync, ) { self.pre_expansion_passes.push(Box::new(pass)); } @@ -191,8 +191,8 @@ impl LintStore { &mut self, pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + 'static - + sync::Send - + sync::Sync, + + sync::DynSend + + sync::DynSync, ) { self.late_passes.push(Box::new(pass)); } @@ -201,8 +201,8 @@ impl LintStore { &mut self, pass: impl for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + 'static - + sync::Send - + sync::Sync, + + sync::DynSend + + sync::DynSync, ) { self.late_module_passes.push(Box::new(pass)); } diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index e9eb14ea188..b1266b58a61 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -1,5 +1,5 @@ use crate::lints::{Expectation, ExpectationNote}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS; use rustc_session::lint::LintExpectationId; diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index b42878a02ee..c9781a72704 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -16,7 +16,7 @@ use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; use rustc_ast as ast; -use rustc_data_structures::sync::join; +use rustc_data_structures::sync::{join, DynSend}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit as hir_visit; @@ -429,7 +429,7 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( /// Performs lint checking on a crate. pub fn check_crate<'tcx, T: LateLintPass<'tcx> + 'tcx>( tcx: TyCtxt<'tcx>, - builtin_lints: impl FnOnce() -> T + Send, + builtin_lints: impl FnOnce() -> T + Send + DynSend, ) { join( || { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index a43c09a7939..b92ed11f38a 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -20,7 +20,7 @@ use rustc_middle::lint::{ reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource, ShallowLintLevelMap, }; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{RegisteredTools, TyCtxt}; use rustc_session::lint::builtin::{RENAMED_AND_REMOVED_LINTS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES}; use rustc_session::lint::{ diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 5c7016633c2..dfddfe09ab3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -86,7 +86,7 @@ use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index a8b25ff66d7..001d53b1099 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -253,7 +253,7 @@ fn add_query_desc_cached_impl( quote! { #[allow(unused_variables, unused_braces, rustc::pass_by_value)] #[inline] - pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::ty::query::query_keys::#name<'tcx>) -> bool { + pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::query_keys::#name<'tcx>) -> bool { #expr } } @@ -262,7 +262,7 @@ fn add_query_desc_cached_impl( // we're taking `key` by reference, but some rustc types usually prefer being passed by value #[allow(rustc::pass_by_value)] #[inline] - pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::ty::query::query_keys::#name<'tcx>) -> bool { + pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::query_keys::#name<'tcx>) -> bool { false } } @@ -273,7 +273,7 @@ fn add_query_desc_cached_impl( let desc = quote! { #[allow(unused_variables)] - pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::ty::query::query_keys::#name<'tcx>) -> String { + pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::query::query_keys::#name<'tcx>) -> String { let (#tcx, #key) = (tcx, key); ::rustc_middle::ty::print::with_no_trimmed_paths!( format!(#desc) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index eab32ad8e3f..1c36d5e82da 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1472,28 +1472,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .. } = 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, + // If this file is under $sysroot/lib/rustlib/src/ + // and the user wish to simulate remapping with -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.unstable_opts.simulate_remapped_rust_src_base - { - if let Some(real_dir) = &sess.opts.real_rust_source_base_dir { - for subdir in ["library", "compiler"] { - 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.join(subdir)) { - *old_name = rustc_span::RealFileName::Remapped { - local_path: None, - virtual_name: virtual_dir.join(subdir).join(rest), - }; - } - } - } + && let Some(real_dir) = &sess.opts.real_rust_source_base_dir + && let rustc_span::FileName::Real(ref mut old_name) = name { + let relative_path = match old_name { + rustc_span::RealFileName::LocalPath(local) => local.strip_prefix(real_dir).ok(), + rustc_span::RealFileName::Remapped { virtual_name, .. } => { + option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok()) + } + }; + debug!(?relative_path, ?virtual_dir, "simulate_remapped_rust_src_base"); + for subdir in ["library", "compiler"] { + if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) { + *old_name = rustc_span::RealFileName::Remapped { + local_path: None, // FIXME: maybe we should preserve this? + virtual_name: virtual_dir.join(subdir).join(rest), + }; + break; } } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4a3b783c636..fe880b939ef 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -14,8 +14,8 @@ use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; use rustc_middle::query::LocalCrate; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::cstore::CrateStore; use rustc_session::{Session, StableCrateId}; @@ -114,8 +114,8 @@ macro_rules! provide_one { ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => { fn $name<'tcx>( $tcx: TyCtxt<'tcx>, - def_id_arg: ty::query::query_keys::$name<'tcx>, - ) -> ty::query::query_provided::$name<'tcx> { + def_id_arg: rustc_middle::query::query_keys::$name<'tcx>, + ) -> rustc_middle::query::query_provided::$name<'tcx> { let _prof_timer = $tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name))); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 36be07f6205..79eb48a1a31 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; -use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; +use rustc_data_structures::sync::{join, par_for_each_in, Lrc}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -25,10 +25,10 @@ use rustc_middle::middle::exported_symbols::{ }; use rustc_middle::mir::interpret; use rustc_middle::query::LocalCrate; +use rustc_middle::query::Providers; use rustc_middle::traits::specialization_graph; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; use rustc_middle::util::common::to_readable_str; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; @@ -1516,8 +1516,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) { - record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- tcx.mir_generator_witnesses(def_id)); + if tcx.sess.opts.unstable_opts.drop_tracking_mir + && let DefKind::Generator = self.tcx.def_kind(def_id) + && let Some(witnesses) = tcx.mir_generator_witnesses(def_id) + { + record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses); } } if encode_const { @@ -2131,7 +2134,7 @@ fn prefetch_mir(tcx: TyCtxt<'_>) { return; } - par_iter(tcx.mir_keys(())).for_each(|&def_id| { + par_for_each_in(tcx.mir_keys(()), |&def_id| { let (encode_const, encode_opt) = should_encode_mir(tcx, def_id); if encode_const { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1328d700210..9eaf330b536 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -20,8 +20,8 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; +use rustc_middle::query::Providers; use rustc_middle::ty::fast_reject::SimplifiedType; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams}; use rustc_middle::ty::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt}; use rustc_serialize::opaque::FileEncoder; diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index a7d97bd3cf5..7c56af1da41 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -11,6 +11,7 @@ chalk-ir = "0.87.0" derive_more = "0.99.17" either = "1.5.0" gsgdt = "0.1.2" +field-offset = "0.3.5" measureme = "10.0.0" polonius-engine = "0.13.0" rustc_apfloat = { path = "../rustc_apfloat" } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 15d672c1408..5bf0938d518 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -5,7 +5,7 @@ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; +use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; @@ -150,11 +150,6 @@ impl<'hir> Map<'hir> { self.tcx.hir_module_items(module).items() } - #[inline] - pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) { - par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id)); - } - pub fn def_key(self, def_id: LocalDefId) -> DefKey { // Accessing the DefKey is ok, since it is part of DefPathHash. self.tcx.definitions_untracked().def_key(def_id) @@ -502,7 +497,7 @@ impl<'hir> Map<'hir> { } #[inline] - pub fn par_body_owners(self, f: impl Fn(LocalDefId) + Sync + Send) { + pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id)); } @@ -640,7 +635,7 @@ impl<'hir> Map<'hir> { } #[inline] - pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + Sync + Send) { + pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { let crate_items = self.tcx.hir_crate_items(()); par_for_each_in(&crate_items.submodules[..], |module| f(module.def_id)) } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 7770a5e4764..61c9e72db2c 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -6,10 +6,10 @@ pub mod map; pub mod nested_filter; pub mod place; -use crate::ty::query::Providers; +use crate::query::Providers; use crate::ty::{EarlyBinder, ImplSubject, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; +use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::*; use rustc_query_system::ich::StableHashingContext; @@ -77,19 +77,19 @@ impl ModuleItems { self.owners().map(|id| id.def_id) } - pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) { + pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) { par_for_each_in(&self.items[..], |&id| f(id)) } - pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + Send + Sync) { + pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) { par_for_each_in(&self.trait_items[..], |&id| f(id)) } - pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + Send + Sync) { + pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) { par_for_each_in(&self.impl_items[..], |&id| f(id)) } - pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + Send + Sync) { + pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) { par_for_each_in(&self.foreign_items[..], |&id| f(id)) } } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e9172e767e0..dc911c88574 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -85,12 +85,7 @@ mod tests; mod macros; #[macro_use] -pub mod query; - -#[macro_use] pub mod arena; -#[macro_use] -pub mod dep_graph; pub(crate) mod error; pub mod hir; pub mod infer; @@ -100,10 +95,16 @@ pub mod middle; pub mod mir; pub mod thir; pub mod traits; +#[macro_use] pub mod ty; pub mod util; mod values; +#[macro_use] +pub mod query; +#[macro_use] +pub mod dep_graph; + // Allows macros to refer to this crate as `::rustc_middle` extern crate self as rustc_middle; diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 12aef66bcf9..bd859d4d61b 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -11,7 +11,7 @@ use crate::bug; use crate::error::LimitInvalid; -use crate::ty; +use crate::query::Providers; use rustc_ast::Attribute; use rustc_session::Session; use rustc_session::{Limit, Limits}; @@ -19,7 +19,7 @@ use rustc_span::symbol::{sym, Symbol}; use std::num::IntErrorKind; -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { providers.limits = |tcx, ()| Limits { recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess), move_size_limit: get_limit( diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 9c25f3009ba..9bb4570ef14 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -32,6 +32,6 @@ pub mod region; pub mod resolve_bound_vars; pub mod stability; -pub fn provide(providers: &mut crate::ty::query::Providers) { +pub fn provide(providers: &mut crate::query::Providers) { limits::provide(providers); } diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 967fed687b6..aeb6a1601fc 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -64,7 +64,7 @@ impl EffectiveVisibility { self.at_level(level).is_public() } - pub fn from_vis(vis: Visibility) -> EffectiveVisibility { + pub const fn from_vis(vis: Visibility) -> EffectiveVisibility { EffectiveVisibility { direct: vis, reexported: vis, @@ -72,6 +72,18 @@ impl EffectiveVisibility { reachable_through_impl_trait: vis, } } + + #[must_use] + pub fn min(mut self, lhs: EffectiveVisibility, tcx: TyCtxt<'_>) -> Self { + for l in Level::all_levels() { + let rhs_vis = self.at_level_mut(l); + let lhs_vis = *lhs.at_level(l); + if rhs_vis.is_at_least(lhs_vis, tcx) { + *rhs_vis = lhs_vis; + }; + } + self + } } /// Holds a map of effective visibilities for reachable HIR nodes. @@ -137,24 +149,6 @@ impl EffectiveVisibilities { }; } - pub fn set_public_at_level( - &mut self, - id: LocalDefId, - lazy_private_vis: impl FnOnce() -> Visibility, - level: Level, - ) { - let mut effective_vis = self - .effective_vis(id) - .copied() - .unwrap_or_else(|| EffectiveVisibility::from_vis(lazy_private_vis())); - for l in Level::all_levels() { - if l <= level { - *effective_vis.at_level_mut(l) = Visibility::Public; - } - } - self.map.insert(id, effective_vis); - } - pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) { if !cfg!(debug_assertions) { return; @@ -219,7 +213,7 @@ impl<Id: Eq + Hash> EffectiveVisibilities<Id> { pub fn update( &mut self, id: Id, - nominal_vis: Visibility, + nominal_vis: Option<Visibility>, lazy_private_vis: impl FnOnce() -> Visibility, inherited_effective_vis: EffectiveVisibility, level: Level, @@ -243,12 +237,11 @@ impl<Id: Eq + Hash> EffectiveVisibilities<Id> { if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level && level != l) { - calculated_effective_vis = - if nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { - inherited_effective_vis_at_level - } else { - nominal_vis - }; + calculated_effective_vis = if let Some(nominal_vis) = nominal_vis && !nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { + nominal_vis + } else { + inherited_effective_vis_at_level + } } // effective visibility can't be decreased at next update call for the // same id diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e45284ca506..d65ceef2472 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -15,15 +15,49 @@ use std::{any::Any, backtrace::Backtrace, fmt}; pub enum ErrorHandled { /// Already reported an error for this evaluation, and the compilation is /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. - Reported(ErrorGuaranteed), + Reported(ReportedErrorInfo), /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, } impl From<ErrorGuaranteed> for ErrorHandled { - fn from(err: ErrorGuaranteed) -> ErrorHandled { - ErrorHandled::Reported(err) + #[inline] + fn from(error: ErrorGuaranteed) -> ErrorHandled { + ErrorHandled::Reported(error.into()) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub struct ReportedErrorInfo { + error: ErrorGuaranteed, + is_tainted_by_errors: bool, +} + +impl ReportedErrorInfo { + #[inline] + pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: true, error } + } + + /// Returns true if evaluation failed because MIR was tainted by errors. + #[inline] + pub fn is_tainted_by_errors(self) -> bool { + self.is_tainted_by_errors + } +} + +impl From<ErrorGuaranteed> for ReportedErrorInfo { + #[inline] + fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: false, error } + } +} + +impl Into<ErrorGuaranteed> for ReportedErrorInfo { + #[inline] + fn into(self) -> ErrorGuaranteed { + self.error } } @@ -89,7 +123,7 @@ fn print_backtrace(backtrace: &Backtrace) { impl From<ErrorGuaranteed> for InterpErrorInfo<'_> { fn from(err: ErrorGuaranteed) -> Self { - InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into() + InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into() } } @@ -125,7 +159,7 @@ pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. TooGeneric, /// Abort in case errors are already reported. - AlreadyReported(ErrorGuaranteed), + AlreadyReported(ReportedErrorInfo), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), /// An error occurred during FnAbi computation: the passed --target lacks FFI support @@ -144,7 +178,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { use InvalidProgramInfo::*; match self { TooGeneric => write!(f, "encountered overly generic constant"), - AlreadyReported(ErrorGuaranteed { .. }) => { + AlreadyReported(_) => { write!( f, "an error has already been reported elsewhere (this should not usually be printed)" diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index e5a9766c84d..3620385fab1 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -120,8 +120,8 @@ use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, - MachineStopType, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, - UninitBytesAccess, UnsupportedOpInfo, + MachineStopType, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, + UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, }; pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar}; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index ed4ee93e97d..ce11dabc195 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -61,7 +61,7 @@ impl<'tcx> TyCtxt<'tcx> { self.const_eval_global_id(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } @@ -110,7 +110,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 55991facd89..1da94dd7917 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1111,6 +1111,10 @@ pub struct VarDebugInfo<'tcx> { /// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the /// argument number in the original function before it was inlined. pub argument_index: Option<u16>, + + /// The data represents `name` dereferenced `references` times, + /// and not the direct value. + pub references: u8, } /////////////////////////////////////////////////////////////////////////// @@ -1550,8 +1554,11 @@ impl<V, T> ProjectionElem<V, T> { /// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`. pub fn can_use_in_debuginfo(&self) -> bool { match self { - Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true, - Self::ConstantIndex { .. } + Self::ConstantIndex { from_end: false, .. } + | Self::Deref + | Self::Downcast(_, _) + | Self::Field(_, _) => true, + Self::ConstantIndex { from_end: true, .. } | Self::Index(_) | Self::OpaqueCast(_) | Self::Subslice { .. } => false, @@ -1639,18 +1646,7 @@ impl<'tcx> Place<'tcx> { return self; } - let mut v: Vec<PlaceElem<'tcx>>; - - let new_projections = if self.projection.is_empty() { - more_projections - } else { - v = Vec::with_capacity(self.projection.len() + more_projections.len()); - v.extend(self.projection); - v.extend(more_projections); - &v - }; - - Place { local: self.local, projection: tcx.mk_place_elems(new_projections) } + self.as_ref().project_deeper(more_projections, tcx) } } @@ -1721,6 +1717,27 @@ impl<'tcx> PlaceRef<'tcx> { (base, *proj) }) } + + /// Generates a new place by appending `more_projections` to the existing ones + /// and interning the result. + pub fn project_deeper( + self, + more_projections: &[PlaceElem<'tcx>], + tcx: TyCtxt<'tcx>, + ) -> Place<'tcx> { + let mut v: Vec<PlaceElem<'tcx>>; + + let new_projections = if self.projection.is_empty() { + more_projections + } else { + v = Vec::with_capacity(self.projection.len() + more_projections.len()); + v.extend(self.projection); + v.extend(more_projections); + &v + }; + + Place { local: self.local, projection: tcx.mk_place_elems(new_projections) } + } } impl Debug for Place<'_> { @@ -2313,7 +2330,7 @@ impl<'tcx> ConstantKind<'tcx> { if let Some(val) = c.kind().try_eval_for_mir(tcx, param_env) { match val { Ok(val) => Self::Val(val, c.ty()), - Err(_) => Self::Ty(tcx.const_error(self.ty())), + Err(guar) => Self::Ty(tcx.const_error(self.ty(), guar)), } } else { self @@ -2325,9 +2342,7 @@ impl<'tcx> ConstantKind<'tcx> { match tcx.const_eval_resolve(param_env, uneval, None) { Ok(val) => Self::Val(val, ty), Err(ErrorHandled::TooGeneric) => self, - Err(ErrorHandled::Reported(guar)) => { - Self::Ty(tcx.const_error_with_guaranteed(ty, guar)) - } + Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar.into())), } } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index fa8a339631e..62c3d8cf239 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -551,8 +551,13 @@ fn write_scope_tree( } let indented_debug_info = format!( - "{0:1$}debug {2} => {3:?};", - INDENT, indent, var_debug_info.name, var_debug_info.value, + "{0:1$}debug {2} => {3:&<4$}{5:?};", + INDENT, + indent, + var_debug_info.name, + "", + var_debug_info.references as usize, + var_debug_info.value, ); writeln!( diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index d7a7fdebda6..596dd80bf48 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -842,6 +842,7 @@ macro_rules! make_mir_visitor { source_info, value, argument_index: _, + references: _, } = var_debug_info; self.visit_source_info(source_info); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5acdd68e60e..f564f5e99e8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -4,8 +4,89 @@ //! ["Queries: demand-driven compilation"](https://rustc-dev-guide.rust-lang.org/query.html). //! This chapter includes instructions for adding new queries. -use crate::ty::{self, print::describe_as_module, TyCtxt}; +#![allow(unused_parens)] + +use crate::dep_graph; +use crate::dep_graph::DepKind; +use crate::infer::canonical::{self, Canonical}; +use crate::lint::LintExpectation; +use crate::metadata::ModChild; +use crate::middle::codegen_fn_attrs::CodegenFnAttrs; +use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; +use crate::middle::lib_features::LibFeatures; +use crate::middle::privacy::EffectiveVisibilities; +use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; +use crate::middle::stability::{self, DeprecationEntry}; +use crate::mir; +use crate::mir::interpret::GlobalId; +use crate::mir::interpret::{ + ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, +}; +use crate::mir::interpret::{LitToConstError, LitToConstInput}; +use crate::mir::mono::CodegenUnit; +use crate::query::erase::{erase, restore, Erase}; +use crate::thir; +use crate::traits::query::{ + CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, + CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution, +}; +use crate::traits::query::{ + DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult, + OutlivesBound, +}; +use crate::traits::specialization_graph; +use crate::traits::{self, ImplSource}; +use crate::ty::fast_reject::SimplifiedType; +use crate::ty::layout::ValidityRequirement; +use crate::ty::query::{ + query_ensure, query_get_at, DynamicQuery, IntoQueryParam, TyCtxtAt, TyCtxtEnsure, + TyCtxtEnsureWithValue, +}; +use crate::ty::subst::{GenericArg, SubstsRef}; +use crate::ty::util::AlwaysRequiresDrop; +use crate::ty::GeneratorDiagnosticData; +use crate::ty::TyCtxtFeed; +use crate::ty::{ + self, print::describe_as_module, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, + UnusedGenericParams, +}; +use rustc_arena::TypedArena; +use rustc_ast as ast; +use rustc_ast::expand::allocator::AllocatorKind; +use rustc_attr as attr; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; +use rustc_data_structures::steal::Steal; +use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::WorkerLocal; +use rustc_data_structures::unord::UnordSet; +use rustc_errors::ErrorGuaranteed; +use rustc_hir as hir; +use rustc_hir::def::{DefKind, DocLinkResMap}; +use rustc_hir::def_id::{ + CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet, +}; +use rustc_hir::lang_items::{LangItem, LanguageItems}; +use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; +use rustc_index::IndexVec; +use rustc_query_system::ich::StableHashingContext; +use rustc_query_system::query::{try_get_cached, CacheSelector, QueryCache, QueryMode, QueryState}; +use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; +use rustc_session::cstore::{CrateDepKind, CrateSource}; +use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; +use rustc_session::lint::LintExpectationId; +use rustc_session::Limits; use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::symbol::Symbol; +use rustc_span::{Span, DUMMY_SP}; +use rustc_target::abi; +use rustc_target::spec::PanicStrategy; +use std::mem; +use std::ops::Deref; +use std::path::PathBuf; +use std::sync::Arc; pub mod erase; mod keys; @@ -446,7 +527,7 @@ rustc_queries! { } } - query mir_generator_witnesses(key: DefId) -> &'tcx mir::GeneratorLayout<'tcx> { + query mir_generator_witnesses(key: DefId) -> &'tcx Option<mir::GeneratorLayout<'tcx>> { arena_cache desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -2102,3 +2183,6 @@ rustc_queries! { desc { "check whether two const param are definitely not equal to eachother"} } } + +rustc_query_append! { define_callbacks! } +rustc_feedable_queries! { define_feedable! } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 468c2c818b2..cbc68fde9d9 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -83,7 +83,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)), - _ => relate::super_relate_tys(self, a, b), + _ => relate::structurally_relate_tys(self, a, b), } } @@ -109,7 +109,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { _ => {} } - relate::super_relate_consts(self, a, b) + relate::structurally_relate_consts(self, a, b) } fn binders<T>( diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 972c417cbba..a39631da936 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -53,7 +53,7 @@ impl<'tcx> TyCtxt<'tcx> { fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> { let ct = match c.kind() { ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) { - Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e), + Err(e) => self.tcx.const_error(c.ty(), e), Ok(Some(bac)) => { let substs = self.tcx.erase_regions(uv.substs); let bac = bac.subst(self.tcx, substs); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index f29bf92b0ed..be7b2b7ec67 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -5,6 +5,7 @@ use crate::{mir, ty}; use std::fmt::Write; +use crate::query::Providers; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, LangItem}; @@ -457,6 +458,6 @@ impl BorrowKind { } } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { closure_typeinfo, ..*providers } +pub fn provide(providers: &mut Providers) { + *providers = Providers { closure_typeinfo, ..*providers } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e7107c28bf4..0a5792a9c47 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -142,9 +142,7 @@ impl<'tcx> Const<'tcx> { ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)), param_ty, )), - Some(rbv::ResolvedArg::Error(guar)) => { - Some(tcx.const_error_with_guaranteed(param_ty, guar)) - } + Some(rbv::ResolvedArg::Error(guar)) => Some(tcx.const_error(param_ty, guar)), arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id), } } @@ -228,7 +226,7 @@ impl<'tcx> Const<'tcx> { if let Some(val) = self.kind().try_eval_for_typeck(tcx, param_env) { match val { Ok(val) => tcx.mk_const(val, self.ty()), - Err(guar) => tcx.const_error_with_guaranteed(self.ty(), guar), + Err(guar) => tcx.const_error(self.ty(), guar), } } else { // Either the constant isn't evaluatable or ValTree creation failed. diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 1ac2cd13982..a108f6c8947 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -245,7 +245,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ValTree(val?))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } EvalMode::Mir => { @@ -256,7 +256,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ConstVal(val))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8aea2d8aedf..097bfb71a6f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,14 +14,13 @@ use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; -use crate::query::on_disk_cache::OnDiskCache; use crate::query::LocalCrate; +use crate::query::Providers; use crate::thir::Thir; use crate::traits; use crate::traits::solve; use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData}; use crate::ty::query::QuerySystem; -use crate::ty::query::QuerySystemFns; use crate::ty::query::{self, TyCtxtAt}; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, @@ -496,7 +495,7 @@ pub struct GlobalCtxt<'tcx> { /// /// FIXME(Centril): consider `dyn LintStoreMarker` once /// we can upcast to `Any` for some additional type safety. - pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>, + pub lint_store: Lrc<dyn Any + sync::DynSync + sync::DynSend>, pub dep_graph: DepGraph, @@ -648,14 +647,13 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, - lint_store: Lrc<dyn Any + sync::Send + sync::Sync>, + lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>, arena: &'tcx WorkerLocal<Arena<'tcx>>, hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>, untracked: Untracked, dep_graph: DepGraph, - on_disk_cache: Option<OnDiskCache<'tcx>>, query_kinds: &'tcx [DepKindStruct<'tcx>], - query_system_fns: QuerySystemFns<'tcx>, + query_system: QuerySystem<'tcx>, ) -> GlobalCtxt<'tcx> { let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.emit_fatal(err); @@ -677,7 +675,7 @@ impl<'tcx> TyCtxt<'tcx> { lifetimes: common_lifetimes, consts: common_consts, untracked, - query_system: QuerySystem::new(query_system_fns, on_disk_cache), + query_system, query_kinds, ty_rcache: Default::default(), pred_rcache: Default::default(), @@ -735,17 +733,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed` #[track_caller] - pub fn const_error_with_guaranteed( - self, - ty: Ty<'tcx>, - reported: ErrorGuaranteed, - ) -> Const<'tcx> { + pub fn const_error(self, ty: Ty<'tcx>, reported: ErrorGuaranteed) -> Const<'tcx> { self.mk_const(ty::ConstKind::Error(reported), ty) } /// Like [TyCtxt::ty_error] but for constants. #[track_caller] - pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> { + pub fn const_error_misc(self, ty: Ty<'tcx>) -> Const<'tcx> { self.const_error_with_message( ty, DUMMY_SP, @@ -2461,7 +2455,7 @@ pub struct DeducedParamAttrs { pub read_only: bool, } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { providers.maybe_unused_trait_imports = |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; providers.names_imported_by_glob_use = |tcx, id| { diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index fb0d909307e..bf9806f6406 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -94,8 +94,8 @@ where f(None) } else { // We could get an `ImplicitCtxt` pointer from another thread. - // Ensure that `ImplicitCtxt` is `Sync`. - sync::assert_sync::<ImplicitCtxt<'_, '_>>(); + // Ensure that `ImplicitCtxt` is `DynSync`. + sync::assert_dyn_sync::<ImplicitCtxt<'_, '_>>(); unsafe { f(Some(downcast(context))) } } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index ad930d1e6b6..7895993ccff 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,8 +1,9 @@ +use crate::query::Providers; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; -pub(super) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { erase_regions_ty, ..*providers }; +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { erase_regions_ty, ..*providers }; } fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index baef4ffeda7..99174bae3f6 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -103,7 +103,7 @@ impl GenericParamDef { ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(), ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(), ty::GenericParamDefKind::Const { .. } => { - tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into() + tcx.const_error_misc(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into() } } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 9e672004cf9..4223502848e 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -43,6 +43,7 @@ //! This code should only compile in modules where the uninhabitedness of `Foo` //! is visible. +use crate::query::Providers; use crate::ty::context::TyCtxt; use crate::ty::{self, DefId, Ty, VariantDef, Visibility}; @@ -52,9 +53,8 @@ pub mod inhabited_predicate; pub use inhabited_predicate::InhabitedPredicate; -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers }; +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers }; } /// Returns an `InhabitedPredicate` that is generic over type parameters and diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 30f036e471c..71911a5a618 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -199,6 +199,12 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> { unsafe impl<T: Sync> Sync for List<T> {} +// We need this since `List` uses extern type `OpaqueListContents`. +#[cfg(parallel_compiler)] +use rustc_data_structures::sync::DynSync; +#[cfg(parallel_compiler)] +unsafe impl<T: DynSync> DynSync for List<T> {} + // Safety: // Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail, // thus aligns of `Equivalent<T>` and `List<T>` must be the same. diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b414e1200cd..df324bcc52c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -21,6 +21,7 @@ use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, GeneratorLayout}; +use crate::query::Providers; use crate::traits::{self, Reveal}; use crate::ty; use crate::ty::fast_reject::SimplifiedType; @@ -121,6 +122,7 @@ pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; pub mod print; +#[macro_use] pub mod query; pub mod relate; pub mod subst; @@ -1070,6 +1072,24 @@ impl ParamTerm { } } +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum TermVid<'tcx> { + Ty(ty::TyVid), + Const(ty::ConstVid<'tcx>), +} + +impl From<ty::TyVid> for TermVid<'_> { + fn from(value: ty::TyVid) -> Self { + TermVid::Ty(value) + } +} + +impl<'tcx> From<ty::ConstVid<'tcx>> for TermVid<'tcx> { + fn from(value: ty::ConstVid<'tcx>) -> Self { + TermVid::Const(value) + } +} + /// This kind of predicate has no *direct* correspondent in the /// syntax, but it roughly corresponds to the syntactic forms: /// @@ -2590,7 +2610,7 @@ pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy { } } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { closure::provide(providers); context::provide(providers); erase_regions::provide(providers); @@ -2599,7 +2619,7 @@ pub fn provide(providers: &mut ty::query::Providers) { print::provide(providers); super::util::bug::provide(providers); super::middle::provide(providers); - *providers = ty::query::Providers { + *providers = Providers { trait_impls_of: trait_def::trait_impls_of_provider, incoherent_impls: trait_def::incoherent_impls_provider, const_param_default: consts::const_param_default, diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 72710b78c93..1b336b7bfc6 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -207,14 +207,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { - if !self.ignore_errors { - self.tcx.sess.emit_err(ConstNotUsedTraitAlias { + let guar = self + .tcx + .sess + .create_err(ConstNotUsedTraitAlias { ct: ct.to_string(), span: self.span, - }); - } + }) + .emit_unless(self.ignore_errors); - self.interner().const_error(ct.ty()) + self.interner().const_error(ct.ty(), guar) } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 926172ff828..385156262c7 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,4 +1,5 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::query::Providers; use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, @@ -3054,8 +3055,8 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> { map } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { trimmed_def_paths, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { trimmed_def_paths, ..*providers }; } #[derive(Default)] diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 07d47cae5ee..647f4826876 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -1,89 +1,26 @@ -#![allow(unused_parens)] - use crate::dep_graph; use crate::dep_graph::DepKind; -use crate::infer::canonical::{self, Canonical}; -use crate::lint::LintExpectation; -use crate::metadata::ModChild; -use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; -use crate::middle::lib_features::LibFeatures; -use crate::middle::privacy::EffectiveVisibilities; -use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; -use crate::middle::stability::{self, DeprecationEntry}; -use crate::mir; -use crate::mir::interpret::GlobalId; -use crate::mir::interpret::{ - ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, -}; -use crate::mir::interpret::{LitToConstError, LitToConstInput}; -use crate::mir::mono::CodegenUnit; - -use crate::query::erase::{erase, restore, Erase}; use crate::query::on_disk_cache::CacheEncoder; use crate::query::on_disk_cache::EncodedDepNodeIndex; use crate::query::on_disk_cache::OnDiskCache; -use crate::query::{AsLocalKey, Key}; -use crate::thir; -use crate::traits::query::{ - CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, - CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, - CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution, +use crate::query::{ + DynamicQueries, ExternProviders, Providers, QueryArenas, QueryCaches, QueryEngine, QueryStates, }; -use crate::traits::query::{ - DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult, - OutlivesBound, -}; -use crate::traits::specialization_graph; -use crate::traits::{self, ImplSource}; -use crate::ty::context::TyCtxtFeed; -use crate::ty::fast_reject::SimplifiedType; -use crate::ty::layout::ValidityRequirement; -use crate::ty::subst::{GenericArg, SubstsRef}; -use crate::ty::util::AlwaysRequiresDrop; -use crate::ty::GeneratorDiagnosticData; -use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams}; +use crate::ty::TyCtxt; +use field_offset::FieldOffset; use measureme::StringId; -use rustc_arena::TypedArena; -use rustc_ast as ast; -use rustc_ast::expand::allocator::AllocatorKind; -use rustc_attr as attr; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; -use rustc_data_structures::steal::Steal; -use rustc_data_structures::svh::Svh; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::AtomicU64; -use rustc_data_structures::sync::Lrc; -use rustc_data_structures::sync::WorkerLocal; -use rustc_data_structures::unord::UnordSet; -use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; -use rustc_hir::def::{DefKind, DocLinkResMap}; -use rustc_hir::def_id::{ - CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet, -}; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; -use rustc_hir::lang_items::{LangItem, LanguageItems}; -use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; -use rustc_index::IndexVec; -use rustc_query_system::ich::StableHashingContext; +use rustc_query_system::dep_graph::DepNodeIndex; +use rustc_query_system::dep_graph::SerializedDepNodeIndex; pub(crate) use rustc_query_system::query::QueryJobId; use rustc_query_system::query::*; -use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; -use rustc_session::cstore::{CrateDepKind, CrateSource}; -use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; -use rustc_session::lint::LintExpectationId; -use rustc_session::Limits; -use rustc_span::symbol::Symbol; +use rustc_query_system::HandleCycleError; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi; -use rustc_target::spec::PanicStrategy; - -use std::marker::PhantomData; -use std::mem; use std::ops::Deref; -use std::path::PathBuf; -use std::sync::Arc; pub struct QueryKeyStringCache { pub def_id_cache: FxHashMap<DefId, StringId>, @@ -103,6 +40,31 @@ pub struct QueryStruct<'tcx> { Option<fn(TyCtxt<'tcx>, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>, } +pub struct DynamicQuery<'tcx, C: QueryCache> { + pub name: &'static str, + pub eval_always: bool, + pub dep_kind: rustc_middle::dep_graph::DepKind, + pub handle_cycle_error: HandleCycleError, + pub query_state: FieldOffset<QueryStates<'tcx>, QueryState<C::Key, crate::dep_graph::DepKind>>, + pub query_cache: FieldOffset<QueryCaches<'tcx>, C>, + pub cache_on_disk: fn(tcx: TyCtxt<'tcx>, key: &C::Key) -> bool, + pub execute_query: fn(tcx: TyCtxt<'tcx>, k: C::Key) -> C::Value, + pub compute: fn(tcx: TyCtxt<'tcx>, key: C::Key) -> C::Value, + pub can_load_from_disk: bool, + pub try_load_from_disk: fn( + tcx: TyCtxt<'tcx>, + key: &C::Key, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, + ) -> Option<C::Value>, + pub loadable_from_disk: + fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool, + pub hash_result: HashResult<C::Value>, + pub value_from_cycle_error: + fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<crate::dep_graph::DepKind>]) -> C::Value, + pub format_value: fn(&C::Value) -> String, +} + pub struct QuerySystemFns<'tcx> { pub engine: QueryEngine, pub local_providers: Providers, @@ -120,6 +82,7 @@ pub struct QuerySystem<'tcx> { pub states: QueryStates<'tcx>, pub arenas: QueryArenas<'tcx>, pub caches: QueryCaches<'tcx>, + pub dynamic_queries: DynamicQueries<'tcx>, /// 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 @@ -130,23 +93,6 @@ pub struct QuerySystem<'tcx> { pub fns: QuerySystemFns<'tcx>, pub jobs: AtomicU64, - - // Since we erase query value types we tell the typesystem about them with `PhantomData`. - _phantom_values: QueryPhantomValues<'tcx>, -} - -impl<'tcx> QuerySystem<'tcx> { - pub fn new(fns: QuerySystemFns<'tcx>, on_disk_cache: Option<OnDiskCache<'tcx>>) -> Self { - QuerySystem { - states: Default::default(), - arenas: Default::default(), - caches: Default::default(), - on_disk_cache, - fns, - jobs: AtomicU64::new(1), - _phantom_values: Default::default(), - } - } } #[derive(Copy, Clone)] @@ -203,7 +149,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] -fn query_get_at<'tcx, Cache>( +pub fn query_get_at<'tcx, Cache>( tcx: TyCtxt<'tcx>, execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>, query_cache: &Cache, @@ -221,7 +167,7 @@ where } #[inline] -fn query_ensure<'tcx, Cache>( +pub fn query_ensure<'tcx, Cache>( tcx: TyCtxt<'tcx>, execute_query: fn(TyCtxt<'tcx>, Span, Cache::Key, QueryMode) -> Option<Cache::Value>, query_cache: &Cache, @@ -428,11 +374,6 @@ macro_rules! define_callbacks { } #[derive(Default)] - pub struct QueryPhantomValues<'tcx> { - $($(#[$attr])* pub $name: PhantomData<query_values::$name<'tcx>>,)* - } - - #[derive(Default)] pub struct QueryCaches<'tcx> { $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)* } @@ -490,6 +431,12 @@ macro_rules! define_callbacks { })* } + pub struct DynamicQueries<'tcx> { + $( + pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>, + )* + } + #[derive(Default)] pub struct QueryStates<'tcx> { $( @@ -627,9 +574,6 @@ macro_rules! define_feedable { // Queries marked with `fatal_cycle` do not need the latter implementation, // as they will raise an fatal error on query cycles instead. -rustc_query_append! { define_callbacks! } -rustc_feedable_queries! { define_feedable! } - mod sealed { use super::{DefId, LocalDefId, OwnerId}; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index da43475941e..3bbe6a23b66 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -388,24 +388,24 @@ impl<'tcx> Relate<'tcx> for Ty<'tcx> { } } -/// The main "type relation" routine. Note that this does not handle -/// inference artifacts, so you should filter those out before calling -/// it. -pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( +/// Relates `a` and `b` structurally, calling the relation for all nested values. +/// Any semantic equality, e.g. of projections, and inference variables have to be +/// handled by the caller. +pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, a: Ty<'tcx>, b: Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> { let tcx = relation.tcx(); - debug!("super_relate_tys: a={:?} b={:?}", a, b); + debug!("structurally_relate_tys: a={:?} b={:?}", a, b); match (a.kind(), b.kind()) { (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { // The caller should handle these cases! - bug!("var types encountered in super_relate_tys") + bug!("var types encountered in structurally_relate_tys") } (ty::Bound(..), _) | (_, ty::Bound(..)) => { - bug!("bound types encountered in super_relate_tys") + bug!("bound types encountered in structurally_relate_tys") } (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error(guar)), @@ -575,15 +575,18 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( } } -/// The main "const relation" routine. Note that this does not handle -/// inference artifacts, so you should filter those out before calling -/// it. -pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( +/// Relates `a` and `b` structurally, calling the relation for all nested values. +/// Any semantic equality, e.g. of unevaluated consts, and inference variables have +/// to be handled by the caller. +/// +/// FIXME: This is not totally structual, which probably should be fixed. +/// See the HACKs below. +pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( relation: &mut R, mut a: ty::Const<'tcx>, mut b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); + debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); let tcx = relation.tcx(); // HACK(const_generics): We still need to eagerly evaluate consts when @@ -602,7 +605,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( b = tcx.expand_abstract_consts(b); } - debug!("{}.super_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b); + debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b); // Currently, the values that can be unified are primitive types, // and those that derive both `PartialEq` and `Eq`, corresponding @@ -610,7 +613,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( let is_match = match (a.kind(), b.kind()) { (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { // The caller should handle these cases! - bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b) + bug!("var types encountered in structurally_relate_consts: {:?} {:?}", a, b) } (ty::ConstKind::Error(_), _) => return Ok(a), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 29a3bc8bb97..e73208b877f 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -204,6 +204,7 @@ CloneLiftImpls! { (), bool, usize, + u8, u16, u32, u64, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d175cf72d67..e6d51c4ec97 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1708,7 +1708,9 @@ impl<'tcx> Region<'tcx> { ty::ReErased => { flags = flags | TypeFlags::HAS_RE_ERASED; } - ty::ReError(_) => {} + ty::ReError(_) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + } } debug!("type_flags({:?}) = {:?}", self, flags); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9bab693156b..eb903ebfd99 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,6 +2,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; +use crate::query::Providers; use crate::ty::layout::IntegerExt; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -667,10 +668,10 @@ impl<'tcx> TyCtxt<'tcx> { self, def_id: DefId, ) -> impl Iterator<Item = ty::EarlyBinder<Ty<'tcx>>> { - let generator_layout = &self.mir_generator_witnesses(def_id); + let generator_layout = self.mir_generator_witnesses(def_id); generator_layout - .field_tys - .iter() + .as_ref() + .map_or_else(|| [].iter(), |l| l.field_tys.iter()) .filter(|decl| !decl.ignore_for_traits) .map(|decl| ty::EarlyBinder(decl.ty)) } @@ -1484,8 +1485,8 @@ pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub fn provide(providers: &mut Providers) { + *providers = Providers { reveal_opaque_types_in_bounds, is_doc_hidden, is_doc_notable_trait, diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index 3dfd0824f98..43ee0343f5a 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -48,6 +48,6 @@ pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: rustc_hir::def_id::DefId) { ); } -pub fn provide(providers: &mut crate::ty::query::Providers) { - *providers = crate::ty::query::Providers { trigger_delay_span_bug, ..*providers }; +pub fn provide(providers: &mut crate::query::Providers) { + *providers = crate::query::Providers { trigger_delay_span_bug, ..*providers }; } diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 931fe1b2433..b74422708ce 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -154,6 +154,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset)))) }, @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)), + @call("mir_copy_for_deref", args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)), ExprKind::Borrow { borrow_kind, arg } => Ok( Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?) ), diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 59549435233..4d99ab4b0ec 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -52,7 +52,7 @@ pub fn as_constant_inner<'tcx>( match lit_to_mir_constant(tcx, LitToConstInput { lit: &lit.node, ty, neg }) { Ok(c) => c, Err(LitToConstError::Reported(guar)) => { - ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar)) + ConstantKind::Ty(tcx.const_error(ty, guar)) } Err(LitToConstError::TypeError) => { bug!("encountered type error in `lit_to_mir_constant`") diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 4926ff85de3..6df06df5c60 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2241,6 +2241,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info: debug_source_info, + references: 0, value: VarDebugInfoContents::Place(for_arm_body.into()), argument_index: None, }); @@ -2260,6 +2261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info: debug_source_info, + references: 0, value: VarDebugInfoContents::Place(ref_for_guard.into()), argument_index: None, }); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 4536ecf17b8..dbdb5b4a9a1 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -380,18 +380,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - /// Compare two `&T` values using `<T as std::compare::PartialEq>::eq` + /// Compare two values using `<T as std::compare::PartialEq>::eq`. + /// If the values are already references, just call it directly, otherwise + /// take a reference to the values first and then call it. fn non_scalar_compare( &mut self, block: BasicBlock, make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>, source_info: SourceInfo, value: ConstantKind<'tcx>, - place: Place<'tcx>, + mut val: Place<'tcx>, mut ty: Ty<'tcx>, ) { let mut expect = self.literal_operand(source_info.span, value); - let mut val = Operand::Copy(place); // If we're using `b"..."` as a pattern, we need to insert an // unsizing coercion, as the byte string has the type `&[u8; N]`. @@ -421,9 +422,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, temp, - Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty), + Rvalue::Cast( + CastKind::Pointer(PointerCast::Unsize), + Operand::Copy(val), + ty, + ), ); - val = Operand::Move(temp); + val = temp; } if opt_ref_test_ty.is_some() { let slice = self.temp(ty, source_info.span); @@ -438,12 +443,36 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let ty::Ref(_, deref_ty, _) = *ty.kind() else { - bug!("non_scalar_compare called on non-reference type: {}", ty); - }; + match *ty.kind() { + ty::Ref(_, deref_ty, _) => ty = deref_ty, + _ => { + // non_scalar_compare called on non-reference type + let temp = self.temp(ty, source_info.span); + self.cfg.push_assign(block, source_info, temp, Rvalue::Use(expect)); + let ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, ty); + let ref_temp = self.temp(ref_ty, source_info.span); + + self.cfg.push_assign( + block, + source_info, + ref_temp, + Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, temp), + ); + expect = Operand::Move(ref_temp); + + let ref_temp = self.temp(ref_ty, source_info.span); + self.cfg.push_assign( + block, + source_info, + ref_temp, + Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val), + ); + val = ref_temp; + } + } let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [ty, ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -463,7 +492,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { literal: method, })), - args: vec![val, expect], + args: vec![Operand::Copy(val), expect], destination: eq_result, target: Some(eq_block), unwind: UnwindAction::Continue, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 20d381eddb1..4e3e98b56e7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -798,6 +798,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; self.var_debug_info.push(VarDebugInfo { name, + references: 0, source_info: SourceInfo::outermost(captured_place.var_ident.span), value: VarDebugInfoContents::Place(use_place), argument_index: None, @@ -828,6 +829,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.var_debug_info.push(VarDebugInfo { name, source_info, + references: 0, value: VarDebugInfoContents::Place(arg_local.into()), argument_index: Some(argument_index as u16 + 1), }); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 2765a107cf0..c964e62c9d0 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -22,7 +22,7 @@ mod errors; mod lints; pub mod thir; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c73f8284ca5..b243f1dc8d0 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -62,21 +62,13 @@ struct ConstToPat<'tcx> { treat_byte_string_as_slice: bool, } -mod fallback_to_const_ref { - #[derive(Debug)] - /// This error type signals that we encountered a non-struct-eq situation behind a reference. - /// We bubble this up in order to get back to the reference destructuring and make that emit - /// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq` - /// on such patterns (since that function takes a reference) and not have to jump through any - /// hoops to get a reference to the value. - pub(super) struct FallbackToConstRef(()); - - pub(super) fn fallback_to_const_ref(c2p: &super::ConstToPat<'_>) -> FallbackToConstRef { - assert!(c2p.behind_reference.get()); - FallbackToConstRef(()) - } -} -use fallback_to_const_ref::{fallback_to_const_ref, FallbackToConstRef}; +/// This error type signals that we encountered a non-struct-eq situation. +/// We bubble this up in order to get back to the reference destructuring and make that emit +/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq` +/// on such patterns (since that function takes a reference) and not have to jump through any +/// hoops to get a reference to the value. +#[derive(Debug)] +struct FallbackToConstRef; impl<'tcx> ConstToPat<'tcx> { fn new( @@ -236,13 +228,13 @@ impl<'tcx> ConstToPat<'tcx> { let kind = match cv.ty().kind() { ty::Float(_) => { - tcx.emit_spanned_lint( - lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, - id, - span, - FloatPattern, - ); - PatKind::Constant { value: cv } + tcx.emit_spanned_lint( + lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, + id, + span, + FloatPattern, + ); + return Err(FallbackToConstRef); } ty::Adt(adt_def, _) if adt_def.is_union() => { // Matching on union fields is unsafe, we can't hide it in constants @@ -289,7 +281,7 @@ impl<'tcx> ConstToPat<'tcx> { // Since we are behind a reference, we can just bubble the error up so we get a // constant at reference type, making it easy to let the fallback call // `PartialEq::eq` on it. - return Err(fallback_to_const_ref(self)); + return Err(FallbackToConstRef); } ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty()) => { debug!( @@ -393,11 +385,11 @@ impl<'tcx> ConstToPat<'tcx> { self.behind_reference.set(old); val } - // Backwards compatibility hack: support references to non-structural types. - // We'll lower - // this pattern to a `PartialEq::eq` comparison and `PartialEq::eq` takes a - // reference. This makes the rest of the matching logic simpler as it doesn't have - // to figure out how to get a reference again. + // Backwards compatibility hack: support references to non-structural types, + // but hard error if we aren't behind a double reference. We could just use + // the fallback code path below, but that would allow *more* of this fishy + // code to compile, as then it only goes through the future incompat lint + // instead of a hard error. ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { if self.behind_reference.get() { if !self.saw_const_match_error.get() @@ -411,7 +403,7 @@ impl<'tcx> ConstToPat<'tcx> { IndirectStructuralMatch { non_sm_ty: *pointee_ty }, ); } - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } else { if !self.saw_const_match_error.get() { self.saw_const_match_error.set(true); @@ -435,16 +427,9 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Wild } else { let old = self.behind_reference.replace(true); - // In case there are structural-match violations somewhere in this subpattern, - // we fall back to a const pattern. If we do not do this, we may end up with - // a !structural-match constant that is not of reference type, which makes it - // very hard to invoke `PartialEq::eq` on it as a fallback. - let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) { - Ok(subpattern) => PatKind::Deref { subpattern }, - Err(_) => PatKind::Constant { value: cv }, - }; + let subpattern = self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false)?; self.behind_reference.set(old); - val + PatKind::Deref { subpattern } } } }, @@ -452,7 +437,7 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Constant { value: cv } } ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => { - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } // FIXME: these can have very surprising behaviour where optimization levels or other // compilation choices change the runtime behaviour of the match. @@ -469,7 +454,7 @@ impl<'tcx> ConstToPat<'tcx> { PointerPattern ); } - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } _ => { self.saw_const_match_error.set(true); diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 9af13781312..6a77146138b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -844,8 +844,8 @@ impl<'tcx> Constructor<'tcx> { } /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is - /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is - /// assumed to have been split from a wildcard. + /// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out, + /// and `self` is assumed to have been split from a wildcard. fn is_covered_by_any<'p>( &self, pcx: &PatCtxt<'_, 'p, 'tcx>, @@ -894,7 +894,7 @@ impl<'tcx> Constructor<'tcx> { /// in `to_ctors`: in some cases we only return `Missing`. #[derive(Debug)] pub(super) struct SplitWildcard<'tcx> { - /// Constructors seen in the matrix. + /// Constructors (other than wildcards and opaques) seen in the matrix. matrix_ctors: Vec<Constructor<'tcx>>, /// All the constructors for this type all_ctors: SmallVec<[Constructor<'tcx>; 1]>, @@ -1037,7 +1037,7 @@ impl<'tcx> SplitWildcard<'tcx> { // Since `all_ctors` never contains wildcards, this won't recurse further. self.all_ctors = self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect(); - self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect(); + self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect(); } /// Whether there are any value constructors for this type that are not present in the matrix. diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index f229b10c447..e5b63506906 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -288,6 +288,22 @@ //! //! The details are not necessary to understand this file, so we explain them in //! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function. +//! +//! # Constants in patterns +//! +//! There are two kinds of constants in patterns: +//! +//! * literals (`1`, `true`, `"foo"`) +//! * named or inline consts (`FOO`, `const { 5 + 6 }`) +//! +//! The latter are converted into other patterns with literals at the leaves. For example +//! `const_to_pat(const { [1, 2, 3] })` becomes an `Array(vec![Const(1), Const(2), Const(3)])` +//! pattern. This gets problematic when comparing the constant via `==` would behave differently +//! from matching on the constant converted to a pattern. Situations like that can occur, when +//! the user implements `PartialEq` manually, and thus could make `==` behave arbitrarily different. +//! In order to honor the `==` implementation, constants of types that implement `PartialEq` manually +//! stay as a full constant and become an `Opaque` pattern. These `Opaque` patterns do not participate +//! in exhaustiveness, specialization or overlap checking. use self::ArmType::*; use self::Usefulness::*; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index bdb4f20da10..069514d8a3b 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -7,7 +7,7 @@ use rustc_hir::intravisit; use rustc_hir::{BlockCheckMode, ExprKind, Node}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index bf01b45eb40..74b4b4a07c5 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -2,7 +2,7 @@ use super::*; use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, Body, Coverage, CoverageInfo}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::DefId; diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index 8ee08c5be34..a133c9d4782 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -8,7 +8,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; -use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE}; +use rustc_middle::mir::{Body, Location, Operand, Place, Terminator, TerminatorKind, RETURN_PLACE}; use rustc_middle::ty::{self, DeducedParamAttrs, Ty, TyCtxt}; use rustc_session::config::OptLevel; @@ -29,31 +29,31 @@ impl DeduceReadOnly { } impl<'tcx> Visitor<'tcx> for DeduceReadOnly { - fn visit_local(&mut self, local: Local, mut context: PlaceContext, _: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { // We're only interested in arguments. - if local == RETURN_PLACE || local.index() > self.mutable_args.domain_size() { + if place.local == RETURN_PLACE || place.local.index() > self.mutable_args.domain_size() { return; } - // Replace place contexts that are moves with copies. This is safe in all cases except - // function argument position, which we already handled in `visit_terminator()` by using the - // ArgumentChecker. See the comment in that method for more details. - // - // In the future, we might want to move this out into a separate pass, but for now let's - // just do it on the fly because that's faster. - if matches!(context, PlaceContext::NonMutatingUse(NonMutatingUseContext::Move)) { - context = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy); - } - - match context { - PlaceContext::MutatingUse(..) - | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => { + let mark_as_mutable = match context { + PlaceContext::MutatingUse(..) => { // This is a mutation, so mark it as such. - self.mutable_args.insert(local.index() - 1); + true + } + PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) => { + // Whether mutating though a `&raw const` is allowed is still undecided, so we + // disable any sketchy `readonly` optimizations for now. + // But we only need to do this if the pointer would point into the argument. + !place.is_indirect() } PlaceContext::NonMutatingUse(..) | PlaceContext::NonUse(..) => { // Not mutating, so it's fine. + false } + }; + + if mark_as_mutable { + self.mutable_args.insert(place.local.index() - 1); } } diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index ac1de989a72..58cc161ddcc 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -1,8 +1,8 @@ use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE}; use rustc_middle::mir::*; use rustc_middle::query::LocalCrate; +use rustc_middle::query::Providers; use rustc_middle::ty::layout; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::FFI_UNWIND_CALLS; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index c9144729145..891e446942e 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1397,7 +1397,7 @@ fn create_cases<'tcx>( pub(crate) fn mir_generator_witnesses<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> GeneratorLayout<'tcx> { +) -> Option<GeneratorLayout<'tcx>> { assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir); let (body, _) = tcx.mir_promoted(def_id); @@ -1410,6 +1410,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( // Get the interior types and substs which typeck computed let movable = match *gen_ty.kind() { ty::Generator(_, _, movability) => movability == hir::Movability::Movable, + ty::Error(_) => return None, _ => span_bug!(body.span, "unexpected generator type {}", gen_ty), }; @@ -1425,7 +1426,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( check_suspend_tys(tcx, &generator_layout, &body); - generator_layout + Some(generator_layout) } impl<'tcx> MirPass<'tcx> for StateTransform { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 277237a5515..65864dc016f 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -34,7 +34,7 @@ use rustc_middle::mir::{ MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK, }; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index d1bc9ee9153..bbd9f76ba5c 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -77,11 +77,11 @@ impl<'tcx> MirPass<'tcx> for ReferencePropagation { #[instrument(level = "trace", skip(self, tcx, body))] fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!(def_id = ?body.source.def_id()); - propagate_ssa(tcx, body); + while propagate_ssa(tcx, body) {} } } -fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { let ssa = SsaLocals::new(body); let mut replacer = compute_replacement(tcx, body, &ssa); @@ -94,6 +94,8 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { if replacer.any_replacement { crate::simplify::remove_unused_definitions(body); } + + replacer.any_replacement } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -263,6 +265,7 @@ fn compute_replacement<'tcx>( targets, storage_to_remove, allowed_replacements, + fully_replacable_locals, any_replacement: false, }; @@ -343,6 +346,7 @@ struct Replacer<'tcx> { storage_to_remove: BitSet<Local>, allowed_replacements: FxHashSet<(Local, Location)>, any_replacement: bool, + fully_replacable_locals: BitSet<Local>, } impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { @@ -350,6 +354,25 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { self.tcx } + fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) { + if let VarDebugInfoContents::Place(ref mut place) = debuginfo.value + && place.projection.is_empty() + && let Value::Pointer(target, _) = self.targets[place.local] + && target.projection.iter().all(|p| p.can_use_in_debuginfo()) + { + if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() { + *place = Place::from(target.local).project_deeper(rest, self.tcx); + self.any_replacement = true; + } else if self.fully_replacable_locals.contains(place.local) + && let Some(references) = debuginfo.references.checked_add(1) + { + debuginfo.references = references; + *place = target; + self.any_replacement = true; + } + } + } + fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) { if place.projection.first() != Some(&PlaceElem::Deref) { return; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 19d07fab0b9..7c47d8814db 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 7253acf61e6..1c18e6b0b02 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -12,9 +12,10 @@ extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; use rustc_hir::lang_items::LangItem; +use rustc_middle::query::Providers; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::query::{Providers, TyCtxtAt}; +use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::{self, Ty}; mod collector; diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 993e35c7fd2..c10180ee3f4 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -106,8 +106,8 @@ use rustc_hir::def_id::{DefIdSet, LOCAL_CRATE}; use rustc_middle::mir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{CodegenUnit, Linkage}; +use rustc_middle::query::Providers; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index ddc62d9c390..88a3e028527 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -11,9 +11,9 @@ use rustc_middle::mir::{ visit::{TyContext, Visitor}, Constant, ConstantKind, Local, LocalDecl, Location, }; +use rustc_middle::query::Providers; use rustc_middle::ty::{ self, - query::Providers, subst::SubstsRef, visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}, Const, Ty, TyCtxt, UnusedGenericParams, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 1bbf833e3cd..2d0f466e236 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -478,6 +478,11 @@ parse_missing_for_in_trait_impl = missing `for` in a trait impl parse_expected_trait_in_trait_impl_found_type = expected a trait, found type +parse_extra_impl_keyword_in_trait_impl = unexpected `impl` keyword + .suggestion = remove the extra `impl` + .note = this is parsed as an `impl Trait` type, but a trait is expected at this position + + parse_non_item_in_item_list = non-item in item list .suggestion_use_const_not_let = consider using `const` instead of `let` for associated const .label_list_start = item list starts here diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index b6aeaf3d59f..84494eab855 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1520,6 +1520,16 @@ pub(crate) struct ExpectedTraitInTraitImplFoundType { } #[derive(Diagnostic)] +#[diag(parse_extra_impl_keyword_in_trait_impl)] +pub(crate) struct ExtraImplKeywordInTraitImpl { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub extra_impl_kw: Span, + #[note] + pub impl_trait_span: Span, +} + +#[derive(Diagnostic)] #[diag(parse_bounds_not_allowed_on_trait_aliases)] pub(crate) struct BoundsNotAllowedOnTraitAliases { #[primary_span] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 887e155426f..ee712a8e1b5 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1180,6 +1180,10 @@ impl<'a> Parser<'a> { self.restore_snapshot(snapshot); let close_paren = self.prev_token.span; let span = lo.to(close_paren); + // filter shorthand fields + let fields: Vec<_> = + fields.into_iter().filter(|field| !field.is_shorthand).collect(); + if !fields.is_empty() && // `token.kind` should not be compared here. // This is because the `snapshot.token.kind` is treated as the same as diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index e6d0f9fbc76..cd779b0b43e 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -453,6 +453,8 @@ impl<'a> Parser<'a> { // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `=` - generic parameter with a default // `<` const - generic const parameter + // `<` IDENT `?` - RECOVERY for `impl<T ?Bound` missing a `:`, meant to + // avoid the `T?` to `Option<T>` recovery for types. // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) @@ -463,6 +465,9 @@ impl<'a> Parser<'a> { || self.look_ahead(start + 1, |t| t.is_lifetime() || t.is_ident()) && self.look_ahead(start + 2, |t| { matches!(t.kind, token::Gt | token::Comma | token::Colon | token::Eq) + // Recovery-only branch -- this could be removed, + // since it only affects diagnostics currently. + || matches!(t.kind, token::Question) }) || self.is_keyword_ahead(start + 1, &[kw::Const])) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 840cfe90899..dc18d400f1e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -603,10 +603,24 @@ impl<'a> Parser<'a> { let path = match ty_first.kind { // This notably includes paths passed through `ty` macro fragments (#46438). TyKind::Path(None, path) => path, - _ => { - self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType { - span: ty_first.span, - }); + other => { + if let TyKind::ImplTrait(_, bounds) = other + && let [bound] = bounds.as_slice() + { + // Suggest removing extra `impl` keyword: + // `impl<T: Default> impl Default for Wrapper<T>` + // ^^^^^ + let extra_impl_kw = ty_first.span.until(bound.span()); + self.sess + .emit_err(errors::ExtraImplKeywordInTraitImpl { + extra_impl_kw, + impl_trait_span: ty_first.span + }); + } else { + self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType { + span: ty_first.span, + }); + } err_path(ty_first.span) } }; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 06aa2737915..455d7b89f9c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -19,9 +19,9 @@ use rustc_hir::{ use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; +use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 6742722ce52..2357b0aadef 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::parse::feature_err; use rustc_span::{sym, Span, Symbol}; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 3ae5b45d330..7812dcde44c 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -12,7 +12,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Node, PatKind, TyKind}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::privacy::Level; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 72371b9950b..8ea95b3f383 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -6,8 +6,8 @@ use rustc_data_structures::sync::Lrc; use rustc_expand::base::resolve_path; use rustc_hir as hir; use rustc_hir::HirId; +use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::TyCtxt; -use rustc_middle::{query::LocalCrate, ty::query::Providers}; use rustc_span::{sym, DebuggerVisualizerFile, DebuggerVisualizerType}; use crate::errors::DebugVisualizerUnreadable; diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index eb6ea673c85..d8b9f4fae87 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -13,7 +13,7 @@ use rustc_ast as ast; use rustc_hir::diagnostic_items::DiagnosticItems; use rustc_hir::OwnerId; use rustc_middle::query::LocalCrate; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index e3e4b73efa3..ffd8f77b78b 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -4,7 +4,7 @@ use rustc_errors::error_code; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{ItemId, Node, CRATE_HIR_ID}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::{sigpipe, CrateType, EntryFnType}; use rustc_session::parse::feature_err; diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index fdd0e5dab70..476394f30cc 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::cstore::ExternCrate; use rustc_span::{symbol::kw::Empty, Span}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; pub(crate) enum Duplicate { Plain, diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 8b7338e29aa..0da4b294648 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -22,7 +22,7 @@ extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; mod check_attr; mod check_const; diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index f4da1aaec11..44174b1b89d 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -9,7 +9,7 @@ use rustc_attr::{rust_version_symbol, VERSION_PLACEHOLDER}; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; use rustc_middle::middle::lib_features::LibFeatures; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; use rustc_span::{sym, Span}; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6758024419d..63b1578d43f 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -94,7 +94,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet}; use rustc_index::IndexVec; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index b4cf19e4a34..73cfe68e7f2 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -6,7 +6,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Movability, Node}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::hygiene::DesugaringKind; diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index cf8d9300a11..a849d61edfe 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -6,7 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::Visitor; use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; use rustc_span::symbol::sym; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index a5f7b07fe52..160528e4074 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -13,7 +13,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::privacy::{self, Level}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::CrateType; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 9615f283ff4..f9060328f48 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -16,7 +16,8 @@ use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index}; -use rustc_middle::ty::{query::Providers, TyCtxt}; +use rustc_middle::query::Providers; +use rustc_middle::ty::TyCtxt; use rustc_session::lint; use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED}; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 605cf0a93b8..d87df706cc8 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self, HirId}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::Span; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d6eb5463870..7b39cb0a068 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -25,9 +25,9 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; -use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; +use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; +use rustc_middle::query::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Const, GenericParamDefKind}; use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; @@ -38,7 +38,7 @@ use rustc_span::Span; use std::marker::PhantomData; use std::ops::ControlFlow; -use std::{cmp, fmt, mem}; +use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, @@ -408,8 +408,9 @@ impl VisibilityLike for ty::Visibility { min(find.tcx.local_visibility(def_id), find.min, find.tcx) } } -impl VisibilityLike for Option<Level> { - const MAX: Self = Some(Level::Direct); + +impl VisibilityLike for Option<EffectiveVisibility> { + const MAX: Self = Some(EffectiveVisibility::from_vis(ty::Visibility::Public)); // Type inference is very smart sometimes. // It can make an impl reachable even some components of its type or trait are unreachable. // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }` @@ -421,7 +422,13 @@ impl VisibilityLike for Option<Level> { // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { - cmp::min(find.effective_visibilities.public_at_level(def_id), find.min) + if let Some(min) = find.min { + return find + .effective_visibilities + .effective_vis(def_id) + .map(|eff_vis| min.min(*eff_vis, find.tcx)); + } + None } } @@ -447,49 +454,79 @@ struct EmbargoVisitor<'tcx> { /// n::p::f() /// } macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>, - /// Previous visibility level; `None` means unreachable. - prev_level: Option<Level>, /// Has something changed in the level map? changed: bool, } struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> { - level: Option<Level>, + effective_vis: Option<EffectiveVisibility>, item_def_id: LocalDefId, ev: &'a mut EmbargoVisitor<'tcx>, + level: Level, } impl<'tcx> EmbargoVisitor<'tcx> { - fn get(&self, def_id: LocalDefId) -> Option<Level> { - self.effective_visibilities.public_at_level(def_id) - } - - /// Updates node level and returns the updated level. - fn update(&mut self, def_id: LocalDefId, level: Option<Level>) -> Option<Level> { - let old_level = self.get(def_id); - // Visibility levels can only grow. - if level > old_level { - self.effective_visibilities.set_public_at_level( - def_id, - || ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)), - level.unwrap(), - ); - self.changed = true; - level - } else { - old_level + fn get(&self, def_id: LocalDefId) -> Option<EffectiveVisibility> { + self.effective_visibilities.effective_vis(def_id).copied() + } + + // Updates node effective visibility. + fn update( + &mut self, + def_id: LocalDefId, + inherited_effective_vis: Option<EffectiveVisibility>, + level: Level, + ) { + let nominal_vis = self.tcx.local_visibility(def_id); + self.update_eff_vis(def_id, inherited_effective_vis, Some(nominal_vis), level); + } + + fn update_eff_vis( + &mut self, + def_id: LocalDefId, + inherited_effective_vis: Option<EffectiveVisibility>, + nominal_vis: Option<ty::Visibility>, + level: Level, + ) { + if let Some(inherited_effective_vis) = inherited_effective_vis { + let private_vis = + ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)); + if Some(private_vis) != nominal_vis { + self.changed |= self.effective_visibilities.update( + def_id, + nominal_vis, + || private_vis, + inherited_effective_vis, + level, + self.tcx, + ); + } } } fn reach( &mut self, def_id: LocalDefId, - level: Option<Level>, + effective_vis: Option<EffectiveVisibility>, ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { ReachEverythingInTheInterfaceVisitor { - level: cmp::min(level, Some(Level::Reachable)), + effective_vis, item_def_id: def_id, ev: self, + level: Level::Reachable, + } + } + + fn reach_through_impl_trait( + &mut self, + def_id: LocalDefId, + effective_vis: Option<EffectiveVisibility>, + ) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { + ReachEverythingInTheInterfaceVisitor { + effective_vis, + item_def_id: def_id, + ev: self, + level: Level::ReachableThroughImplTrait, } } @@ -510,16 +547,18 @@ impl<'tcx> EmbargoVisitor<'tcx> { return; } - if self.get(local_def_id).is_none() { + if self.effective_visibilities.public_at_level(local_def_id).is_none() { return; } // Since we are starting from an externally visible module, // all the parents in the loop below are also guaranteed to be modules. let mut module_def_id = macro_module_def_id; + let macro_ev = self.get(local_def_id); + assert!(macro_ev.is_some()); loop { let changed_reachability = - self.update_macro_reachable(module_def_id, macro_module_def_id); + self.update_macro_reachable(module_def_id, macro_module_def_id, macro_ev); if changed_reachability || module_def_id == CRATE_DEF_ID { break; } @@ -533,21 +572,33 @@ impl<'tcx> EmbargoVisitor<'tcx> { &mut self, module_def_id: LocalDefId, defining_mod: LocalDefId, + macro_ev: Option<EffectiveVisibility>, ) -> bool { if self.macro_reachable.insert((module_def_id, defining_mod)) { - self.update_macro_reachable_mod(module_def_id, defining_mod); + self.update_macro_reachable_mod(module_def_id, defining_mod, macro_ev); true } else { false } } - fn update_macro_reachable_mod(&mut self, module_def_id: LocalDefId, defining_mod: LocalDefId) { + fn update_macro_reachable_mod( + &mut self, + module_def_id: LocalDefId, + defining_mod: LocalDefId, + macro_ev: Option<EffectiveVisibility>, + ) { let module = self.tcx.hir().get_module(module_def_id).0; for item_id in module.item_ids { let def_kind = self.tcx.def_kind(item_id.owner_id); let vis = self.tcx.local_visibility(item_id.owner_id.def_id); - self.update_macro_reachable_def(item_id.owner_id.def_id, def_kind, vis, defining_mod); + self.update_macro_reachable_def( + item_id.owner_id.def_id, + def_kind, + vis, + defining_mod, + macro_ev, + ); } for child in self.tcx.module_children_local(module_def_id) { // FIXME: Use module children for the logic above too. @@ -556,7 +607,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { && let Res::Def(def_kind, def_id) = child.res && let Some(def_id) = def_id.as_local() { let vis = self.tcx.local_visibility(def_id); - self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod); + self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod, macro_ev); } } } @@ -567,16 +618,14 @@ impl<'tcx> EmbargoVisitor<'tcx> { def_kind: DefKind, vis: ty::Visibility, module: LocalDefId, + macro_ev: Option<EffectiveVisibility>, ) { - let level = Some(Level::Reachable); - if vis.is_public() { - self.update(def_id, level); - } + self.update(def_id, macro_ev, Level::Reachable); match def_kind { // No type privacy, so can be directly marked as reachable. DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => { if vis.is_accessible_from(module, self.tcx) { - self.update(def_id, level); + self.update(def_id, macro_ev, Level::Reachable); } } @@ -588,7 +637,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { let item = self.tcx.hir().expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { - self.update(def_id, level); + self.update(def_id, macro_ev, Level::Reachable); } } } @@ -599,26 +648,24 @@ impl<'tcx> EmbargoVisitor<'tcx> { // the module, however may be reachable. DefKind::Mod => { if vis.is_accessible_from(module, self.tcx) { - self.update_macro_reachable(def_id, module); + self.update_macro_reachable(def_id, module, macro_ev); } } DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. - if vis.is_public() { - let item = self.tcx.hir().expect_item(def_id); - if let hir::ItemKind::Struct(ref struct_def, _) - | hir::ItemKind::Union(ref struct_def, _) = item.kind - { - for field in struct_def.fields() { - let field_vis = self.tcx.local_visibility(field.def_id); - if field_vis.is_accessible_from(module, self.tcx) { - self.reach(field.def_id, level).ty(); - } + let item = self.tcx.hir().expect_item(def_id); + if let hir::ItemKind::Struct(ref struct_def, _) + | hir::ItemKind::Union(ref struct_def, _) = item.kind + { + for field in struct_def.fields() { + let field_vis = self.tcx.local_visibility(field.def_id); + if field_vis.is_accessible_from(module, self.tcx) { + self.reach(field.def_id, macro_ev).ty(); } - } else { - bug!("item {:?} with DefKind {:?}", item, def_kind); } + } else { + bug!("item {:?} with DefKind {:?}", item, def_kind); } } @@ -662,14 +709,16 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let item_level = match item.kind { + let item_ev = match item.kind { hir::ItemKind::Impl { .. } => { - let impl_level = Option::<Level>::of_impl( + let impl_ev = Option::<EffectiveVisibility>::of_impl( item.owner_id.def_id, self.tcx, &self.effective_visibilities, ); - self.update(item.owner_id.def_id, impl_level) + + self.update_eff_vis(item.owner_id.def_id, impl_ev, None, Level::Direct); + impl_ev } _ => self.get(item.owner_id.def_id), }; @@ -678,38 +727,35 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { match item.kind { hir::ItemKind::Enum(ref def, _) => { for variant in def.variants { - let variant_level = self.update(variant.def_id, item_level); + self.update(variant.def_id, item_ev, Level::Reachable); + let variant_ev = self.get(variant.def_id); if let Some(ctor_def_id) = variant.data.ctor_def_id() { - self.update(ctor_def_id, item_level); + self.update(ctor_def_id, variant_ev, Level::Reachable); } for field in variant.data.fields() { - self.update(field.def_id, variant_level); + self.update(field.def_id, variant_ev, Level::Reachable); } } } hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { - if impl_.of_trait.is_some() - || self.tcx.visibility(impl_item_ref.id.owner_id).is_public() - { - self.update(impl_item_ref.id.owner_id.def_id, item_level); - } + let def_id = impl_item_ref.id.owner_id.def_id; + let nominal_vis = + impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id)); + self.update_eff_vis(def_id, item_ev, nominal_vis, Level::Direct); } } hir::ItemKind::Trait(.., trait_item_refs) => { for trait_item_ref in trait_item_refs { - self.update(trait_item_ref.id.owner_id.def_id, item_level); + self.update(trait_item_ref.id.owner_id.def_id, item_ev, Level::Reachable); } } hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { if let Some(ctor_def_id) = def.ctor_def_id() { - self.update(ctor_def_id, item_level); + self.update(ctor_def_id, item_ev, Level::Reachable); } for field in def.fields() { - let vis = self.tcx.visibility(field.def_id); - if vis.is_public() { - self.update(field.def_id, item_level); - } + self.update(field.def_id, item_ev, Level::Reachable); } } hir::ItemKind::Macro(ref macro_def, _) => { @@ -717,9 +763,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - if self.tcx.visibility(foreign_item.id.owner_id).is_public() { - self.update(foreign_item.id.owner_id.def_id, item_level); - } + self.update(foreign_item.id.owner_id.def_id, item_ev, Level::Reachable); } } @@ -754,8 +798,11 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // FIXME: This is some serious pessimization intended to workaround deficiencies // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // reachable if they are returned via `impl Trait`, even from private functions. - let exist_level = cmp::max(item_level, Some(Level::ReachableThroughImplTrait)); - self.reach(item.owner_id.def_id, exist_level).generics().predicates().ty(); + let exist_ev = Some(EffectiveVisibility::from_vis(ty::Visibility::Public)); + self.reach_through_impl_trait(item.owner_id.def_id, exist_ev) + .generics() + .predicates() + .ty(); } } // Visit everything. @@ -763,17 +810,18 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Fn(..) | hir::ItemKind::TyAlias(..) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates().ty(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty(); } } hir::ItemKind::Trait(.., trait_item_refs) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for trait_item_ref in trait_item_refs { let tcx = self.tcx; - let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_level); + let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev); + reach.generics().predicates(); if trait_item_ref.kind == AssocItemKind::Type @@ -787,23 +835,24 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } hir::ItemKind::TraitAlias(..) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); } } // Visit everything except for private impl items. hir::ItemKind::Impl(ref impl_) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level) + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev) .generics() .predicates() .ty() .trait_ref(); for impl_item_ref in impl_.items { - let impl_item_level = self.get(impl_item_ref.id.owner_id.def_id); - if impl_item_level.is_some() { - self.reach(impl_item_ref.id.owner_id.def_id, impl_item_level) + let impl_item_ev = self.get(impl_item_ref.id.owner_id.def_id); + + if impl_item_ev.is_some() { + self.reach(impl_item_ref.id.owner_id.def_id, impl_item_ev) .generics() .predicates() .ty(); @@ -814,23 +863,23 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything, but enum variants have their own levels. hir::ItemKind::Enum(ref def, _) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); } for variant in def.variants { - let variant_level = self.get(variant.def_id); - if variant_level.is_some() { + let variant_ev = self.get(variant.def_id); + if variant_ev.is_some() { for field in variant.data.fields() { - self.reach(field.def_id, variant_level).ty(); + self.reach(field.def_id, variant_ev).ty(); } // Corner case: if the variant is reachable, but its // enum is not, make the enum reachable as well. - self.reach(item.owner_id.def_id, variant_level).ty(); + self.reach(item.owner_id.def_id, variant_ev).ty(); } if let Some(ctor_def_id) = variant.data.ctor_def_id() { - let ctor_level = self.get(ctor_def_id); - if ctor_level.is_some() { - self.reach(item.owner_id.def_id, ctor_level).ty(); + let ctor_ev = self.get(ctor_def_id); + if ctor_ev.is_some() { + self.reach(item.owner_id.def_id, ctor_ev).ty(); } } } @@ -838,9 +887,9 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // Visit everything, but foreign items have their own levels. hir::ItemKind::ForeignMod { items, .. } => { for foreign_item in items { - let foreign_item_level = self.get(foreign_item.id.owner_id.def_id); - if foreign_item_level.is_some() { - self.reach(foreign_item.id.owner_id.def_id, foreign_item_level) + let foreign_item_ev = self.get(foreign_item.id.owner_id.def_id); + if foreign_item_ev.is_some() { + self.reach(foreign_item.id.owner_id.def_id, foreign_item_ev) .generics() .predicates() .ty(); @@ -849,36 +898,32 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Visit everything except for private fields. hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { - if item_level.is_some() { - self.reach(item.owner_id.def_id, item_level).generics().predicates(); + if item_ev.is_some() { + self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for field in struct_def.fields() { - let field_level = self.get(field.def_id); - if field_level.is_some() { - self.reach(field.def_id, field_level).ty(); + let field_ev = self.get(field.def_id); + if field_ev.is_some() { + self.reach(field.def_id, field_ev).ty(); } } } if let Some(ctor_def_id) = struct_def.ctor_def_id() { - let ctor_level = self.get(ctor_def_id); - if ctor_level.is_some() { - self.reach(item.owner_id.def_id, ctor_level).ty(); + let ctor_ev = self.get(ctor_def_id); + if ctor_ev.is_some() { + self.reach(item.owner_id.def_id, ctor_ev).ty(); } } } } - let orig_level = mem::replace(&mut self.prev_level, item_level); intravisit::walk_item(self, item); - self.prev_level = orig_level; } fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) { // Blocks can have public items, for example impls, but they always // start as completely private regardless of publicity of a function, // constant, type, field, etc., in which this block resides. - let orig_level = mem::replace(&mut self.prev_level, None); intravisit::walk_block(self, b); - self.prev_level = orig_level; } } @@ -932,11 +977,7 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> _descr: &dyn fmt::Display, ) -> ControlFlow<Self::BreakTy> { if let Some(def_id) = def_id.as_local() { - if let (ty::Visibility::Public, _) | (_, Some(Level::ReachableThroughImplTrait)) = - (self.tcx().visibility(def_id.to_def_id()), self.level) - { - self.ev.update(def_id, self.level); - } + self.ev.update_eff_vis(def_id, self.effective_vis, None, self.level); } ControlFlow::Continue(()) } @@ -2164,7 +2205,6 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { tcx, effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(), macro_reachable: Default::default(), - prev_level: Some(Level::Direct), changed: false, }; diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index b107a3f03fe..e596993465c 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" [dependencies] +memoffset = { version = "0.6.0", features = ["unstable_const"] } +field-offset = "0.3.5" measureme = "10.0.0" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 82b335f4b4b..5ca102a0946 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -3,11 +3,12 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] // this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref #![feature(const_mut_refs)] +#![feature(const_refs_to_cell)] #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] +#![allow(rustc::potential_query_instability, unused_parens)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -15,16 +16,27 @@ extern crate rustc_middle; use crate::plumbing::{encode_all_query_results, try_mark_green}; +use field_offset::offset_of; +use rustc_data_structures::stable_hasher::HashStable; +use rustc_data_structures::sync::AtomicU64; use rustc_middle::arena::Arena; +use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::dep_graph::{self, DepKind, DepKindStruct}; use rustc_middle::query::erase::{erase, restore, Erase}; +use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_middle::query::AsLocalKey; -use rustc_middle::ty::query::{ +use rustc_middle::query::{ query_keys, query_provided, query_provided_to_value, query_storage, query_values, + DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; -use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine, QuerySystemFns}; +use rustc_middle::ty::query::{DynamicQuery, QuerySystem, QuerySystemFns}; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; +use rustc_query_system::ich::StableHashingContext; +use rustc_query_system::query::{ + get_query, HashResult, QueryCache, QueryConfig, QueryInfo, QueryMap, QueryMode, QueryState, +}; +use rustc_query_system::HandleCycleError; use rustc_query_system::Value; use rustc_span::Span; @@ -32,31 +44,182 @@ use rustc_span::Span; mod plumbing; pub use crate::plumbing::QueryCtxt; -pub use rustc_query_system::query::QueryConfig; -use rustc_query_system::query::*; - mod profiling_support; pub use self::profiling_support::alloc_self_profile_query_strings; -/// This is implemented per query and restoring query values from their erased state. -trait QueryConfigRestored<'tcx>: QueryConfig<QueryCtxt<'tcx>> + Default { - type RestoredValue; +struct DynamicConfig< + 'tcx, + C: QueryCache, + const ANON: bool, + const DEPTH_LIMIT: bool, + const FEEDABLE: bool, +> { + dynamic: &'tcx DynamicQuery<'tcx, C>, +} - fn restore(value: <Self as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue; +impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Copy + for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +{ +} +impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> Clone + for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +{ + fn clone(&self) -> Self { + DynamicConfig { dynamic: self.dynamic } + } } -rustc_query_append! { define_queries! } +impl<'tcx, C: QueryCache, const ANON: bool, const DEPTH_LIMIT: bool, const FEEDABLE: bool> + QueryConfig<QueryCtxt<'tcx>> for DynamicConfig<'tcx, C, ANON, DEPTH_LIMIT, FEEDABLE> +where + for<'a> C::Key: HashStable<StableHashingContext<'a>>, +{ + type Key = C::Key; + type Value = C::Value; + type Cache = C; + + #[inline(always)] + fn name(self) -> &'static str { + self.dynamic.name + } + + #[inline(always)] + fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { + (self.dynamic.cache_on_disk)(tcx, key) + } + + #[inline(always)] + fn query_state<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key, DepKind> + where + QueryCtxt<'tcx>: 'a, + { + self.dynamic.query_state.apply(&qcx.tcx.query_system.states) + } + + #[inline(always)] + fn query_cache<'a>(self, qcx: QueryCtxt<'tcx>) -> &'a Self::Cache + where + 'tcx: 'a, + { + self.dynamic.query_cache.apply(&qcx.tcx.query_system.caches) + } + + #[inline(always)] + fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { + (self.dynamic.execute_query)(tcx, key) + } + + #[inline(always)] + fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { + (self.dynamic.compute)(qcx.tcx, key) + } + + #[inline(always)] + fn try_load_from_disk( + self, + qcx: QueryCtxt<'tcx>, + key: &Self::Key, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, + ) -> Option<Self::Value> { + if self.dynamic.can_load_from_disk { + (self.dynamic.try_load_from_disk)(qcx.tcx, key, prev_index, index) + } else { + None + } + } + + #[inline] + fn loadable_from_disk( + self, + qcx: QueryCtxt<'tcx>, + key: &Self::Key, + index: SerializedDepNodeIndex, + ) -> bool { + (self.dynamic.loadable_from_disk)(qcx.tcx, key, index) + } + + fn value_from_cycle_error( + self, + tcx: TyCtxt<'tcx>, + cycle: &[QueryInfo<DepKind>], + ) -> Self::Value { + (self.dynamic.value_from_cycle_error)(tcx, cycle) + } + + #[inline(always)] + fn format_value(self) -> fn(&Self::Value) -> String { + self.dynamic.format_value + } + + #[inline(always)] + fn anon(self) -> bool { + ANON + } + + #[inline(always)] + fn eval_always(self) -> bool { + self.dynamic.eval_always + } + + #[inline(always)] + fn depth_limit(self) -> bool { + DEPTH_LIMIT + } + + #[inline(always)] + fn feedable(self) -> bool { + FEEDABLE + } + + #[inline(always)] + fn dep_kind(self) -> DepKind { + self.dynamic.dep_kind + } + + #[inline(always)] + fn handle_cycle_error(self) -> HandleCycleError { + self.dynamic.handle_cycle_error + } + + #[inline(always)] + fn hash_result(self) -> HashResult<Self::Value> { + self.dynamic.hash_result + } +} -pub fn query_system_fns<'tcx>( +/// This is implemented per query. It allows restoring query values from their erased state +/// and constructing a QueryConfig. +trait QueryConfigRestored<'tcx> { + type RestoredValue; + type Config: QueryConfig<QueryCtxt<'tcx>>; + + fn config(tcx: TyCtxt<'tcx>) -> Self::Config; + fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) + -> Self::RestoredValue; +} + +pub fn query_system<'tcx>( local_providers: Providers, extern_providers: ExternProviders, -) -> QuerySystemFns<'tcx> { - QuerySystemFns { - engine: engine(), - local_providers, - extern_providers, - query_structs: make_dep_kind_array!(query_structs).to_vec(), - encode_query_results: encode_all_query_results, - try_mark_green: try_mark_green, + on_disk_cache: Option<OnDiskCache<'tcx>>, +) -> QuerySystem<'tcx> { + QuerySystem { + states: Default::default(), + arenas: Default::default(), + caches: Default::default(), + dynamic_queries: dynamic_queries(), + on_disk_cache, + fns: QuerySystemFns { + engine: engine(), + local_providers, + extern_providers, + query_structs: make_dep_kind_array!(query_structs).to_vec(), + encode_query_results: encode_all_query_results, + try_mark_green: try_mark_green, + }, + jobs: AtomicU64::new(1), } } + +rustc_query_append! { define_queries! } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 9f8ac7ccd0b..74924e8113e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -4,6 +4,7 @@ use crate::rustc_middle::dep_graph::DepContext; use crate::rustc_middle::ty::TyEncoder; +use crate::QueryConfigRestored; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_errors::Diagnostic; @@ -265,14 +266,14 @@ macro_rules! hash_result { } macro_rules! call_provider { - ([][$qcx:expr, $name:ident, $key:expr]) => {{ - ($qcx.query_system.fns.local_providers.$name)($qcx, $key) + ([][$tcx:expr, $name:ident, $key:expr]) => {{ + ($tcx.query_system.fns.local_providers.$name)($tcx, $key) }}; - ([(separate_provide_extern) $($rest:tt)*][$qcx:expr, $name:ident, $key:expr]) => {{ + ([(separate_provide_extern) $($rest:tt)*][$tcx:expr, $name:ident, $key:expr]) => {{ if let Some(key) = $key.as_local_key() { - ($qcx.query_system.fns.local_providers.$name)($qcx, key) + ($tcx.query_system.fns.local_providers.$name)($tcx, key) } else { - ($qcx.query_system.fns.extern_providers.$name)($qcx, $key) + ($tcx.query_system.fns.extern_providers.$name)($tcx, $key) } }}; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { @@ -341,7 +342,7 @@ pub(crate) fn create_query_frame< } pub(crate) fn encode_query_results<'a, 'tcx, Q>( - query: Q, + query: Q::Config, qcx: QueryCtxt<'tcx>, encoder: &mut CacheEncoder<'a, 'tcx>, query_result_index: &mut EncodedDepNodeIndex, @@ -392,12 +393,26 @@ pub(crate) fn loadable_from_disk<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeI pub(crate) fn try_load_from_disk<'tcx, V>( tcx: TyCtxt<'tcx>, - id: SerializedDepNodeIndex, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, ) -> Option<V> where V: for<'a> Decodable<CacheDecoder<'a, 'tcx>>, { - tcx.query_system.on_disk_cache.as_ref()?.try_load_query_result(tcx, id) + let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?; + + let prof_timer = tcx.prof.incr_cache_loading(); + + // The call to `with_query_deserialization` enforces that no new `DepNodes` + // are created during deserialization. See the docs of that method for more + // details. + let value = tcx + .dep_graph + .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index)); + + prof_timer.finish_with_query_invocation_id(index.into()); + + value } fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool @@ -434,10 +449,9 @@ where pub(crate) fn query_callback<'tcx, Q>(is_anon: bool, is_eval_always: bool) -> DepKindStruct<'tcx> where - Q: QueryConfig<QueryCtxt<'tcx>> + Default, - Q::Key: DepNodeParams<TyCtxt<'tcx>>, + Q: QueryConfigRestored<'tcx>, { - let fingerprint_style = Q::Key::fingerprint_style(); + let fingerprint_style = <Q::Config as QueryConfig<QueryCtxt<'tcx>>>::Key::fingerprint_style(); if is_anon || !fingerprint_style.reconstructible() { return DepKindStruct { @@ -453,9 +467,11 @@ where is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node| force_from_dep_node(Q::default(), tcx, dep_node)), + force_from_dep_node: Some(|tcx, dep_node| { + force_from_dep_node(Q::config(tcx), tcx, dep_node) + }), try_load_from_on_disk_cache: Some(|tcx, dep_node| { - try_load_from_on_disk_cache(Q::default(), tcx, dep_node) + try_load_from_on_disk_cache(Q::config(tcx), tcx, dep_node) }), } } @@ -491,7 +507,7 @@ macro_rules! define_queries { mode: QueryMode, ) -> Option<Erase<query_values::$name<'tcx>>> { get_query( - queries::$name::default(), + queries::$name::config(tcx), QueryCtxt::new(tcx), span, key, @@ -519,146 +535,91 @@ macro_rules! define_queries { )* } - $(impl<'tcx> QueryConfig<QueryCtxt<'tcx>> for queries::$name<'tcx> { - type Key = query_keys::$name<'tcx>; - type Value = Erase<query_values::$name<'tcx>>; - - #[inline(always)] - fn name(self) -> &'static str { - stringify!($name) - } - - #[inline] - fn format_value(self) -> fn(&Self::Value) -> String { - |value| format!("{:?}", restore::<query_values::$name<'tcx>>(*value)) - } - - #[inline] - fn cache_on_disk(self, tcx: TyCtxt<'tcx>, key: &Self::Key) -> bool { - ::rustc_middle::query::cached::$name(tcx, key) - } - - type Cache = query_storage::$name<'tcx>; - - #[inline(always)] - fn query_state<'a>(self, tcx: QueryCtxt<'tcx>) -> &'a QueryState<Self::Key, crate::dep_graph::DepKind> - where QueryCtxt<'tcx>: 'a - { - &tcx.query_system.states.$name - } - - #[inline(always)] - fn query_cache<'a>(self, tcx: QueryCtxt<'tcx>) -> &'a Self::Cache - where 'tcx:'a - { - &tcx.query_system.caches.$name - } - - fn execute_query(self, tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value { - erase(tcx.$name(key)) - } - - #[inline] - #[allow(unused_variables)] - fn compute(self, qcx: QueryCtxt<'tcx>, key: Self::Key) -> Self::Value { - query_provided_to_value::$name( - qcx.tcx, - call_provider!([$($modifiers)*][qcx.tcx, $name, key]) - ) - } + #[allow(nonstandard_style)] + mod dynamic_query { + use super::*; - #[inline] - fn try_load_from_disk( - self, - _qcx: QueryCtxt<'tcx>, - _key: &Self::Key - ) -> rustc_query_system::query::TryLoadFromDisk<QueryCtxt<'tcx>, Self::Value> { - should_ever_cache_on_disk!([$($modifiers)*] { - if ::rustc_middle::query::cached::$name(_qcx.tcx, _key) { - Some(|qcx: QueryCtxt<'tcx>, dep_node| { - let value = $crate::plumbing::try_load_from_disk::<query_provided::$name<'tcx>>( - qcx.tcx, - dep_node - ); - value.map(|value| query_provided_to_value::$name(qcx.tcx, value)) - }) - } else { - None + $( + pub(super) fn $name<'tcx>() -> DynamicQuery<'tcx, query_storage::$name<'tcx>> { + DynamicQuery { + name: stringify!($name), + eval_always: is_eval_always!([$($modifiers)*]), + dep_kind: dep_graph::DepKind::$name, + handle_cycle_error: handle_cycle_error!([$($modifiers)*]), + query_state: offset_of!(QueryStates<'tcx> => $name), + query_cache: offset_of!(QueryCaches<'tcx> => $name), + cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key), + execute_query: |tcx, key| erase(tcx.$name(key)), + compute: |tcx, key| query_provided_to_value::$name( + tcx, + call_provider!([$($modifiers)*][tcx, $name, key]) + ), + can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false), + try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] { + |tcx, key, prev_index, index| { + if ::rustc_middle::query::cached::$name(tcx, key) { + let value = $crate::plumbing::try_load_from_disk::<query_provided::$name<'tcx>>( + tcx, + prev_index, + index, + ); + value.map(|value| query_provided_to_value::$name(tcx, value)) + } else { + None + } + } + } { + |_tcx, _key, _prev_index, _index| None + }), + value_from_cycle_error: |tcx, cycle| { + let result: query_values::$name<'tcx> = Value::from_cycle_error(tcx, cycle); + erase(result) + }, + loadable_from_disk: |_tcx, _key, _index| { + should_ever_cache_on_disk!([$($modifiers)*] { + ::rustc_middle::query::cached::$name(_tcx, _key) && + $crate::plumbing::loadable_from_disk(_tcx, _index) + } { + false + }) + }, + hash_result: hash_result!([$($modifiers)*][query_values::$name<'tcx>]), + format_value: |value| format!("{:?}", restore::<query_values::$name<'tcx>>(*value)), } - } { - None - }) - } - - #[inline] - fn loadable_from_disk( - self, - _qcx: QueryCtxt<'tcx>, - _key: &Self::Key, - _index: SerializedDepNodeIndex, - ) -> bool { - should_ever_cache_on_disk!([$($modifiers)*] { - self.cache_on_disk(_qcx.tcx, _key) && - $crate::plumbing::loadable_from_disk(_qcx.tcx, _index) - } { - false - }) - } - - #[inline] - fn value_from_cycle_error( - self, - tcx: TyCtxt<'tcx>, - cycle: &[QueryInfo<DepKind>], - ) -> Self::Value { - let result: query_values::$name<'tcx> = Value::from_cycle_error(tcx, cycle); - erase(result) - } - - #[inline(always)] - fn anon(self) -> bool { - is_anon!([$($modifiers)*]) - } - - #[inline(always)] - fn eval_always(self) -> bool { - is_eval_always!([$($modifiers)*]) - } - - #[inline(always)] - fn depth_limit(self) -> bool { - depth_limit!([$($modifiers)*]) - } - - #[inline(always)] - fn feedable(self) -> bool { - feedable!([$($modifiers)*]) - } + } + )* + } - #[inline(always)] - fn dep_kind(self) -> rustc_middle::dep_graph::DepKind { - dep_graph::DepKind::$name - } + $(impl<'tcx> QueryConfigRestored<'tcx> for queries::$name<'tcx> { + type RestoredValue = query_values::$name<'tcx>; + type Config = DynamicConfig< + 'tcx, + query_storage::$name<'tcx>, + { is_anon!([$($modifiers)*]) }, + { depth_limit!([$($modifiers)*]) }, + { feedable!([$($modifiers)*]) }, + >; #[inline(always)] - fn handle_cycle_error(self) -> rustc_query_system::HandleCycleError { - handle_cycle_error!([$($modifiers)*]) + fn config(tcx: TyCtxt<'tcx>) -> Self::Config { + DynamicConfig { + dynamic: &tcx.query_system.dynamic_queries.$name, + } } #[inline(always)] - fn hash_result(self) -> rustc_query_system::query::HashResult<Self::Value> { - hash_result!([$($modifiers)*][query_values::$name<'tcx>]) + fn restore(value: <Self::Config as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue { + restore::<query_values::$name<'tcx>>(value) } })* - $(impl<'tcx> QueryConfigRestored<'tcx> for queries::$name<'tcx> { - type RestoredValue = query_values::$name<'tcx>; - - #[inline(always)] - fn restore(value: <Self as QueryConfig<QueryCtxt<'tcx>>>::Value) -> Self::RestoredValue { - restore::<query_values::$name<'tcx>>(value) + pub fn dynamic_queries<'tcx>() -> DynamicQueries<'tcx> { + DynamicQueries { + $( + $name: dynamic_query::$name(), + )* } - })* + } #[allow(nonstandard_style)] mod query_callbacks { @@ -730,6 +691,7 @@ macro_rules! define_queries { use rustc_middle::ty::query::QueryStruct; use rustc_middle::ty::query::QueryKeyStringCache; use rustc_middle::dep_graph::DepKind; + use crate::QueryConfigRestored; pub(super) const fn dummy_query_struct<'tcx>() -> QueryStruct<'tcx> { fn noop_try_collect_active_jobs(_: TyCtxt<'_>, _: &mut QueryMap<DepKind>) -> Option<()> { @@ -774,7 +736,7 @@ macro_rules! define_queries { }, encode_query_results: expand_if_cached!([$($modifiers)*], |tcx, encoder, query_result_index| $crate::plumbing::encode_query_results::<super::queries::$name<'tcx>>( - super::queries::$name::default(), + super::queries::$name::config(tcx), QueryCtxt::new(tcx), encoder, query_result_index, diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index bb9ea50a1ea..7e47d701205 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -4,6 +4,7 @@ use crate::dep_graph::{DepNode, DepNodeParams, SerializedDepNodeIndex}; use crate::error::HandleCycleError; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; +use crate::query::DepNodeIndex; use crate::query::{QueryContext, QueryInfo, QueryState}; use rustc_data_structures::fingerprint::Fingerprint; @@ -12,8 +13,6 @@ use std::hash::Hash; pub type HashResult<V> = Option<fn(&mut StableHashingContext<'_>, &V) -> Fingerprint>; -pub type TryLoadFromDisk<Qcx, V> = Option<fn(Qcx, SerializedDepNodeIndex) -> Option<V>>; - pub trait QueryConfig<Qcx: QueryContext>: Copy { fn name(self) -> &'static str; @@ -43,7 +42,13 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy { fn compute(self, tcx: Qcx, key: Self::Key) -> Self::Value; - fn try_load_from_disk(self, qcx: Qcx, idx: &Self::Key) -> TryLoadFromDisk<Qcx, Self::Value>; + fn try_load_from_disk( + self, + tcx: Qcx, + key: &Self::Key, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, + ) -> Option<Self::Value>; fn loadable_from_disk(self, qcx: Qcx, key: &Self::Key, idx: SerializedDepNodeIndex) -> bool; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index fa1f51b04da..f7619d75be7 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -12,7 +12,7 @@ pub use self::caches::{ }; mod config; -pub use self::config::{HashResult, QueryConfig, TryLoadFromDisk}; +pub use self::config::{HashResult, QueryConfig}; use crate::dep_graph::DepKind; use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 3b17c665fb7..4aaedc7a6c1 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -564,59 +564,44 @@ where // First we try to load the result from the on-disk cache. // Some things are never cached on disk. - if let Some(try_load_from_disk) = query.try_load_from_disk(qcx, &key) { - let prof_timer = qcx.dep_context().profiler().incr_cache_loading(); - - // The call to `with_query_deserialization` enforces that no new `DepNodes` - // are created during deserialization. See the docs of that method for more - // details. - let result = qcx - .dep_context() - .dep_graph() - .with_query_deserialization(|| try_load_from_disk(qcx, prev_dep_node_index)); - - prof_timer.finish_with_query_invocation_id(dep_node_index.into()); - - if let Some(result) = result { - if std::intrinsics::unlikely( - qcx.dep_context().sess().opts.unstable_opts.query_dep_graph, - ) { - dep_graph_data.mark_debug_loaded_from_disk(*dep_node) - } - - let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index); - // If `-Zincremental-verify-ich` is specified, re-hash results from - // the cache and make sure that they have the expected fingerprint. - // - // If not, we still seek to verify a subset of fingerprints loaded - // from disk. Re-hashing results is fairly expensive, so we can't - // currently afford to verify every hash. This subset should still - // give us some coverage of potential bugs though. - let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0; - if std::intrinsics::unlikely( - try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, - ) { - incremental_verify_ich( - *qcx.dep_context(), - dep_graph_data, - &result, - prev_dep_node_index, - query.hash_result(), - query.format_value(), - ); - } + if let Some(result) = query.try_load_from_disk(qcx, key, prev_dep_node_index, dep_node_index) { + if std::intrinsics::unlikely(qcx.dep_context().sess().opts.unstable_opts.query_dep_graph) { + dep_graph_data.mark_debug_loaded_from_disk(*dep_node) + } - return Some((result, dep_node_index)); + let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index); + // If `-Zincremental-verify-ich` is specified, re-hash results from + // the cache and make sure that they have the expected fingerprint. + // + // If not, we still seek to verify a subset of fingerprints loaded + // from disk. Re-hashing results is fairly expensive, so we can't + // currently afford to verify every hash. This subset should still + // give us some coverage of potential bugs though. + let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0; + if std::intrinsics::unlikely( + try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, + ) { + incremental_verify_ich( + *qcx.dep_context(), + dep_graph_data, + &result, + prev_dep_node_index, + query.hash_result(), + query.format_value(), + ); } - // We always expect to find a cached result for things that - // can be forced from `DepNode`. - debug_assert!( - !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), - "missing on-disk cache entry for reconstructible {dep_node:?}" - ); + return Some((result, dep_node_index)); } + // We always expect to find a cached result for things that + // can be forced from `DepNode`. + debug_assert!( + !query.cache_on_disk(*qcx.dep_context(), key) + || !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), + "missing on-disk cache entry for {dep_node:?}" + ); + // Sanity check for the logic in `ensure`: if the node is green and the result loadable, // we should actually be able to load it. debug_assert!( diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 87067189a77..7393bdb388a 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -199,7 +199,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { let tcx = self.r.tcx; self.changed |= self.import_effective_visibilities.update( binding, - nominal_vis, + Some(nominal_vis), || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_import(binding)), inherited_eff_vis, parent_id.level(), @@ -213,7 +213,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { let tcx = self.r.tcx; self.changed |= self.def_effective_visibilities.update( def_id, - nominal_vis, + Some(nominal_vis), || cheap_private_vis.unwrap_or_else(|| self.r.private_vis_def(def_id)), inherited_eff_vis, parent_id.level(), diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 44e277c99b9..c053ea222a0 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3543,10 +3543,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // // Similar thing, for types, happens in `report_errors` above. let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| { - if !source.is_call() { - return Some(parent_err); - } - // Before we start looking for candidates, we have to get our hands // on the type user is trying to perform invocation on; basically: // we're transforming `HashMap::new` into just `HashMap`. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index c12dc2f5d92..323b78fcd98 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -47,6 +47,7 @@ use rustc_index::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; +use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt}; use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs}; @@ -2026,6 +2027,6 @@ impl Finalize { } } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { providers.registered_tools = macros::registered_tools; } diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 6b559cb5b2f..0ffc537eee0 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,4 +1,4 @@ -use crate::leb128::{self, largest_max_leb128_len}; +use crate::leb128; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fs::File; use std::io::{self, Write}; @@ -14,6 +14,9 @@ use std::ptr; pub type FileEncodeResult = Result<usize, io::Error>; +/// The size of the buffer in `FileEncoder`. +const BUF_SIZE: usize = 8192; + /// `FileEncoder` encodes data to file via fixed-size buffer. /// /// There used to be a `MemEncoder` type that encoded all the data into a @@ -35,26 +38,12 @@ pub struct FileEncoder { impl FileEncoder { pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> { - const DEFAULT_BUF_SIZE: usize = 8192; - FileEncoder::with_capacity(path, DEFAULT_BUF_SIZE) - } - - pub fn with_capacity<P: AsRef<Path>>(path: P, capacity: usize) -> io::Result<Self> { - // Require capacity at least as large as the largest LEB128 encoding - // here, so that we don't have to check or handle this on every write. - assert!(capacity >= largest_max_leb128_len()); - - // Require capacity small enough such that some capacity checks can be - // done using guaranteed non-overflowing add rather than sub, which - // shaves an instruction off those code paths (on x86 at least). - assert!(capacity <= usize::MAX - largest_max_leb128_len()); - // Create the file for reading and writing, because some encoders do both // (e.g. the metadata encoder when -Zmeta-stats is enabled) let file = File::options().read(true).write(true).create(true).truncate(true).open(path)?; Ok(FileEncoder { - buf: Box::new_uninit_slice(capacity), + buf: Box::new_uninit_slice(BUF_SIZE), buffered: 0, flushed: 0, file, @@ -160,18 +149,10 @@ impl FileEncoder { } #[inline] - fn capacity(&self) -> usize { - self.buf.len() - } - - #[inline] fn write_one(&mut self, value: u8) { - // We ensure this during `FileEncoder` construction. - debug_assert!(self.capacity() >= 1); - let mut buffered = self.buffered; - if std::intrinsics::unlikely(buffered >= self.capacity()) { + if std::intrinsics::unlikely(buffered + 1 > BUF_SIZE) { self.flush(); buffered = 0; } @@ -187,13 +168,12 @@ impl FileEncoder { #[inline] fn write_all(&mut self, buf: &[u8]) { - let capacity = self.capacity(); let buf_len = buf.len(); - if std::intrinsics::likely(buf_len <= capacity) { + if std::intrinsics::likely(buf_len <= BUF_SIZE) { let mut buffered = self.buffered; - if std::intrinsics::unlikely(buf_len > capacity - buffered) { + if std::intrinsics::unlikely(buffered + buf_len > BUF_SIZE) { self.flush(); buffered = 0; } @@ -271,13 +251,11 @@ macro_rules! write_leb128 { fn $this_fn(&mut self, v: $int_ty) { const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); - // We ensure this during `FileEncoder` construction. - debug_assert!(self.capacity() >= MAX_ENCODED_LEN); - let mut buffered = self.buffered; - // This can't overflow. See assertion in `FileEncoder::with_capacity`. - if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > self.capacity()) { + // This can't overflow because BUF_SIZE and MAX_ENCODED_LEN are both + // quite small. + if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > BUF_SIZE) { self.flush(); buffered = 0; } diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index dd1721801f3..8089d81cc22 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -207,7 +207,7 @@ pub trait MetadataLoader: std::fmt::Debug { fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>; } -pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync; +pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync; /// A store of Rust crates, through which their metadata can be accessed. /// @@ -252,7 +252,7 @@ pub trait CrateStore: std::fmt::Debug { fn import_source_files(&self, sess: &Session, cnum: CrateNum); } -pub type CrateStoreDyn = dyn CrateStore + sync::Sync + sync::Send; +pub type CrateStoreDyn = dyn CrateStore + sync::DynSync + sync::DynSend; pub struct Untracked { pub cstore: RwLock<Box<CrateStoreDyn>>, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 7bbab34c69a..97cb734619e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -20,6 +20,7 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] #![feature(let_chains)] +#![feature(round_char_boundary)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 1294a8b8e6b..11ea5fe4ddf 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -14,7 +14,9 @@ pub use crate::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher}; -use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock}; +use rustc_data_structures::sync::{ + AtomicU32, IntoDynSyncSend, Lrc, MappedReadGuard, ReadGuard, RwLock, +}; use std::cmp; use std::hash::Hash; use std::path::{self, Path, PathBuf}; @@ -176,7 +178,7 @@ pub struct SourceMap { used_address_space: AtomicU32, files: RwLock<SourceMapFiles>, - file_loader: Box<dyn FileLoader + Sync + Send>, + file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>, // This is used to apply the file path remapping as specified via // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`. path_mapping: FilePathMapping, @@ -202,7 +204,7 @@ impl SourceMap { SourceMap { used_address_space: AtomicU32::new(0), files: Default::default(), - file_loader, + file_loader: IntoDynSyncSend(file_loader), path_mapping, hash_kind, } @@ -1017,36 +1019,19 @@ impl SourceMap { let src = local_begin.sf.external_src.borrow(); - // We need to extend the snippet to the end of the src rather than to end_index so when - // searching forwards for boundaries we've got somewhere to search. - let snippet = if let Some(ref src) = local_begin.sf.src { - &src[start_index..] + let snippet = if let Some(src) = &local_begin.sf.src { + src } else if let Some(src) = src.get_source() { - &src[start_index..] + src } else { return 1; }; - debug!("snippet=`{:?}`", snippet); - let mut target = if forwards { end_index + 1 } else { end_index - 1 }; - debug!("initial target=`{:?}`", target); - - while !snippet.is_char_boundary(target - start_index) && target < source_len { - target = if forwards { - target + 1 - } else { - match target.checked_sub(1) { - Some(target) => target, - None => { - break; - } - } - }; - debug!("target=`{:?}`", target); + if forwards { + (snippet.ceil_char_boundary(end_index + 1) - end_index) as u32 + } else { + (end_index - snippet.floor_char_boundary(end_index - 1)) as u32 } - debug!("final target=`{:?}`", target); - - if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 } } pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> { diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c97406868b6..692542da78e 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -107,7 +107,7 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_session::config::SymbolManglingVersion; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 20ce2d9416e..d3228074421 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -124,10 +124,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; if !assoc_def.item.defaultness(tcx).has_value() { - tcx.sess.delay_span_bug( + let guar = tcx.sess.delay_span_bug( tcx.def_span(assoc_def.item.def_id), "missing value for assoc item in impl", ); + let error_term = match assoc_def.item.kind { + ty::AssocKind::Const => tcx + .const_error( + tcx.type_of(goal.predicate.def_id()) + .subst(tcx, goal.predicate.projection_ty.substs), + guar, + ) + .into(), + ty::AssocKind::Type => tcx.ty_error(guar).into(), + ty::AssocKind::Fn => unreachable!(), + }; + ecx.eq(goal.param_env, goal.predicate.term, error_term) + .expect("expected goal term to be fully unconstrained"); + return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } // Getting the right substitutions here is complex, e.g. given: diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6b080a132f3..183c2401fc3 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -801,7 +801,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { span: tcx.def_span(unevaluated.def), unevaluated: unevaluated, }); - Err(ErrorHandled::Reported(reported)) + Err(ErrorHandled::Reported(reported.into())) } Err(err) => Err(err), } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 9d99d30d45c..bd1ea43a78e 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -79,7 +79,7 @@ pub fn is_const_evaluatable<'tcx>( "Missing value for constant, but no error reported?", ))) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } @@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>( Err(err) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 49b309abcda..ea17f23434b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2447,10 +2447,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && generator_did.is_local() // Try to avoid cycles. && !generator_within_in_progress_typeck + && let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did) { - let generator_info = &self.tcx.mir_generator_witnesses(generator_did); debug!(?generator_info); - 'find_source: for (variant, source_info) in generator_info.variant_fields.iter().zip(&generator_info.variant_source_info) { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 43196d1e629..2f85c32b575 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -615,7 +615,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { (Err(ErrorHandled::Reported(reported)), _) | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( CodeSelectionError(SelectionError::NotConstEvaluatable( - NotConstEvaluatable::Error(reported), + NotConstEvaluatable::Error(reported.into()), )), ), (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 38daca5377a..223cdc48f0b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -26,6 +26,7 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; +use rustc_middle::query::Providers; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeSuperVisitable}; @@ -498,10 +499,10 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI false } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { object_safety::provide(providers); vtable::provide(providers); - *providers = ty::query::Providers { + *providers = Providers { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, subst_and_check_impossible_predicates, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 06d9c10386e..c81bf6ebc2e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -16,6 +16,7 @@ use crate::traits::{self, Obligation, ObligationCause}; use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_middle::query::Providers; use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; use rustc_middle::ty::{ self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, @@ -947,7 +948,6 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>( }) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { object_safety_violations, check_is_object_safe, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { object_safety_violations, check_is_object_safe, ..*providers }; } diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index f7a3126b4aa..cc674ceee3d 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -4,6 +4,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::util::PredicateSet; use rustc_infer::traits::ImplSource; +use rustc_middle::query::Providers; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry}; @@ -379,8 +380,8 @@ pub(crate) fn count_own_vtable_entries<'tcx>( tcx.own_existential_vtable_entries(trait_ref.def_id()).len() } -pub(super) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { own_existential_vtable_entries, vtable_entries, vtable_trait_upcasting_coercion_new_vptr_slot, diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index a5ebc26a8bc..8834449c9a4 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -7,8 +7,8 @@ pub(crate) mod db; pub(crate) mod lowering; use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; +use rustc_middle::query::Providers; use rustc_middle::traits::ChalkRustInterner; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_infer::infer::canonical::{ diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index fcdffc7468b..83f6c7d07fe 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index e94c8efe69a..149dffc7e31 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -1,5 +1,5 @@ use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::source_map::DUMMY_SP; use rustc_trait_selection::traits::query::CanonicalPredicateGoal; diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index f5bba14d2fb..0c2bb863e1f 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::canonical::{self, Canonical}; use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::query::OutlivesBound; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::DUMMY_SP; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 8bea5588ae7..b0f9c57154f 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -23,7 +23,7 @@ mod type_op; pub use type_op::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause}; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; pub fn provide(p: &mut Providers) { dropck_outlives::provide(p); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 5da0f16c2bf..94c33efaeff 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -1,6 +1,6 @@ use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::query::Providers; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 36d80a06ee7..b552ba41acd 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -1,6 +1,6 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::{ diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 19622112f2a..70dc7ccec63 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_infer::traits::ObligationCauseCode; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{ParamEnvAnd, Predicate}; use rustc_middle::ty::{UserSelfTy, UserSubsts, UserType}; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 271284b2d81..442d041a8a7 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,5 +1,6 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; +use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, }; @@ -14,8 +15,8 @@ use rustc_target::spec::abi::Abi as SpecAbi; use std::iter; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; } // NOTE(eddyb) this is private to avoid using it from outside of diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 9029ba2a51a..ed574f22e61 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,11 +4,12 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, InternalSubsts, TyCtxt}; use rustc_span::symbol::kw; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub fn provide(providers: &mut Providers) { + *providers = Providers { associated_item, associated_item_def_ids, associated_items, diff --git a/compiler/rustc_ty_utils/src/common_traits.rs b/compiler/rustc_ty_utils/src/common_traits.rs index 3b1abdcb24f..51b908881eb 100644 --- a/compiler/rustc_ty_utils/src/common_traits.rs +++ b/compiler/rustc_ty_utils/src/common_traits.rs @@ -2,6 +2,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_trait_selection::traits; @@ -32,12 +33,6 @@ fn is_item_raw<'tcx>( traits::type_known_to_meet_bound_modulo_regions(&infcx, param_env, ty, trait_def_id) } -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { - is_copy_raw, - is_sized_raw, - is_freeze_raw, - is_unpin_raw, - ..*providers - }; +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { is_copy_raw, is_sized_raw, is_freeze_raw, is_unpin_raw, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 3dd1d056be2..1219bb40098 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -2,6 +2,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; +use rustc_middle::query::Providers; use rustc_middle::thir::visit; use rustc_middle::thir::visit::Visitor; use rustc_middle::ty::abstract_const::CastKind; @@ -115,9 +116,7 @@ fn recurse_build<'tcx>( let sp = node.span; match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { Ok(c) => c, - Err(LitToConstError::Reported(guar)) => { - tcx.const_error_with_guaranteed(node.ty, guar) - } + Err(LitToConstError::Reported(guar)) => tcx.const_error(node.ty, guar), Err(LitToConstError::TypeError) => { bug!("encountered type error in lit_to_const") } @@ -423,6 +422,6 @@ pub fn thir_abstract_const( Ok(Some(ty::EarlyBinder(recurse_build(tcx, body, body_id, root_span)?))) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { destructure_const, thir_abstract_const, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 5ca5d14337c..081be065864 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,8 +1,9 @@ use rustc_hir::{def::DefKind, def_id::DefId}; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { assumed_wf_types, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { assumed_wf_types, ..*providers }; } fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index eb3c21163ab..36a20c78fcc 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::query::Providers; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt}; @@ -319,6 +320,6 @@ fn resolve_associated_item<'tcx>( }) } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { resolve_instance, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { resolve_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index f7c75583f60..16cd8bc8e69 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; +use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; @@ -22,8 +23,8 @@ use crate::errors::{ }; use crate::layout_sanity_check::sanity_check_layout; -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { layout_of, ..*providers }; +pub fn provide(providers: &mut Providers) { + *providers = Providers { layout_of, ..*providers }; } #[instrument(skip(tcx, query), level = "debug")] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 8306c5ae493..55b8857ed39 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -21,7 +21,7 @@ extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; mod abi; mod assoc; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index a04f85afb9e..1f9701b9322 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; +use rustc_middle::query::Providers; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop}; use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; @@ -323,8 +324,8 @@ fn adt_significant_drop_tys( .map(|components| tcx.mk_type_list(&components)) } -pub(crate) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { needs_drop_raw, has_significant_drop_raw, adt_drop_tys, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 25ebb333bf7..4e91dd380e8 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::ErrorGuaranteed; use rustc_hir::{def::DefKind, def_id::LocalDefId}; +use rustc_middle::query::Providers; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; @@ -192,6 +193,6 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ } } -pub(super) fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { opaque_types_defined_by, ..*providers }; +pub(super) fn provide(providers: &mut Providers) { + *providers = Providers { opaque_types_defined_by, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 26d6deab883..0b5e27c2c74 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -2,7 +2,7 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index 9cb0fc10594..215acbe2c8f 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -1,5 +1,5 @@ use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::query::Providers; +use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_infer::infer::TyCtxtInferExt; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 78efcce572d..65dc3c39c6a 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; +use rustc_middle::query::Providers; use rustc_middle::ty::{ self, Binder, EarlyBinder, ImplTraitInTraitData, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, @@ -566,8 +567,8 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32 unsizing_params } -pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { +pub fn provide(providers: &mut Providers) { + *providers = Providers { asyncness, adt_sized_constraint, param_env, diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs index c9675f93f95..45a2e9023c9 100644 --- a/compiler/rustc_type_ir/src/structural_impls.rs +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -21,6 +21,7 @@ TrivialTypeTraversalImpls! { (), bool, usize, + u8, u16, u32, u64, diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 2daef82d6f1..1f8a1ecba6e 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3021,7 +3021,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { }) } - /// Returns a mutable reference to the of the element that the cursor is + /// Returns a mutable reference to the key of the element that the cursor is /// currently pointing to. /// /// This returns `None` if the cursor is currently pointing to the diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 97da6f06b70..82f30a26d41 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -646,14 +646,14 @@ impl<T, A: Allocator> Vec<T, A> { /// /// // The vector contains no items, even though it has capacity for more /// assert_eq!(vec.len(), 0); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // These are all done without reallocating... /// for i in 0..10 { /// vec.push(i); /// } /// assert_eq!(vec.len(), 10); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // ...but this may make the vector reallocate /// vec.push(11); @@ -877,7 +877,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec: Vec<i32> = Vec::with_capacity(10); /// vec.push(42); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1028,7 +1028,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to_fit(); /// assert!(vec.capacity() >= 3); /// ``` @@ -1055,7 +1055,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to(4); /// assert!(vec.capacity() >= 4); /// vec.shrink_to(0); @@ -1090,7 +1090,7 @@ impl<T, A: Allocator> Vec<T, A> { /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); /// - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// let slice = vec.into_boxed_slice(); /// assert_eq!(slice.into_vec().capacity(), 3); /// ``` diff --git a/library/core/benches/fmt.rs b/library/core/benches/fmt.rs index ff726ff7559..d1cdb12e50f 100644 --- a/library/core/benches/fmt.rs +++ b/library/core/benches/fmt.rs @@ -1,13 +1,13 @@ use std::fmt::{self, Write as FmtWrite}; use std::io::{self, Write as IoWrite}; -use test::Bencher; +use test::{black_box, Bencher}; #[bench] fn write_vec_value(bh: &mut Bencher) { bh.iter(|| { let mut mem = Vec::new(); for _ in 0..1000 { - mem.write_all("abc".as_bytes()).unwrap(); + mem.write_all(black_box("abc").as_bytes()).unwrap(); } }); } @@ -18,7 +18,7 @@ fn write_vec_ref(bh: &mut Bencher) { let mut mem = Vec::new(); let wr = &mut mem as &mut dyn io::Write; for _ in 0..1000 { - wr.write_all("abc".as_bytes()).unwrap(); + wr.write_all(black_box("abc").as_bytes()).unwrap(); } }); } @@ -29,7 +29,7 @@ fn write_vec_macro1(bh: &mut Bencher) { let mut mem = Vec::new(); let wr = &mut mem as &mut dyn io::Write; for _ in 0..1000 { - write!(wr, "abc").unwrap(); + write!(wr, "{}", black_box("abc")).unwrap(); } }); } @@ -40,7 +40,7 @@ fn write_vec_macro2(bh: &mut Bencher) { let mut mem = Vec::new(); let wr = &mut mem as &mut dyn io::Write; for _ in 0..1000 { - write!(wr, "{}", "abc").unwrap(); + write!(wr, "{}", black_box("abc")).unwrap(); } }); } @@ -51,7 +51,7 @@ fn write_vec_macro_debug(bh: &mut Bencher) { let mut mem = Vec::new(); let wr = &mut mem as &mut dyn io::Write; for _ in 0..1000 { - write!(wr, "{:?}", "☃").unwrap(); + write!(wr, "{:?}", black_box("☃")).unwrap(); } }); } @@ -61,7 +61,7 @@ fn write_str_value(bh: &mut Bencher) { bh.iter(|| { let mut mem = String::new(); for _ in 0..1000 { - mem.write_str("abc").unwrap(); + mem.write_str(black_box("abc")).unwrap(); } }); } @@ -72,7 +72,7 @@ fn write_str_ref(bh: &mut Bencher) { let mut mem = String::new(); let wr = &mut mem as &mut dyn fmt::Write; for _ in 0..1000 { - wr.write_str("abc").unwrap(); + wr.write_str(black_box("abc")).unwrap(); } }); } @@ -82,7 +82,7 @@ fn write_str_macro1(bh: &mut Bencher) { bh.iter(|| { let mut mem = String::new(); for _ in 0..1000 { - write!(mem, "abc").unwrap(); + write!(mem, "{}", black_box("abc")).unwrap(); } }); } @@ -93,7 +93,7 @@ fn write_str_macro2(bh: &mut Bencher) { let mut mem = String::new(); let wr = &mut mem as &mut dyn fmt::Write; for _ in 0..1000 { - write!(wr, "{}", "abc").unwrap(); + write!(wr, "{}", black_box("abc")).unwrap(); } }); } @@ -104,7 +104,7 @@ fn write_str_macro_debug(bh: &mut Bencher) { let mut mem = String::new(); let wr = &mut mem as &mut dyn fmt::Write; for _ in 0..1000 { - write!(wr, "{:?}", "☃").unwrap(); + write!(wr, "{:?}", black_box("☃")).unwrap(); } }); } @@ -115,7 +115,7 @@ fn write_str_macro_debug_ascii(bh: &mut Bencher) { let mut mem = String::new(); let wr = &mut mem as &mut dyn fmt::Write; for _ in 0..1000 { - write!(wr, "{:?}", "Hello, World!").unwrap(); + write!(wr, "{:?}", black_box("Hello, World!")).unwrap(); } }); } diff --git a/library/core/benches/num/dec2flt/mod.rs b/library/core/benches/num/dec2flt/mod.rs index 305baa68729..fb4a786b27e 100644 --- a/library/core/benches/num/dec2flt/mod.rs +++ b/library/core/benches/num/dec2flt/mod.rs @@ -1,57 +1,57 @@ -use test::Bencher; +use test::{black_box, Bencher}; #[bench] fn bench_0(b: &mut Bencher) { - b.iter(|| "0.0".parse::<f64>()); + b.iter(|| black_box("0.0").parse::<f64>()); } #[bench] fn bench_42(b: &mut Bencher) { - b.iter(|| "42".parse::<f64>()); + b.iter(|| black_box("42").parse::<f64>()); } #[bench] fn bench_huge_int(b: &mut Bencher) { // 2^128 - 1 - b.iter(|| "170141183460469231731687303715884105727".parse::<f64>()); + b.iter(|| black_box("170141183460469231731687303715884105727").parse::<f64>()); } #[bench] fn bench_short_decimal(b: &mut Bencher) { - b.iter(|| "1234.5678".parse::<f64>()); + b.iter(|| black_box("1234.5678").parse::<f64>()); } #[bench] fn bench_pi_long(b: &mut Bencher) { - b.iter(|| "3.14159265358979323846264338327950288".parse::<f64>()); + b.iter(|| black_box("3.14159265358979323846264338327950288").parse::<f64>()); } #[bench] fn bench_pi_short(b: &mut Bencher) { - b.iter(|| "3.141592653589793".parse::<f64>()) + b.iter(|| black_box("3.141592653589793").parse::<f64>()) } #[bench] fn bench_1e150(b: &mut Bencher) { - b.iter(|| "1e150".parse::<f64>()); + b.iter(|| black_box("1e150").parse::<f64>()); } #[bench] fn bench_long_decimal_and_exp(b: &mut Bencher) { - b.iter(|| "727501488517303786137132964064381141071e-123".parse::<f64>()); + b.iter(|| black_box("727501488517303786137132964064381141071e-123").parse::<f64>()); } #[bench] fn bench_min_subnormal(b: &mut Bencher) { - b.iter(|| "5e-324".parse::<f64>()); + b.iter(|| black_box("5e-324").parse::<f64>()); } #[bench] fn bench_min_normal(b: &mut Bencher) { - b.iter(|| "2.2250738585072014e-308".parse::<f64>()); + b.iter(|| black_box("2.2250738585072014e-308").parse::<f64>()); } #[bench] fn bench_max(b: &mut Bencher) { - b.iter(|| "1.7976931348623157e308".parse::<f64>()); + b.iter(|| black_box("1.7976931348623157e308").parse::<f64>()); } diff --git a/library/core/benches/num/flt2dec/mod.rs b/library/core/benches/num/flt2dec/mod.rs index 32fd5e626bc..1a330ef5fe5 100644 --- a/library/core/benches/num/flt2dec/mod.rs +++ b/library/core/benches/num/flt2dec/mod.rs @@ -7,7 +7,7 @@ use core::num::flt2dec::MAX_SIG_DIGITS; use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded}; use std::io::Write; use std::vec::Vec; -use test::Bencher; +use test::{black_box, Bencher}; pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded { match decode(v).1 { @@ -22,7 +22,7 @@ fn bench_small_shortest(b: &mut Bencher) { b.iter(|| { buf.clear(); - write!(&mut buf, "{}", 3.1415926f64).unwrap() + write!(black_box(&mut buf), "{}", black_box(3.1415926f64)).unwrap() }); } @@ -32,6 +32,6 @@ fn bench_big_shortest(b: &mut Bencher) { b.iter(|| { buf.clear(); - write!(&mut buf, "{}", f64::MAX).unwrap() + write!(black_box(&mut buf), "{}", black_box(f64::MAX)).unwrap() }); } diff --git a/library/core/benches/num/mod.rs b/library/core/benches/num/mod.rs index 2f9cad2725d..b97014d9bf9 100644 --- a/library/core/benches/num/mod.rs +++ b/library/core/benches/num/mod.rs @@ -3,7 +3,7 @@ mod flt2dec; mod int_log; use std::str::FromStr; -use test::Bencher; +use test::{black_box, Bencher}; const ASCII_NUMBERS: [&str; 19] = [ "0", @@ -36,7 +36,7 @@ macro_rules! from_str_bench { .iter() .cycle() .take(5_000) - .filter_map(|s| <$t>::from_str(s).ok()) + .filter_map(|s| <$t>::from_str(black_box(s)).ok()) .max() }) } @@ -52,7 +52,7 @@ macro_rules! from_str_radix_bench { .iter() .cycle() .take(5_000) - .filter_map(|s| <$t>::from_str_radix(s, $radix).ok()) + .filter_map(|s| <$t>::from_str_radix(black_box(s), $radix).ok()) .max() }) } diff --git a/library/core/src/any.rs b/library/core/src/any.rs index bb93ea509d8..d1c1ae6526b 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -866,7 +866,7 @@ where /// /// A data provider provides values by calling this type's provide methods. #[unstable(feature = "provide_any", issue = "96024")] -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 pub struct Demand<'a>(dyn Erased<'a> + 'a); impl<'a> Demand<'a> { diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index a96dfafd9c4..2c3c14853a4 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2100,6 +2100,8 @@ impl<T: ?Sized> UnsafeCell<T> { /// /// let m = MaybeUninit::<UnsafeCell<i32>>::uninit(); /// unsafe { UnsafeCell::raw_get(m.as_ptr()).write(5); } + /// // avoid below which references to uninitialized data + /// // unsafe { UnsafeCell::get(&*m.as_ptr()).write(5); } /// let uc = unsafe { m.assume_init() }; /// /// assert_eq!(uc.into_inner(), 5); diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index b85894259f1..b73abbbaca7 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -203,7 +203,7 @@ mod c_long_definition { // be UB. #[doc = include_str!("c_void.md")] #[cfg_attr(not(bootstrap), lang = "c_void")] -#[repr(u8)] +#[cfg_attr(not(doc), repr(u8))] // work around https://github.com/rust-lang/rust/issues/90435 #[stable(feature = "core_c_void", since = "1.30.0")] pub enum c_void { #[unstable( @@ -244,7 +244,7 @@ impl fmt::Debug for c_void { target_os = "uefi", windows, ))] -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ @@ -296,7 +296,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> { not(target_os = "uefi"), not(windows), ))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -316,7 +316,7 @@ pub struct VaListImpl<'f> { /// PowerPC ABI implementation of a `va_list`. #[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -336,7 +336,7 @@ pub struct VaListImpl<'f> { /// s390x ABI implementation of a `va_list`. #[cfg(target_arch = "s390x")] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -355,7 +355,7 @@ pub struct VaListImpl<'f> { /// x86_64 ABI implementation of a `va_list`. #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -373,7 +373,7 @@ pub struct VaListImpl<'f> { } /// A wrapper for a `va_list` -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 #[derive(Debug)] #[unstable( feature = "c_variadic", diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index 19f8b944c1f..5944a0de1a4 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -228,7 +228,7 @@ //! //! - Operands implicitly convert to `Use` rvalues. //! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue. -//! - [`Discriminant`] and [`Len`] have associated functions. +//! - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions. //! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc. //! - The binary operation `Offset` can be created via [`Offset`]. //! - Checked binary operations are represented by wrapping the associated binop in [`Checked`]. @@ -279,6 +279,7 @@ define!("mir_storage_dead", fn StorageDead<T>(local: T)); define!("mir_deinit", fn Deinit<T>(place: T)); define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool)); define!("mir_len", fn Len<T>(place: T) -> usize); +define!("mir_copy_for_deref", fn CopyForDeref<T>(place: T) -> T); define!("mir_retag", fn Retag<T>(place: T)); define!("mir_move", fn Move<T>(place: T) -> T); define!("mir_static", fn Static<T>(s: T) -> &'static T); diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 520ec9abcf0..2568aaf34f3 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -310,6 +310,7 @@ where /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] +#[unstable(feature = "trusted_len", issue = "37572")] struct FlattenCompat<I, U> { iter: Fuse<I>, frontiter: Option<U>, @@ -463,6 +464,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] impl<I, U> Iterator for FlattenCompat<I, U> where I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, @@ -577,6 +579,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] impl<I, U> DoubleEndedIterator for FlattenCompat<I, U> where I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, @@ -646,6 +649,7 @@ where } } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<const N: usize, I, T> TrustedLen for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter> where @@ -653,6 +657,7 @@ where { } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, const N: usize, I, T> TrustedLen for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter> where @@ -660,6 +665,7 @@ where { } +#[unstable(feature = "trusted_len", issue = "37572")] unsafe impl<'a, const N: usize, I, T> TrustedLen for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter> where diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 26c51e84035..0af04fac909 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -133,6 +133,7 @@ #![feature(const_maybe_uninit_assume_init)] #![feature(const_maybe_uninit_uninit_array)] #![feature(const_nonnull_new)] +#![feature(const_num_midpoint)] #![feature(const_option)] #![feature(const_option_ext)] #![feature(const_pin)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 01606086fca..47a3e78b4d5 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -695,7 +695,7 @@ impl<T: ?Sized> !Sync for *mut T {} /// } /// ``` /// -/// This also in turn requires the annotation `T: 'a`, indicating +/// This also in turn infers the lifetime bound `T: 'a`, indicating /// that any references in `T` are valid over the lifetime `'a`. /// /// When initializing a `Slice` you simply provide the value diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 1c6819b547d..4a035ad61e1 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -940,6 +940,42 @@ impl f32 { } } + /// Calculates the middle point of `self` and `rhs`. + /// + /// This returns NaN when *either* argument is NaN or if a combination of + /// +inf and -inf is provided as arguments. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + /// assert_eq!(1f32.midpoint(4.0), 2.5); + /// assert_eq!((-5.5f32).midpoint(8.0), 1.25); + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + pub fn midpoint(self, other: f32) -> f32 { + const LO: f32 = f32::MIN_POSITIVE * 2.; + const HI: f32 = f32::MAX / 2.; + + let (a, b) = (self, other); + let abs_a = a.abs_private(); + let abs_b = b.abs_private(); + + if abs_a <= HI && abs_b <= HI { + // Overflow is impossible + (a + b) / 2. + } else if abs_a < LO { + // Not safe to halve a + a + (b / 2.) + } else if abs_b < LO { + // Not safe to halve b + (a / 2.) + b + } else { + // Not safe to halve a and b + (a / 2.) + (b / 2.) + } + } + /// Rounds toward zero and converts to any primitive integer type, /// assuming that the value is finite and fits in that type. /// diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 1e7387217cb..3aafc435f1e 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -951,6 +951,42 @@ impl f64 { } } + /// Calculates the middle point of `self` and `rhs`. + /// + /// This returns NaN when *either* argument is NaN or if a combination of + /// +inf and -inf is provided as arguments. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + /// assert_eq!(1f64.midpoint(4.0), 2.5); + /// assert_eq!((-5.5f64).midpoint(8.0), 1.25); + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + pub fn midpoint(self, other: f64) -> f64 { + const LO: f64 = f64::MIN_POSITIVE * 2.; + const HI: f64 = f64::MAX / 2.; + + let (a, b) = (self, other); + let abs_a = a.abs_private(); + let abs_b = b.abs_private(); + + if abs_a <= HI && abs_b <= HI { + // Overflow is impossible + (a + b) / 2. + } else if abs_a < LO { + // Not safe to halve a + a + (b / 2.) + } else if abs_b < LO { + // Not safe to halve b + (a / 2.) + b + } else { + // Not safe to halve a and b + (a / 2.) + (b / 2.) + } + } + /// Rounds toward zero and converts to any primitive integer type, /// assuming that the value is finite and fits in that type. /// diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 17715c9291f..1199d09b563 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2332,6 +2332,44 @@ macro_rules! int_impl { } } + /// Calculates the middle point of `self` and `rhs`. + /// + /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a + /// sufficiently-large signed integral type. This implies that the result is + /// always rounded towards negative infinity and that no overflow will ever occur. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] + #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-1), -1);")] + #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(0), -1);")] + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] + #[rustc_allow_const_fn_unstable(const_num_midpoint)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn midpoint(self, rhs: Self) -> Self { + const U: $UnsignedT = <$SelfT>::MIN.unsigned_abs(); + + // Map an $SelfT to an $UnsignedT + // ex: i8 [-128; 127] to [0; 255] + const fn map(a: $SelfT) -> $UnsignedT { + (a as $UnsignedT) ^ U + } + + // Map an $UnsignedT to an $SelfT + // ex: u8 [0; 255] to [-128; 127] + const fn demap(a: $UnsignedT) -> $SelfT { + (a ^ U) as $SelfT + } + + demap(<$UnsignedT>::midpoint(map(self), map(rhs))) + } + /// Returns the logarithm of the number with respect to an arbitrary base, /// rounded down. /// diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 08444421dca..c9baa09f407 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -95,6 +95,57 @@ depending on the target pointer size. }; } +macro_rules! midpoint_impl { + ($SelfT:ty, unsigned) => { + /// Calculates the middle point of `self` and `rhs`. + /// + /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a + /// sufficiently-large signed integral type. This implies that the result is + /// always rounded towards negative infinity and that no overflow will ever occur. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] + #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")] + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn midpoint(self, rhs: $SelfT) -> $SelfT { + // Use the well known branchless algorthim from Hacker's Delight to compute + // `(a + b) / 2` without overflowing: `((a ^ b) >> 1) + (a & b)`. + ((self ^ rhs) >> 1) + (self & rhs) + } + }; + ($SelfT:ty, $WideT:ty, unsigned) => { + /// Calculates the middle point of `self` and `rhs`. + /// + /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a + /// sufficiently-large signed integral type. This implies that the result is + /// always rounded towards negative infinity and that no overflow will ever occur. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] + #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")] + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn midpoint(self, rhs: $SelfT) -> $SelfT { + ((self as $WideT + rhs as $WideT) / 2) as $SelfT + } + }; +} + macro_rules! widening_impl { ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => { /// Calculates the complete product `self * rhs` without the possibility to overflow. @@ -455,6 +506,7 @@ impl u8 { bound_condition = "", } widening_impl! { u8, u16, 8, unsigned } + midpoint_impl! { u8, u16, unsigned } /// Checks if the value is within the ASCII range. /// @@ -1066,6 +1118,7 @@ impl u16 { bound_condition = "", } widening_impl! { u16, u32, 16, unsigned } + midpoint_impl! { u16, u32, unsigned } /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`]. /// @@ -1114,6 +1167,7 @@ impl u32 { bound_condition = "", } widening_impl! { u32, u64, 32, unsigned } + midpoint_impl! { u32, u64, unsigned } } impl u64 { @@ -1137,6 +1191,7 @@ impl u64 { bound_condition = "", } widening_impl! { u64, u128, 64, unsigned } + midpoint_impl! { u64, u128, unsigned } } impl u128 { @@ -1161,6 +1216,7 @@ impl u128 { from_xe_bytes_doc = "", bound_condition = "", } + midpoint_impl! { u128, unsigned } } #[cfg(target_pointer_width = "16")] @@ -1185,6 +1241,7 @@ impl usize { bound_condition = " on 16-bit targets", } widening_impl! { usize, u32, 16, unsigned } + midpoint_impl! { usize, u32, unsigned } } #[cfg(target_pointer_width = "32")] @@ -1209,6 +1266,7 @@ impl usize { bound_condition = " on 32-bit targets", } widening_impl! { usize, u64, 32, unsigned } + midpoint_impl! { usize, u64, unsigned } } #[cfg(target_pointer_width = "64")] @@ -1233,6 +1291,7 @@ impl usize { bound_condition = " on 64-bit targets", } widening_impl! { usize, u128, 64, unsigned } + midpoint_impl! { usize, u128, unsigned } } impl usize { diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 74a325b89d4..38a1c42d9e8 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -493,6 +493,43 @@ macro_rules! nonzero_unsigned_operations { pub const fn ilog10(self) -> u32 { super::int_log10::$Int(self.0) } + + /// Calculates the middle point of `self` and `rhs`. + /// + /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a + /// sufficiently-large signed integral type. This implies that the result is + /// always rounded towards negative infinity and that no overflow will ever occur. + /// + /// # Examples + /// + /// ``` + /// #![feature(num_midpoint)] + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")] + #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")] + #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")] + /// + /// assert_eq!(one.midpoint(four), two); + /// assert_eq!(four.midpoint(one), two); + /// # Some(()) + /// # } + /// ``` + #[unstable(feature = "num_midpoint", issue = "110840")] + #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] + #[rustc_allow_const_fn_unstable(const_num_midpoint)] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn midpoint(self, rhs: Self) -> Self { + // SAFETY: The only way to get `0` with midpoint is to have two opposite or + // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because + // of the unsignedness of this number and also because $Ty is guaranteed to + // never being 0. + unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) } + } } )+ } @@ -719,8 +756,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -734,7 +769,8 @@ macro_rules! nonzero_signed_operations { /// ``` #[must_use] #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn is_positive(self) -> bool { self.get().is_positive() } @@ -745,8 +781,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -760,7 +794,8 @@ macro_rules! nonzero_signed_operations { /// ``` #[must_use] #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn is_negative(self) -> bool { self.get().is_negative() } @@ -770,8 +805,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -786,7 +819,8 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn checked_neg(self) -> Option<$Ty> { if let Some(result) = self.get().checked_neg() { // SAFETY: negation of nonzero cannot yield zero values. @@ -803,8 +837,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -819,7 +851,8 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn overflowing_neg(self) -> ($Ty, bool) { let (result, overflow) = self.get().overflowing_neg(); // SAFETY: negation of nonzero cannot yield zero values. @@ -832,8 +865,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -853,7 +884,8 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn saturating_neg(self) -> $Ty { if let Some(result) = self.checked_neg() { return result; @@ -870,8 +902,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_negation_ops)] - /// #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// # fn main() { test().unwrap(); } /// # fn test() -> Option<()> { @@ -886,7 +916,8 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[inline] - #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")] pub const fn wrapping_neg(self) -> $Ty { let result = self.get().wrapping_neg(); // SAFETY: negation of nonzero cannot yield zero values. diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 8338a5d7e5a..ebcce79b0f8 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -35,9 +35,11 @@ pub macro panic_2015 { ("{}", $arg:expr $(,)?) => ( $crate::panicking::panic_display(&$arg) ), - ($fmt:expr, $($arg:tt)+) => ( - $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+)) - ), + ($fmt:expr, $($arg:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+)); + }), } #[doc(hidden)] @@ -53,9 +55,11 @@ pub macro panic_2021 { ("{}", $arg:expr $(,)?) => ( $crate::panicking::panic_display(&$arg) ), - ($($t:tt)+) => ( - $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)) - ), + ($($t:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)); + }), } #[doc(hidden)] diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 06fbe083ca1..5576adde84b 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -134,7 +134,7 @@ impl<'a> PanicInfo<'a> { /// whose ABI does not support unwinding. /// /// It is safe for a panic handler to unwind even when this function returns - /// true, however this will simply cause the panic handler to be called + /// false, however this will simply cause the panic handler to be called /// again. #[must_use] #[unstable(feature = "panic_can_unwind", issue = "92988")] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index c2e9ba273a5..6fd2b87d0e3 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1595,7 +1595,8 @@ impl<T> [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_split_at_not_mut", issue = "101158")] + #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(slice_split_at_unchecked)] #[inline] #[track_caller] #[must_use] diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index e3a464a1c51..91ee2903aab 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -791,8 +791,8 @@ pub struct CharArrayRefSearcher<'a, 'b, const N: usize>( /// # Examples /// /// ``` -/// assert_eq!("Hello world".find(['l', 'l']), Some(2)); -/// assert_eq!("Hello world".find(['l', 'l']), Some(2)); +/// assert_eq!("Hello world".find(['o', 'l']), Some(2)); +/// assert_eq!("Hello world".find(['h', 'w']), Some(6)); /// ``` impl<'a, const N: usize> Pattern<'a> for [char; N] { pattern_methods!(CharArraySearcher<'a, N>, MultiCharEqPattern, CharArraySearcher); @@ -811,8 +811,8 @@ unsafe impl<'a, const N: usize> ReverseSearcher<'a> for CharArraySearcher<'a, N> /// # Examples /// /// ``` -/// assert_eq!("Hello world".find(&['l', 'l']), Some(2)); -/// assert_eq!("Hello world".find(&['l', 'l']), Some(2)); +/// assert_eq!("Hello world".find(&['o', 'l']), Some(2)); +/// assert_eq!("Hello world".find(&['h', 'w']), Some(6)); /// ``` impl<'a, 'b, const N: usize> Pattern<'a> for &'b [char; N] { pattern_methods!(CharArrayRefSearcher<'a, 'b, N>, MultiCharEqPattern, CharArrayRefSearcher); diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 808825326ae..7043ab5ff2b 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -232,7 +232,7 @@ impl fmt::Debug for Context<'_> { /// /// [`Future::poll()`]: core::future::Future::poll /// [`Poll::Pending`]: core::task::Poll::Pending -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401 #[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { waker: RawWaker, diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 3c49d1705e5..3933e328951 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -53,6 +53,7 @@ #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] #![feature(numfmt)] +#![feature(num_midpoint)] #![feature(step_trait)] #![feature(str_internals)] #![feature(std_internals)] diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 18c55e43aac..439bbe66997 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -364,6 +364,32 @@ macro_rules! int_module { assert_eq!((0 as $T).borrowing_sub($T::MIN, false), ($T::MIN, true)); assert_eq!((0 as $T).borrowing_sub($T::MIN, true), ($T::MAX, false)); } + + #[test] + fn test_midpoint() { + assert_eq!(<$T>::midpoint(1, 3), 2); + assert_eq!(<$T>::midpoint(3, 1), 2); + + assert_eq!(<$T>::midpoint(0, 0), 0); + assert_eq!(<$T>::midpoint(0, 2), 1); + assert_eq!(<$T>::midpoint(2, 0), 1); + assert_eq!(<$T>::midpoint(2, 2), 2); + + assert_eq!(<$T>::midpoint(1, 4), 2); + assert_eq!(<$T>::midpoint(4, 1), 2); + assert_eq!(<$T>::midpoint(3, 4), 3); + assert_eq!(<$T>::midpoint(4, 3), 3); + + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), -1); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), -1); + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); + + assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(<$T>::MAX, 6), <$T>::MAX / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MAX), <$T>::MAX / 2 + 3); + } } }; } diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 3e1f848ccfe..3f3659ba837 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -724,7 +724,7 @@ assume_usize_width! { } macro_rules! test_float { - ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { + ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr, $min: expr, $max: expr, $min_pos: expr) => { mod $modname { #[test] fn min() { @@ -845,6 +845,38 @@ macro_rules! test_float { assert!(($nan as $fty).maximum($nan).is_nan()); } #[test] + fn midpoint() { + assert_eq!((0.5 as $fty).midpoint(0.5), 0.5); + assert_eq!((0.5 as $fty).midpoint(2.5), 1.5); + assert_eq!((3.0 as $fty).midpoint(4.0), 3.5); + assert_eq!((-3.0 as $fty).midpoint(4.0), 0.5); + assert_eq!((3.0 as $fty).midpoint(-4.0), -0.5); + assert_eq!((-3.0 as $fty).midpoint(-4.0), -3.5); + assert_eq!((0.0 as $fty).midpoint(0.0), 0.0); + assert_eq!((-0.0 as $fty).midpoint(-0.0), -0.0); + assert_eq!((-5.0 as $fty).midpoint(5.0), 0.0); + assert_eq!(($max as $fty).midpoint($min), 0.0); + assert_eq!(($min as $fty).midpoint($max), -0.0); + assert_eq!(($max as $fty).midpoint($min_pos), $max / 2.); + assert_eq!((-$max as $fty).midpoint($min_pos), -$max / 2.); + assert_eq!(($max as $fty).midpoint(-$min_pos), $max / 2.); + assert_eq!((-$max as $fty).midpoint(-$min_pos), -$max / 2.); + assert_eq!(($min_pos as $fty).midpoint($max), $max / 2.); + assert_eq!(($min_pos as $fty).midpoint(-$max), -$max / 2.); + assert_eq!((-$min_pos as $fty).midpoint($max), $max / 2.); + assert_eq!((-$min_pos as $fty).midpoint(-$max), -$max / 2.); + assert_eq!(($max as $fty).midpoint($max), $max); + assert_eq!(($min_pos as $fty).midpoint($min_pos), $min_pos); + assert_eq!((-$min_pos as $fty).midpoint(-$min_pos), -$min_pos); + assert_eq!(($max as $fty).midpoint(5.0), $max / 2.0 + 2.5); + assert_eq!(($max as $fty).midpoint(-5.0), $max / 2.0 - 2.5); + assert_eq!(($inf as $fty).midpoint($inf), $inf); + assert_eq!(($neginf as $fty).midpoint($neginf), $neginf); + assert!(($nan as $fty).midpoint(1.0).is_nan()); + assert!((1.0 as $fty).midpoint($nan).is_nan()); + assert!(($nan as $fty).midpoint($nan).is_nan()); + } + #[test] fn rem_euclid() { let a: $fty = 42.0; assert!($inf.rem_euclid(a).is_nan()); @@ -867,5 +899,23 @@ macro_rules! test_float { }; } -test_float!(f32, f32, f32::INFINITY, f32::NEG_INFINITY, f32::NAN); -test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN); +test_float!( + f32, + f32, + f32::INFINITY, + f32::NEG_INFINITY, + f32::NAN, + f32::MIN, + f32::MAX, + f32::MIN_POSITIVE +); +test_float!( + f64, + f64, + f64::INFINITY, + f64::NEG_INFINITY, + f64::NAN, + f64::MIN, + f64::MAX, + f64::MIN_POSITIVE +); diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 15ae9f2324f..7d6203db0b9 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -252,6 +252,32 @@ macro_rules! uint_module { assert_eq!($T::MAX.borrowing_sub(0, true), ($T::MAX - 1, false)); assert_eq!($T::MAX.borrowing_sub($T::MAX, true), ($T::MAX, true)); } + + #[test] + fn test_midpoint() { + assert_eq!(<$T>::midpoint(1, 3), 2); + assert_eq!(<$T>::midpoint(3, 1), 2); + + assert_eq!(<$T>::midpoint(0, 0), 0); + assert_eq!(<$T>::midpoint(0, 2), 1); + assert_eq!(<$T>::midpoint(2, 0), 1); + assert_eq!(<$T>::midpoint(2, 2), 2); + + assert_eq!(<$T>::midpoint(1, 4), 2); + assert_eq!(<$T>::midpoint(4, 1), 2); + assert_eq!(<$T>::midpoint(3, 4), 3); + assert_eq!(<$T>::midpoint(4, 3), 3); + + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MIN), (<$T>::MAX - <$T>::MIN) / 2); + assert_eq!(<$T>::midpoint(<$T>::MIN, <$T>::MIN), <$T>::MIN); + assert_eq!(<$T>::midpoint(<$T>::MAX, <$T>::MAX), <$T>::MAX); + + assert_eq!(<$T>::midpoint(<$T>::MIN, 6), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MIN), <$T>::MIN / 2 + 3); + assert_eq!(<$T>::midpoint(<$T>::MAX, 6), (<$T>::MAX - <$T>::MIN) / 2 + 3); + assert_eq!(<$T>::midpoint(6, <$T>::MAX), (<$T>::MAX - <$T>::MIN) / 2 + 3); + } } }; } diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index e58df80fca8..e0f3c7beef6 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -88,7 +88,7 @@ impl_element! { isize } /// The layout of this type is unspecified, and may change between platforms /// and/or Rust versions, and code should not assume that it is equivalent to /// `[T; LANES]`. -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 pub struct Mask<T, const LANES: usize>(mask_impl::Mask<T, LANES>) where T: MaskElement, diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6640c7fb162..2a6b1a5ec73 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1946,7 +1946,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> /// On success, the total number of bytes copied is returned and it is equal to /// the length of the `to` file as reported by `metadata`. /// -/// If you’re wanting to copy the contents of one file to another and you’re +/// If you want to copy the contents of one file to another and you’re /// working with [`File`]s, see the [`io::copy()`] function. /// /// # Platform-specific behavior diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index 38b98afffa1..1d9d93f5b64 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -10,7 +10,7 @@ use crate::mem::MaybeUninit; /// On success, the total number of bytes that were copied from /// `reader` to `writer` is returned. /// -/// If you’re wanting to copy the contents of one file to another and you’re +/// If you want to copy the contents of one file to another and you’re /// working with filesystem paths, see the [`fs::copy`] function. /// /// [`fs::copy`]: crate::fs::copy diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 280757a41a2..cbf8209a5ad 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -437,6 +437,42 @@ impl<T: AsHandle> AsHandle for &mut T { } } +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +/// This impl allows implementing traits that require `AsHandle` on Arc. +/// ``` +/// # #[cfg(windows)] mod group_cfg { +/// # use std::os::windows::io::AsHandle; +/// use std::fs::File; +/// use std::sync::Arc; +/// +/// trait MyTrait: AsHandle {} +/// impl MyTrait for Arc<File> {} +/// impl MyTrait for Box<File> {} +/// # } +/// ``` +impl<T: AsHandle> AsHandle for crate::sync::Arc<T> { + #[inline] + fn as_handle(&self) -> BorrowedHandle<'_> { + (**self).as_handle() + } +} + +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +impl<T: AsHandle> AsHandle for crate::rc::Rc<T> { + #[inline] + fn as_handle(&self) -> BorrowedHandle<'_> { + (**self).as_handle() + } +} + +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +impl<T: AsHandle> AsHandle for Box<T> { + #[inline] + fn as_handle(&self) -> BorrowedHandle<'_> { + (**self).as_handle() + } +} + #[stable(feature = "io_safety", since = "1.63.0")] impl AsHandle for BorrowedHandle<'_> { #[inline] diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index eb6097a89a6..0c90d55c024 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -254,6 +254,42 @@ impl<T: AsSocket> AsSocket for &mut T { } } +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +/// This impl allows implementing traits that require `AsSocket` on Arc. +/// ``` +/// # #[cfg(windows)] mod group_cfg { +/// # use std::os::windows::io::AsSocket; +/// use std::net::UdpSocket; +/// use std::sync::Arc; +/// +/// trait MyTrait: AsSocket {} +/// impl MyTrait for Arc<UdpSocket> {} +/// impl MyTrait for Box<UdpSocket> {} +/// # } +/// ``` +impl<T: AsSocket> AsSocket for crate::sync::Arc<T> { + #[inline] + fn as_socket(&self) -> BorrowedSocket<'_> { + (**self).as_socket() + } +} + +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +impl<T: AsSocket> AsSocket for crate::rc::Rc<T> { + #[inline] + fn as_socket(&self) -> BorrowedSocket<'_> { + (**self).as_socket() + } +} + +#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")] +impl<T: AsSocket> AsSocket for Box<T> { + #[inline] + fn as_socket(&self) -> BorrowedSocket<'_> { + (**self).as_socket() + } +} + #[stable(feature = "io_safety", since = "1.63.0")] impl AsSocket for BorrowedSocket<'_> { #[inline] diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 345d72ef867..a2ffd8b1e7e 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -26,7 +26,9 @@ pub macro panic_2015 { $crate::rt::panic_display(&$arg) }), ($fmt:expr, $($arg:tt)+) => ({ - $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+)) + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+)); }), } diff --git a/library/std/src/sync/mpmc/error.rs b/library/std/src/sync/mpmc/error.rs index 1b8a1f38797..33b2bff8534 100644 --- a/library/std/src/sync/mpmc/error.rs +++ b/library/std/src/sync/mpmc/error.rs @@ -35,7 +35,7 @@ impl<T> fmt::Display for SendTimeoutError<T> { } } -impl<T: Send> error::Error for SendTimeoutError<T> {} +impl<T> error::Error for SendTimeoutError<T> {} impl<T> From<SendError<T>> for SendTimeoutError<T> { fn from(err: SendError<T>) -> SendTimeoutError<T> { diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index 6e3c28f10bb..0e0c87d1c74 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -1124,7 +1124,7 @@ impl<T> fmt::Display for SendError<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> error::Error for SendError<T> { +impl<T> error::Error for SendError<T> { #[allow(deprecated)] fn description(&self) -> &str { "sending on a closed channel" @@ -1152,7 +1152,7 @@ impl<T> fmt::Display for TrySendError<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Send> error::Error for TrySendError<T> { +impl<T> error::Error for TrySendError<T> { #[allow(deprecated)] fn description(&self) -> &str { match *self { diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 3b7c31826b9..1b86d898cc7 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -18,8 +18,8 @@ use crate::fmt; /// target platform. It is instantiated with the [`thread_local!`] macro and the /// primary method is the [`with`] method. /// -/// The [`with`] method yields a reference to the contained value which cannot be -/// sent across threads or escape the given closure. +/// The [`with`] method yields a reference to the contained value which cannot +/// outlive the current thread or escape the given closure. /// /// [`thread_local!`]: crate::thread_local /// diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index dfe6bb7f057..9420c4fec5f 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -45,6 +45,7 @@ dependencies = [ "build_helper", "cc", "clap", + "clap_complete", "cmake", "fd-lock", "filetime", @@ -57,6 +58,7 @@ dependencies = [ "once_cell", "opener", "pretty_assertions", + "semver", "serde", "serde_derive", "serde_json", @@ -120,6 +122,15 @@ dependencies = [ ] [[package]] +name = "clap_complete" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36774babb166352bb4f7b9cb16f781ffa3439d2a8f12cd31bea85a38c888fea3" +dependencies = [ + "clap", +] + +[[package]] name = "clap_derive" version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -636,6 +647,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] name = "serde" version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index fd5eb740630..746c8dcfce0 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -56,6 +56,8 @@ walkdir = "2" # Dependencies needed by the build-metrics feature sysinfo = { version = "0.26.0", optional = true } clap = { version = "4.2.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] } +clap_complete = "4.2.2" +semver = "1.0.17" # Solaris doesn't support flock() and thus fd-lock is not option now [target.'cfg(not(target_os = "solaris"))'.dependencies] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 237f65b039f..5c37fab5470 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -839,6 +839,7 @@ impl<'a> Builder<'a> { run::CollectLicenseMetadata, run::GenerateCopyright, run::GenerateWindowsSys, + run::GenerateCompletions, ), Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode), Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index bf3bc3247ac..710c8b52194 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -24,6 +24,7 @@ pub use crate::flags::Subcommand; use crate::flags::{Color, Flags, Warnings}; use crate::util::{exe, output, t}; use once_cell::sync::OnceCell; +use semver::Version; use serde::{Deserialize, Deserializer}; use serde_derive::Deserialize; @@ -1019,6 +1020,7 @@ impl Config { config.download_beta_toolchain(); config.out.join(config.build.triple).join("stage0/bin/rustc") }); + config.initial_cargo = build .cargo .map(|cargo| { @@ -1680,6 +1682,42 @@ impl Config { self.rust_codegen_backends.get(0).cloned() } + pub fn check_build_rustc_version(&self) { + if self.dry_run() { + return; + } + + // check rustc version is same or lower with 1 apart from the building one + let mut cmd = Command::new(&self.initial_rustc); + cmd.arg("--version"); + let rustc_output = output(&mut cmd) + .lines() + .next() + .unwrap() + .split(' ') + .nth(1) + .unwrap() + .split('-') + .next() + .unwrap() + .to_owned(); + let rustc_version = Version::parse(&rustc_output.trim()).unwrap(); + let source_version = + Version::parse(&fs::read_to_string(self.src.join("src/version")).unwrap().trim()) + .unwrap(); + if !(source_version == rustc_version + || (source_version.major == rustc_version.major + && source_version.minor == rustc_version.minor + 1)) + { + let prev_version = format!("{}.{}.x", source_version.major, source_version.minor - 1); + eprintln!( + "Unexpected rustc version: {}, we should use {}/{} to build source with {}", + rustc_version, prev_version, source_version, source_version + ); + crate::detail_exit(1); + } + } + /// Returns the commit to download, or `None` if we shouldn't download CI artifacts. fn download_ci_rustc_commit(&self, download_rustc: Option<StringOrBool>) -> Option<String> { // If `download-rustc` is not set, default to rebuilding. diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index c79a1bf9563..6e0c0e01af8 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -3,9 +3,9 @@ //! This module implements the command-line parsing of the build system which //! has various flags to configure how it's run. -use std::path::PathBuf; +use std::path::{Path, PathBuf}; -use clap::{Parser, ValueEnum}; +use clap::{CommandFactory, Parser, ValueEnum}; use crate::builder::{Builder, Kind}; use crate::config::{target_selection_list, Config, TargetSelectionList}; @@ -54,15 +54,15 @@ pub struct Flags { /// Build directory, overrides `build.build-dir` in `config.toml` pub build_dir: Option<PathBuf>, - #[arg(global(true), long, value_name = "BUILD")] + #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "BUILD")] /// build target of the stage0 compiler pub build: Option<String>, - #[arg(global(true), long, value_name = "HOST", value_parser = target_selection_list)] + #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)] /// host targets to build pub host: Option<TargetSelectionList>, - #[arg(global(true), long, value_name = "TARGET", value_parser = target_selection_list)] + #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)] /// target targets to build pub target: Option<TargetSelectionList>, @@ -73,7 +73,7 @@ pub struct Flags { /// include default paths in addition to the provided ones pub include_default_paths: bool, - #[arg(global(true), long)] + #[arg(global(true), value_hint = clap::ValueHint::Other, long)] pub rustc_error_format: Option<String>, #[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")] @@ -82,16 +82,16 @@ pub struct Flags { #[arg(global(true), long)] /// dry run; don't build anything pub dry_run: bool, - #[arg(global(true), long, value_name = "N")] + #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage to build (indicates compiler to use/test, e.g., stage 0 uses the /// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.) pub stage: Option<u32>, - #[arg(global(true), long, value_name = "N")] + #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage(s) to keep without recompiling /// (pass multiple times to keep e.g., both stages 0 and 1) pub keep_stage: Vec<u32>, - #[arg(global(true), long, value_name = "N")] + #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")] /// stage(s) of the standard library to keep without recompiling /// (pass multiple times to keep e.g., both stages 0 and 1) pub keep_stage_std: Vec<u32>, @@ -103,6 +103,7 @@ pub struct Flags { global(true), short, long, + value_hint = clap::ValueHint::Other, default_value_t = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get), value_name = "JOBS" )] @@ -117,7 +118,7 @@ pub struct Flags { /// otherwise, use the default configured behaviour pub warnings: Warnings, - #[arg(global(true), long, value_name = "FORMAT")] + #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")] /// rustc error format pub error_format: Option<String>, #[arg(global(true), long)] @@ -133,13 +134,13 @@ pub struct Flags { #[arg(global(true), long, value_name = "VALUE")] pub llvm_skip_rebuild: Option<bool>, /// generate PGO profile with rustc build - #[arg(global(true), long, value_name = "PROFILE")] + #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub rust_profile_generate: Option<String>, /// use PGO profile for rustc build - #[arg(global(true), long, value_name = "PROFILE")] + #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub rust_profile_use: Option<String>, /// use PGO profile for LLVM build - #[arg(global(true), long, value_name = "PROFILE")] + #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub llvm_profile_use: Option<String>, // LLVM doesn't support a custom location for generating profile // information. @@ -152,7 +153,7 @@ pub struct Flags { #[arg(global(true), long)] pub llvm_bolt_profile_generate: bool, /// use BOLT profile for LLVM build - #[arg(global(true), long, value_name = "PROFILE")] + #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")] pub llvm_bolt_profile_use: Option<String>, #[arg(global(true))] /// paths for the subcommand @@ -524,3 +525,23 @@ impl Subcommand { } } } + +/// Returns the shell completion for a given shell, if the result differs from the current +/// content of `path`. If `path` does not exist, always returns `Some`. +pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Option<String> { + let mut cmd = Flags::command(); + let current = if !path.exists() { + String::new() + } else { + std::fs::read_to_string(path).unwrap_or_else(|_| { + eprintln!("couldn't read {}", path.display()); + crate::detail_exit(1) + }) + }; + let mut buf = Vec::new(); + clap_complete::generate(shell, &mut cmd, "x.py", &mut buf); + if buf == current.as_bytes() { + return None; + } + Some(String::from_utf8(buf).expect("completion script should be UTF-8")) +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 994336977dc..3756976dee0 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -414,6 +414,7 @@ impl Build { bootstrap_out.display() ) } + config.check_build_rustc_version(); if rust_info.is_from_tarball() && config.description.is_none() { config.description = Some("built from a source tarball".to_owned()); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 57f3119e322..ec01f744b82 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,9 +1,12 @@ use std::path::PathBuf; use std::process::Command; +use clap_complete::shells; + use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::dist::distdir; +use crate::flags::get_completion; use crate::test; use crate::tool::{self, SourceType, Tool}; use crate::util::output; @@ -275,3 +278,34 @@ impl Step for GenerateWindowsSys { builder.run(&mut cmd); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct GenerateCompletions; + +impl Step for GenerateCompletions { + type Output = (); + + /// Uses `clap_complete` to generate shell completions. + fn run(self, builder: &Builder<'_>) { + // FIXME(clubby789): enable zsh when clap#4898 is fixed + let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"] + .map(|filename| builder.src.join("src/etc/completions").join(filename)); + if let Some(comp) = get_completion(shells::Bash, &bash) { + std::fs::write(&bash, comp).expect("writing bash completion"); + } + if let Some(comp) = get_completion(shells::Fish, &fish) { + std::fs::write(&fish, comp).expect("writing fish completion"); + } + if let Some(comp) = get_completion(shells::PowerShell, &powershell) { + std::fs::write(&powershell, comp).expect("writing powershell completion"); + } + } + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("generate-completions") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(GenerateCompletions); + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 374b6cafcac..2d600704e02 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -10,6 +10,8 @@ use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use clap_complete::shells; + use crate::builder::crate_description; use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::Interned; @@ -1138,7 +1140,24 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` builder.info("tidy check"); try_run(builder, &mut cmd); - builder.ensure(ExpandYamlAnchors {}); + builder.ensure(ExpandYamlAnchors); + + builder.info("x.py completions check"); + let [bash, fish, powershell] = ["x.py.sh", "x.py.fish", "x.py.ps1"] + .map(|filename| builder.src.join("src/etc/completions").join(filename)); + if builder.config.cmd.bless() { + builder.ensure(crate::run::GenerateCompletions); + } else { + if crate::flags::get_completion(shells::Bash, &bash).is_some() + || crate::flags::get_completion(shells::Fish, &fish).is_some() + || crate::flags::get_completion(shells::PowerShell, &powershell).is_some() + { + eprintln!( + "x.py completions were changed; run `x.py run generate-completions` to update them" + ); + crate::detail_exit(1); + } + } } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index d183d4ace05..6b4966ddeb4 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.16.0
\ No newline at end of file +0.16.3
\ No newline at end of file diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish new file mode 100644 index 00000000000..089c03a0d64 --- /dev/null +++ b/src/etc/completions/x.py.fish @@ -0,0 +1,475 @@ +complete -c x.py -n "__fish_use_subcommand" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_use_subcommand" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_use_subcommand" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_use_subcommand" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_use_subcommand" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_use_subcommand" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_use_subcommand" -l rustc-error-format -r -f +complete -c x.py -n "__fish_use_subcommand" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_use_subcommand" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_use_subcommand" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_use_subcommand" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_use_subcommand" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_use_subcommand" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_use_subcommand" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_use_subcommand" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_use_subcommand" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_use_subcommand" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_use_subcommand" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_use_subcommand" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_use_subcommand" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_use_subcommand" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_use_subcommand" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_use_subcommand" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_use_subcommand" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_use_subcommand" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_use_subcommand" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_use_subcommand" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_use_subcommand" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_use_subcommand" -f -a "build" -d 'Compile either the compiler or libraries' +complete -c x.py -n "__fish_use_subcommand" -f -a "check" -d 'Compile either the compiler or libraries, using cargo check' +complete -c x.py -n "__fish_use_subcommand" -f -a "clippy" -d 'Run Clippy (uses rustup/cargo-installed clippy binary)' +complete -c x.py -n "__fish_use_subcommand" -f -a "fix" -d 'Run cargo fix' +complete -c x.py -n "__fish_use_subcommand" -f -a "fmt" -d 'Run rustfmt' +complete -c x.py -n "__fish_use_subcommand" -f -a "doc" -d 'Build documentation' +complete -c x.py -n "__fish_use_subcommand" -f -a "test" -d 'Build and run some test suites' +complete -c x.py -n "__fish_use_subcommand" -f -a "bench" -d 'Build and run some benchmarks' +complete -c x.py -n "__fish_use_subcommand" -f -a "clean" -d 'Clean out build directories' +complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Duild distribution artifacts' +complete -c x.py -n "__fish_use_subcommand" -f -a "install" -d 'Install distribution artifacts' +complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained in this repository' +complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' +complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files' +complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from build" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from build" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from build" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from build" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from build" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from build" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from build" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from build" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from build" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from build" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from check" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from check" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from check" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from check" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from check" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from check" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l all-targets -d 'Check all targets' +complete -c x.py -n "__fish_seen_subcommand_from check" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from check" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from check" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from check" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from check" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from check" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from check" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s A -d 'clippy lints to allow' -r +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s D -d 'clippy lints to deny' -r +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s W -d 'clippy lints to warn on' -r +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s F -d 'clippy lints to forbid' -r +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l fix +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from clippy" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from fix" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fix" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from fix" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from fix" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from fix" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l check -d 'check formatting instead of applying' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from fmt" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from doc" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from doc" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l open -d 'open the docs in a browser' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format' +complete -c x.py -n "__fish_seen_subcommand_from doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from doc" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l run -d 'whether to execute run-* tests' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from test" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from test" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from test" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from test" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from test" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from test" -l no-fail-fast -d 'run all tests regardless of failure' +complete -c x.py -n "__fish_seen_subcommand_from test" -l no-doc -d 'do not run doc tests' +complete -c x.py -n "__fish_seen_subcommand_from test" -l doc -d 'only run doc tests' +complete -c x.py -n "__fish_seen_subcommand_from test" -l bless -d 'whether to automatically update stderr/stdout files' +complete -c x.py -n "__fish_seen_subcommand_from test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' +complete -c x.py -n "__fish_seen_subcommand_from test" -l only-modified -d 'only run tests that result has been changed' +complete -c x.py -n "__fish_seen_subcommand_from test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`' +complete -c x.py -n "__fish_seen_subcommand_from test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from test" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from test" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from test" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from test" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r +complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from bench" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from bench" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from bench" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from clean" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from clean" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l all +complete -c x.py -n "__fish_seen_subcommand_from clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from clean" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from clean" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from dist" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from dist" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from dist" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from dist" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from dist" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_seen_subcommand_from install" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from install" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from install" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from install" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from install" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from install" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from install" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from install" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from install" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from install" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from install" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from install" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_seen_subcommand_from run" -l args -d 'arguments for the tool' -r +complete -c x.py -n "__fish_seen_subcommand_from run" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from run" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from run" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from run" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from run" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from run" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from run" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from run" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from run" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from run" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from run" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from run" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from setup" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from setup" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from setup" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from setup" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from setup" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l config -d 'TOML configuration file for build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build -d 'build target of the stage0 compiler' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l host -d 'host targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l target -d 'target targets to build' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rustc-error-format -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -s j -l jobs -d 'number of jobs to run in parallel' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny ,warn ,default }" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l error-format -d 'rustc error format' -r -f +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always ,never ,auto }" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true ,false }" +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l run -d 'run suggested tests' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -s i -l incremental -d 'use incremental compilation' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l include-default-paths -d 'include default paths in addition to the provided ones' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l dry-run -d 'dry run; don\'t build anything' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l json-output -d 'use message-format=json' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' +complete -c x.py -n "__fish_seen_subcommand_from suggest" -s h -l help -d 'Print help (see more with \'--help\')' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 new file mode 100644 index 00000000000..fad2391e61f --- /dev/null +++ b/src/etc/completions/x.py.ps1 @@ -0,0 +1,607 @@ + +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { + param($wordToComplete, $commandAst, $cursorPosition) + + $commandElements = $commandAst.CommandElements + $command = @( + 'x.py' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-') -or + $element.Value -eq $wordToComplete) { + break + } + $element.Value + }) -join ';' + + $completions = @(switch ($command) { + 'x.py' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('build', 'build', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries') + [CompletionResult]::new('check', 'check', [CompletionResultType]::ParameterValue, 'Compile either the compiler or libraries, using cargo check') + [CompletionResult]::new('clippy', 'clippy', [CompletionResultType]::ParameterValue, 'Run Clippy (uses rustup/cargo-installed clippy binary)') + [CompletionResult]::new('fix', 'fix', [CompletionResultType]::ParameterValue, 'Run cargo fix') + [CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Run rustfmt') + [CompletionResult]::new('doc', 'doc', [CompletionResultType]::ParameterValue, 'Build documentation') + [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Build and run some test suites') + [CompletionResult]::new('bench', 'bench', [CompletionResultType]::ParameterValue, 'Build and run some benchmarks') + [CompletionResult]::new('clean', 'clean', [CompletionResultType]::ParameterValue, 'Clean out build directories') + [CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Duild distribution artifacts') + [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install distribution artifacts') + [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository') + [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') + [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files') + break + } + 'x.py;build' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;check' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--all-targets', 'all-targets', [CompletionResultType]::ParameterName, 'Check all targets') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;clippy' { + [CompletionResult]::new('-A', 'A', [CompletionResultType]::ParameterName, 'clippy lints to allow') + [CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'clippy lints to deny') + [CompletionResult]::new('-W', 'W', [CompletionResultType]::ParameterName, 'clippy lints to warn on') + [CompletionResult]::new('-F', 'F', [CompletionResultType]::ParameterName, 'clippy lints to forbid') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--fix', 'fix', [CompletionResultType]::ParameterName, 'fix') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;fix' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;fmt' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'check formatting instead of applying') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;doc' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--open', 'open', [CompletionResultType]::ParameterName, 'open the docs in a browser') + [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;test' { + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times') + [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') + [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests') + [CompletionResult]::new('--compare-mode', 'compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to') + [CompletionResult]::new('--pass', 'pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') + [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--no-fail-fast', 'no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') + [CompletionResult]::new('--no-doc', 'no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') + [CompletionResult]::new('--doc', 'doc', [CompletionResultType]::ParameterName, 'only run doc tests') + [CompletionResult]::new('--bless', 'bless', [CompletionResultType]::ParameterName, 'whether to automatically update stderr/stdout files') + [CompletionResult]::new('--force-rerun', 'force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') + [CompletionResult]::new('--only-modified', 'only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') + [CompletionResult]::new('--rustfix-coverage', 'rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;bench' { + [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'test-args') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'x.py;clean' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'all') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'x.py;dist' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'x.py;install' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } + 'x.py;run' { + [CompletionResult]::new('--args', 'args', [CompletionResultType]::ParameterName, 'arguments for the tool') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;setup' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'x.py;suggest' { + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') + [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') + [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') + [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') + [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') + [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') + [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') + [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') + [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel') + [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour') + [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format') + [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output') + [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml') + [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build') + [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') + [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') + [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') + [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'run suggested tests') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') + [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation') + [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones') + [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything') + [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json') + [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc') + [CompletionResult]::new('--llvm-bolt-profile-generate', 'llvm-bolt-profile-generate', [CompletionResultType]::ParameterName, 'generate BOLT profile for LLVM build') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + }) + + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText +} diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh new file mode 100644 index 00000000000..931cc4353b2 --- /dev/null +++ b/src/etc/completions/x.py.sh @@ -0,0 +1,1644 @@ +_x.py() { + local i cur prev opts cmd + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]} + do + case "${cmd},${i}" in + ",$1") + cmd="x.py" + ;; + bootstrap,bench) + cmd="bootstrap__bench" + ;; + bootstrap,build) + cmd="bootstrap__build" + ;; + bootstrap,check) + cmd="bootstrap__check" + ;; + bootstrap,clean) + cmd="bootstrap__clean" + ;; + bootstrap,clippy) + cmd="bootstrap__clippy" + ;; + bootstrap,dist) + cmd="bootstrap__dist" + ;; + bootstrap,doc) + cmd="bootstrap__doc" + ;; + bootstrap,fix) + cmd="bootstrap__fix" + ;; + bootstrap,fmt) + cmd="bootstrap__fmt" + ;; + bootstrap,install) + cmd="bootstrap__install" + ;; + bootstrap,run) + cmd="bootstrap__run" + ;; + bootstrap,setup) + cmd="bootstrap__setup" + ;; + bootstrap,suggest) + cmd="bootstrap__suggest" + ;; + bootstrap,test) + cmd="bootstrap__test" + ;; + *) + ;; + esac + done + + case "${cmd}" in + x.py) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__bench) + opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --test-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__build) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__check) + opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__clean) + opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__clippy) + opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + -A) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -D) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -W) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -F) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__dist) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__doc) + opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__fix) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__fmt) + opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__install) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__run) + opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__setup) + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__suggest) + opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + x.py__test) + opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --help [PATHS]... [ARGS]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --test-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-args) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --compare-mode) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --pass) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --run) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --build) + COMPREPLY=("${cur}") + return 0 + ;; + --host) + COMPREPLY=("${cur}") + return 0 + ;; + --target) + COMPREPLY=("${cur}") + return 0 + ;; + --exclude) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rustc-error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --on-fail) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage) + COMPREPLY=("${cur}") + return 0 + ;; + --keep-stage-std) + COMPREPLY=("${cur}") + return 0 + ;; + --src) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --jobs) + COMPREPLY=("${cur}") + return 0 + ;; + -j) + COMPREPLY=("${cur}") + return 0 + ;; + --warnings) + COMPREPLY=($(compgen -W "deny warn default" -- "${cur}")) + return 0 + ;; + --error-format) + COMPREPLY=("${cur}") + return 0 + ;; + --color) + COMPREPLY=($(compgen -W "always never auto" -- "${cur}")) + return 0 + ;; + --llvm-skip-rebuild) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --rust-profile-generate) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --rust-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --llvm-bolt-profile-use) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + esac +} + +complete -F _x.py -o bashdefault -o default x.py diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b802fd065fe..17aa6b38e38 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -594,9 +594,8 @@ pub(super) fn display_macro_source( def_id: DefId, vis: ty::Visibility<DefId>, ) -> String { - let tts: Vec<_> = def.body.tokens.clone().into_trees().collect(); // Extract the spans of all matchers. They represent the "interface" of the macro. - let matchers = tts.chunks(4).map(|arm| &arm[0]); + let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]); if def.macro_rules { format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(cx.tcx, matchers, ";")) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b6eb450d62b..5460bce21a5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -739,6 +739,9 @@ fn main_args(at_args: &[String]) -> MainResult { } }; + // Set parallel mode before error handler creation, which will create `Lock`s. + interface::set_thread_safe_mode(&options.unstable_opts); + let diag = core::new_handler( options.error_format, None, diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr index 9c91d935716..51a3b0d972e 100644 --- a/src/tools/clippy/tests/ui/diverging_sub_expression.stderr +++ b/src/tools/clippy/tests/ui/diverging_sub_expression.stderr @@ -31,18 +31,10 @@ LL | 3 => true || diverge(), | ^^^^^^^^^ error: sub-expression diverges - --> $DIR/diverging_sub_expression.rs:36:30 - | -LL | _ => true || panic!("boo"), - | ^^^^^^^^^^^^^ - | - = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: sub-expression diverges --> $DIR/diverging_sub_expression.rs:38:26 | LL | _ => true || break, | ^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9059a145b43..ba68b5ee9d5 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -428,7 +428,6 @@ impl TargetCfgs { )) .unwrap(); - let mut current = None; let mut all_targets = HashSet::new(); let mut all_archs = HashSet::new(); let mut all_oses = HashSet::new(); @@ -449,14 +448,11 @@ impl TargetCfgs { } all_pointer_widths.insert(format!("{}bit", cfg.pointer_width)); - if target == config.target { - current = Some(cfg); - } all_targets.insert(target.into()); } Self { - current: current.expect("current target not found"), + current: Self::get_current_target_config(config), all_targets, all_archs, all_oses, @@ -467,6 +463,89 @@ impl TargetCfgs { all_pointer_widths, } } + + fn get_current_target_config(config: &Config) -> TargetCfg { + let mut arch = None; + let mut os = None; + let mut env = None; + let mut abi = None; + let mut families = Vec::new(); + let mut pointer_width = None; + let mut endian = None; + let mut panic = None; + + for config in + rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines() + { + let (name, value) = config + .split_once("=\"") + .map(|(name, value)| { + ( + name, + Some( + value + .strip_suffix("\"") + .expect("key-value pair should be properly quoted"), + ), + ) + }) + .unwrap_or_else(|| (config, None)); + + match name { + "target_arch" => { + arch = Some(value.expect("target_arch should be a key-value pair").to_string()); + } + "target_os" => { + os = Some(value.expect("target_os sould be a key-value pair").to_string()); + } + "target_env" => { + env = Some(value.expect("target_env should be a key-value pair").to_string()); + } + "target_abi" => { + abi = Some(value.expect("target_abi should be a key-value pair").to_string()); + } + "target_family" => { + families + .push(value.expect("target_family should be a key-value pair").to_string()); + } + "target_pointer_width" => { + pointer_width = Some( + value + .expect("target_pointer_width should be a key-value pair") + .parse::<u32>() + .expect("target_pointer_width should be a valid u32"), + ); + } + "target_endian" => { + endian = Some(match value.expect("target_endian should be a key-value pair") { + "big" => Endian::Big, + "little" => Endian::Little, + _ => panic!("target_endian should be either 'big' or 'little'"), + }); + } + "panic" => { + panic = Some(match value.expect("panic should be a key-value pair") { + "abort" => PanicStrategy::Abort, + "unwind" => PanicStrategy::Unwind, + _ => panic!("panic should be either 'abort' or 'unwind'"), + }); + } + _ => (), + } + } + + TargetCfg { + arch: arch.expect("target configuration should specify target_arch"), + os: os.expect("target configuration should specify target_os"), + env: env.expect("target configuration should specify target_env"), + abi: abi.expect("target configuration should specify target_abi"), + families, + pointer_width: pointer_width + .expect("target configuration should specify target_pointer_width"), + endian: endian.expect("target configuration should specify target_endian"), + panic: panic.expect("target configuration should specify panic"), + } + } } #[derive(Clone, Debug, serde::Deserialize)] diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 4170c32f1fe..c8a370085a0 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -139,18 +139,18 @@ enum FileEntry { type Cache = HashMap<String, FileEntry>; fn small_url_encode(s: &str) -> String { - s.replace("<", "%3C") - .replace(">", "%3E") - .replace(" ", "%20") - .replace("?", "%3F") - .replace("'", "%27") - .replace("&", "%26") - .replace(",", "%2C") - .replace(":", "%3A") - .replace(";", "%3B") - .replace("[", "%5B") - .replace("]", "%5D") - .replace("\"", "%22") + s.replace('<', "%3C") + .replace('>', "%3E") + .replace(' ', "%20") + .replace('?', "%3F") + .replace('\'', "%27") + .replace('&', "%26") + .replace(',', "%2C") + .replace(':', "%3A") + .replace(';', "%3B") + .replace('[', "%5B") + .replace(']', "%5D") + .replace('\"', "%22") } impl Checker { @@ -267,7 +267,6 @@ impl Checker { FileEntry::OtherFile => return, FileEntry::Redirect { target } => { let t = target.clone(); - drop(target); let (target, redir_entry) = self.load_file(&t, report); match redir_entry { FileEntry::Missing => { @@ -391,7 +390,7 @@ impl Checker { const ERROR_INVALID_NAME: i32 = 123; let pretty_path = - file.strip_prefix(&self.root).unwrap_or(&file).to_str().unwrap().to_string(); + file.strip_prefix(&self.root).unwrap_or(file).to_str().unwrap().to_string(); let entry = self.cache.entry(pretty_path.clone()).or_insert_with(|| match fs::metadata(file) { @@ -470,10 +469,8 @@ fn is_exception(file: &Path, link: &str) -> bool { // NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path // calculated in `check` function is outside `build/<triple>/doc` dir. // So the `strip_prefix` method just returns the old absolute broken path. - if file.ends_with("std/primitive.slice.html") { - if link.ends_with("primitive.slice.html") { - return true; - } + if file.ends_with("std/primitive.slice.html") && link.ends_with("primitive.slice.html") { + return true; } false } @@ -545,7 +542,7 @@ fn with_attrs_in_source<F: FnMut(&str, usize, &str)>(source: &str, attr: &str, m fn parse_ids(ids: &mut HashSet<String>, file: &str, source: &str, report: &mut Report) { if ids.is_empty() { with_attrs_in_source(source, " id", |fragment, i, _| { - let frag = fragment.trim_start_matches("#").to_owned(); + let frag = fragment.trim_start_matches('#').to_owned(); let encoded = small_url_encode(&frag); if !ids.insert(frag) { report.errors += 1; diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index e2a7d484c23..737423a2cd1 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -820,9 +820,9 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95033b0e41b8018013d99a6f1486c1ae5bd080378ced60c5f797e93842423b33" +checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2" dependencies = [ "bstr", "cargo-platform", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index f6f81836804..5987b0df8d6 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -39,7 +39,7 @@ libloading = "0.7" [dev-dependencies] colored = "2" -ui_test = "0.9" +ui_test = "0.10" rustc_version = "0.4" # Features chosen to match those required by env_logger, to avoid rebuilds regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] } diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 4be970b398d..48a46a76a12 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -306,7 +306,7 @@ test|bless) # Only in root project as `cargo-miri` has no tests. $CARGO test $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml "$@" ;; -run) +run|run-dep) # Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so # that we set the MIRI_SYSROOT up the right way. FOUND_TARGET_OPT=0 @@ -323,11 +323,17 @@ run) # Make sure Miri actually uses this target. MIRIFLAGS="$MIRIFLAGS --target $MIRI_TEST_TARGET" fi + # First build and get a sysroot. $CARGO build $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml find_sysroot # Then run the actual command. - exec $CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- $MIRIFLAGS "$@" + + if [ "$COMMAND" = "run-dep" ]; then + exec $CARGO test --test compiletest $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- --miri-run-dep-mode $MIRIFLAGS "$@" + else + exec $CARGO run $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml -- $MIRIFLAGS "$@" + fi ;; fmt) find "$MIRIDIR" -not \( -name target -prune \) -name '*.rs' \ diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 42687826b02..b450f986149 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -0b795044c6f0854445f1f2bb6443e87848e150d1 +69fef92ab2f287f072b66fb7b4f62c8bb4acba43 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 28f9912e283..083dd4800d9 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -28,8 +28,8 @@ use rustc_middle::{ middle::exported_symbols::{ ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, }, - query::LocalCrate, - ty::{query::ExternProviders, TyCtxt}, + query::{ExternProviders, LocalCrate}, + ty::TyCtxt, }; use rustc_session::config::OptLevel; diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs index 064dbe025af..a1e949183ad 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs @@ -83,7 +83,7 @@ impl Stack { self.borrows.truncate(write_idx); #[cfg(not(feature = "stack-cache"))] - drop(first_removed); // This is only needed for the stack-cache + let _unused = first_removed; // This is only needed for the stack-cache #[cfg(feature = "stack-cache")] if let Some(first_removed) = first_removed { diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index a93f3eb84f2..e3f81a78eea 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -289,7 +289,7 @@ pub fn report_error<'tcx, 'mir>( (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")), ], InvalidProgram( - InvalidProgramInfo::AlreadyReported(rustc_errors::ErrorGuaranteed { .. }) + InvalidProgramInfo::AlreadyReported(_) ) => { // This got already reported. No point in reporting it again. return None; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index fc938080a0e..893a4dbd4c8 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -47,7 +47,6 @@ extern crate rustc_ast; extern crate rustc_middle; extern crate rustc_const_eval; extern crate rustc_data_structures; -extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_index; extern crate rustc_session; diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index d101f8d3111..114c66253f7 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -421,14 +421,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } } #[rustfmt::skip] - "cast" | "as" => { + "cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => { let [op] = check_arg_count(args)?; let (op, op_len) = this.operand_to_simd(op)?; let (dest, dest_len) = this.place_to_simd(dest)?; assert_eq!(dest_len, op_len); + let unsafe_cast = intrinsic_name == "cast"; let safe_cast = intrinsic_name == "as"; + let ptr_cast = intrinsic_name == "cast_ptr"; + let expose_cast = intrinsic_name == "expose_addr"; + let from_exposed_cast = intrinsic_name == "from_exposed_addr"; for i in 0..dest_len { let op = this.read_immediate(&this.mplace_index(&op, i)?.into())?; @@ -436,19 +440,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) { // Int-to-(int|float): always safe - (ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) => + (ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast => this.int_to_int_or_float(&op, dest.layout.ty)?, // Float-to-float: always safe - (ty::Float(_), ty::Float(_)) => + (ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast => this.float_to_float_or_int(&op, dest.layout.ty)?, // Float-to-int in safe mode (ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast => this.float_to_float_or_int(&op, dest.layout.ty)?, // Float-to-int in unchecked mode - (ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if !safe_cast => + (ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(), - (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if !safe_cast => + (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(), + // Ptr-to-ptr cast + (ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => { + this.ptr_to_ptr(&op, dest.layout.ty)? + } + // Ptr/Int casts + (ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => { + this.pointer_expose_address_cast(&op, dest.layout.ty)? + } + (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => { + this.pointer_from_exposed_address_cast(&op, dest.layout.ty)? + } + // Error otherwise _ => throw_unsup_format!( "Unsupported SIMD cast from element type {from_ty} to {to_ty}", diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index e6388c56331..fa06c4b6a12 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -1,5 +1,6 @@ use colored::*; use regex::bytes::Regex; +use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::{env, process::Command}; use ui_test::status_emitter::StatusEmitter; @@ -45,7 +46,7 @@ fn build_so_for_c_ffi_tests() -> PathBuf { so_file_path } -fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> { +fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) -> Config { // Miri is rustc-like, so we create a default builder for rustc and modify it let mut program = CommandBuilder::rustc(); program.program = miri_path(); @@ -103,6 +104,26 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R ..Config::default() }; + let use_std = env::var_os("MIRI_NO_STD").is_none(); + + if with_dependencies && use_std { + config.dependencies_crate_manifest_path = + Some(Path::new("test_dependencies").join("Cargo.toml")); + config.dependency_builder.args = vec![ + "run".into(), + "--manifest-path".into(), + "cargo-miri/Cargo.toml".into(), + "--".into(), + "miri".into(), + "run".into(), // There is no `cargo miri build` so we just use `cargo miri run`. + ]; + } + config +} + +fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> { + let mut config = test_config(target, path, mode, with_dependencies); + // Handle command-line arguments. let mut after_dashdash = false; config.path_filter.extend(std::env::args().skip(1).filter(|arg| { @@ -126,21 +147,6 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R } })); - let use_std = env::var_os("MIRI_NO_STD").is_none(); - - if with_dependencies && use_std { - config.dependencies_crate_manifest_path = - Some(Path::new("test_dependencies").join("Cargo.toml")); - config.dependency_builder.args = vec![ - "run".into(), - "--manifest-path".into(), - "cargo-miri/Cargo.toml".into(), - "--".into(), - "miri".into(), - "run".into(), // There is no `cargo miri build` so we just use `cargo miri run`. - ]; - } - eprintln!(" Compiler: {}", config.program.display()); ui_test::run_tests_generic( config, @@ -226,8 +232,18 @@ fn get_target() -> String { fn main() -> Result<()> { ui_test::color_eyre::install()?; + let target = get_target(); + let mut args = std::env::args_os(); + + // Skip the program name and check whether this is a `./miri run-dep` invocation + if let Some(first) = args.nth(1) { + if first == "--miri-run-dep-mode" { + return run_dep_mode(target, args); + } + } + // Add a test env var to do environment communication tests. env::set_var("MIRI_ENV_VAR_TEST", "0"); // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find). @@ -250,6 +266,21 @@ fn main() -> Result<()> { Ok(()) } +fn run_dep_mode(target: String, mut args: impl Iterator<Item = OsString>) -> Result<()> { + let path = args.next().expect("./miri run-dep must be followed by a file name"); + let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true); + config.program.args.remove(0); // remove the `--error-format=json` argument + config.program.args.push("--color".into()); + config.program.args.push("always".into()); + let mut cmd = ui_test::test_command(config, Path::new(&path))?; + // Separate the arguments to the `cargo miri` invocation from + // the arguments to the interpreted prog + cmd.arg("--"); + cmd.args(args); + println!("{cmd:?}"); + if cmd.spawn()?.wait()?.success() { Ok(()) } else { std::process::exit(1) } +} + /// This is a custom renderer for `ui_test` output that does not emit github actions /// `group`s, while still producing regular github actions messages on test failures. struct TextAndGha; diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs index e4d9404c2ba..443f481c087 100644 --- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs @@ -1,7 +1,6 @@ //@error-in-other-file: memory is uninitialized at [0x4..0x8] //@normalize-stderr-test: "a[0-9]+" -> "ALLOC" #![feature(strict_provenance)] - #![allow(drop_copy)] // Test printing allocations that contain single-byte provenance. diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs new file mode 100644 index 00000000000..303c99834f5 --- /dev/null +++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs @@ -0,0 +1,12 @@ +// Separate test without strict provenance +//@compile-flags: -Zmiri-permissive-provenance +#![feature(portable_simd, platform_intrinsics)] +use std::ptr; +use std::simd::*; + +fn main() { + // Pointer casts + let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast_ptr(); + let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr(); + let _ptrs = Simd::<*const i32, 4>::from_exposed_addr(addrs); +} diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index afa6bce943f..e1004c796c5 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -145,6 +145,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "expect-test", "fallible-iterator", // dependency of `thorin` "fastrand", + "field-offset", "fixedbitset", "flate2", "fluent-bundle", diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 5f388ee47bb..d0257d71697 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -296,6 +296,12 @@ pub fn check(path: &Path, bad: &mut bool) { if filename.contains("ignore-tidy") { return; } + // Shell completions are automatically generated + if let Some(p) = file.parent() { + if p.ends_with(Path::new("src/etc/completions")) { + return; + } + } // apfloat shouldn't be changed because of license problems if is_in(file, "compiler", "rustc_apfloat") { return; diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 9473eabe442..ee12f4acb10 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -4,13 +4,38 @@ use ignore::Walk; use std::collections::HashMap; +use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1920; -const ROOT_ENTRY_LIMIT: usize = 895; +const ROOT_ENTRY_LIMIT: usize = 896; + +const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ + "rs", // test source files + "stderr", // expected stderr file, corresponds to a rs file + "stdout", // expected stdout file, corresponds to a rs file + "fixed", // expected source file after applying fixes + "md", // test directory descriptions + "ftl", // translation tests +]; + +const EXTENSION_EXCEPTION_PATHS: &[&str] = &[ + "tests/ui/asm/named-asm-labels.s", // loading an external asm file to test named labels lint + "tests/ui/check-cfg/my-awesome-platform.json", // testing custom targets with cfgs + "tests/ui/commandline-argfile-badutf8.args", // passing args via a file + "tests/ui/commandline-argfile.args", // passing args via a file + "tests/ui/crate-loading/auxiliary/libfoo.rlib", // testing loading a manually created rlib + "tests/ui/include-macros/data.bin", // testing including data with the include macros + "tests/ui/include-macros/file.txt", // testing including data with the include macros + "tests/ui/macros/macro-expanded-include/file.txt", // testing including data with the include macros + "tests/ui/macros/not-utf8.bin", // testing including data with the include macros + "tests/ui/macros/syntax-extension-source-utils-files/includeme.fragment", // more include + "tests/ui/unused-crate-deps/test.mk", // why would you use make + "tests/ui/proc-macro/auxiliary/included-file.txt", // more include +]; fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap<PathBuf, usize> = HashMap::new(); @@ -66,7 +91,14 @@ pub fn check(path: &Path, bad: &mut bool) { let paths = [ui.as_path(), ui_fulldeps.as_path()]; crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| { let file_path = entry.path(); - if let Some(ext) = file_path.extension() { + if let Some(ext) = file_path.extension().and_then(OsStr::to_str) { + // files that are neither an expected extension or an exception should not exist + // they're probably typos or not meant to exist + if !(EXPECTED_TEST_FILE_EXTENSIONS.contains(&ext) + || EXTENSION_EXCEPTION_PATHS.iter().any(|path| file_path.ends_with(path))) + { + tidy_error!(bad, "file {} has unexpected extension {}", file_path.display(), ext); + } if ext == "stderr" || ext == "stdout" { // Test output filenames have one of the formats: // ``` diff --git a/tests/codegen/addr-of-mutate.rs b/tests/codegen/addr-of-mutate.rs new file mode 100644 index 00000000000..bea1aad2352 --- /dev/null +++ b/tests/codegen/addr-of-mutate.rs @@ -0,0 +1,34 @@ +// compile-flags: -C opt-level=3 -C no-prepopulate-passes +// min-llvm-version: 15.0 (for opaque pointers) + +#![crate_type = "lib"] + +// Test for the absence of `readonly` on the argument when it is mutated via `&raw const`. +// See <https://github.com/rust-lang/rust/issues/111502>. + +// CHECK: i8 @foo(ptr noalias nocapture noundef dereferenceable(128) %x) +#[no_mangle] +pub fn foo(x: [u8; 128]) -> u8 { + let ptr = core::ptr::addr_of!(x).cast_mut(); + unsafe { + (*ptr)[0] = 1; + } + x[0] +} + +// CHECK: i1 @second(ptr noalias nocapture noundef dereferenceable({{[0-9]+}}) %a_ptr_and_b) +#[no_mangle] +pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { + let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut(); + (*b_bool_ptr) = true; + a_ptr_and_b.1.1 +} + +// If going through a deref (and there are no other mutating accesses), then `readonly` is fine. +// CHECK: i1 @third(ptr noalias nocapture noundef readonly dereferenceable({{[0-9]+}}) %a_ptr_and_b) +#[no_mangle] +pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool { + let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut(); + (*b_bool_ptr) = true; + a_ptr_and_b.1.1 +} diff --git a/tests/codegen/binary-search-index-no-bound-check.rs b/tests/codegen/binary-search-index-no-bound-check.rs index c1766a4a44a..595969a8979 100644 --- a/tests/codegen/binary-search-index-no-bound-check.rs +++ b/tests/codegen/binary-search-index-no-bound-check.rs @@ -9,7 +9,9 @@ #[no_mangle] pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check if let Ok(idx) = s.binary_search(&b'\\') { s[idx] } else { diff --git a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs index 8d07a67a1b4..2d779788791 100644 --- a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs +++ b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs @@ -9,7 +9,10 @@ #[no_mangle] pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[..idx] } else { @@ -21,7 +24,10 @@ pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { #[no_mangle] pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().position(|b| *b == b'\\') { &s[idx..] } else { @@ -33,7 +39,10 @@ pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { #[no_mangle] pub fn position_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().position(|b| *b == b'\\') { s[idx] } else { @@ -44,7 +53,10 @@ pub fn position_index_no_bounds_check(s: &[u8]) -> u8 { #[no_mangle] pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[..idx] } else { @@ -56,7 +68,10 @@ pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] { #[no_mangle] pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { &s[idx..] } else { @@ -68,7 +83,10 @@ pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] { #[no_mangle] pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 { // CHECK-NOT: panic - // CHECK-NOT: slice_index_len_fail + // CHECK-NOT: slice_start_index_len_fail + // CHECK-NOT: slice_end_index_len_fail + // CHECK-NOT: panic_bounds_check + // CHECK-NOT: unreachable if let Some(idx) = s.iter().rposition(|b| *b == b'\\') { s[idx] } else { diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs new file mode 100644 index 00000000000..85ade170ac6 --- /dev/null +++ b/tests/debuginfo/reference-debuginfo.rs @@ -0,0 +1,173 @@ +// Copy of `borrowed-basic.rs` which enables the `ReferencePropagation` MIR pass. +// That pass replaces debuginfo for `a => _x` where `_x = &b` to be `a => &b`, +// and leaves codegen to create a ladder of allocations so as `*a == b`. +// +// compile-flags:-g -Zmir-enable-passes=+ReferencePropagation,-ConstDebugInfo +// min-lldb-version: 310 + +// === GDB TESTS =================================================================================== + +// gdb-command:run +// gdb-command:print *bool_ref +// gdb-check:$1 = true + +// gdb-command:print *int_ref +// gdb-check:$2 = -1 + +// gdb-command:print/d *char_ref +// gdb-check:$3 = 97 + +// gdb-command:print *i8_ref +// gdbg-check:$4 = 68 'D' +// gdbr-check:$4 = 68 + +// gdb-command:print *i16_ref +// gdb-check:$5 = -16 + +// gdb-command:print *i32_ref +// gdb-check:$6 = -32 + +// gdb-command:print *i64_ref +// gdb-check:$7 = -64 + +// gdb-command:print *uint_ref +// gdb-check:$8 = 1 + +// gdb-command:print *u8_ref +// gdbg-check:$9 = 100 'd' +// gdbr-check:$9 = 100 + +// gdb-command:print *u16_ref +// gdb-check:$10 = 16 + +// gdb-command:print *u32_ref +// gdb-check:$11 = 32 + +// gdb-command:print *u64_ref +// gdb-check:$12 = 64 + +// gdb-command:print *f32_ref +// gdb-check:$13 = 2.5 + +// gdb-command:print *f64_ref +// gdb-check:$14 = 3.5 + +// gdb-command:print *f64_double_ref +// gdb-check:$15 = 3.5 + + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:print *bool_ref +// lldbg-check:[...]$0 = true +// lldbr-check:(bool) *bool_ref = true + +// lldb-command:print *int_ref +// lldbg-check:[...]$1 = -1 +// lldbr-check:(isize) *int_ref = -1 + +// NOTE: only rust-enabled lldb supports 32bit chars +// lldbr-command:print *char_ref +// lldbr-check:(char) *char_ref = 'a' + +// lldb-command:print *i8_ref +// lldbg-check:[...]$2 = 'D' +// lldbr-check:(i8) *i8_ref = 68 + +// lldb-command:print *i16_ref +// lldbg-check:[...]$3 = -16 +// lldbr-check:(i16) *i16_ref = -16 + +// lldb-command:print *i32_ref +// lldbg-check:[...]$4 = -32 +// lldbr-check:(i32) *i32_ref = -32 + +// lldb-command:print *i64_ref +// lldbg-check:[...]$5 = -64 +// lldbr-check:(i64) *i64_ref = -64 + +// lldb-command:print *uint_ref +// lldbg-check:[...]$6 = 1 +// lldbr-check:(usize) *uint_ref = 1 + +// lldb-command:print *u8_ref +// lldbg-check:[...]$7 = 'd' +// lldbr-check:(u8) *u8_ref = 100 + +// lldb-command:print *u16_ref +// lldbg-check:[...]$8 = 16 +// lldbr-check:(u16) *u16_ref = 16 + +// lldb-command:print *u32_ref +// lldbg-check:[...]$9 = 32 +// lldbr-check:(u32) *u32_ref = 32 + +// lldb-command:print *u64_ref +// lldbg-check:[...]$10 = 64 +// lldbr-check:(u64) *u64_ref = 64 + +// lldb-command:print *f32_ref +// lldbg-check:[...]$11 = 2.5 +// lldbr-check:(f32) *f32_ref = 2.5 + +// lldb-command:print *f64_ref +// lldbg-check:[...]$12 = 3.5 +// lldbr-check:(f64) *f64_ref = 3.5 + +// lldb-command:print *f64_double_ref +// lldbg-check:[...]$13 = 3.5 +// lldbr-check:(f64) **f64_double_ref = 3.5 + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +fn main() { + let bool_val: bool = true; + let bool_ref: &bool = &bool_val; + + let int_val: isize = -1; + let int_ref: &isize = &int_val; + + let char_val: char = 'a'; + let char_ref: &char = &char_val; + + let i8_val: i8 = 68; + let i8_ref: &i8 = &i8_val; + + let i16_val: i16 = -16; + let i16_ref: &i16 = &i16_val; + + let i32_val: i32 = -32; + let i32_ref: &i32 = &i32_val; + + let i64_val: i64 = -64; + let i64_ref: &i64 = &i64_val; + + let uint_val: usize = 1; + let uint_ref: &usize = &uint_val; + + let u8_val: u8 = 100; + let u8_ref: &u8 = &u8_val; + + let u16_val: u16 = 16; + let u16_ref: &u16 = &u16_val; + + let u32_val: u32 = 32; + let u32_ref: &u32 = &u32_val; + + let u64_val: u64 = 64; + let u64_ref: &u64 = &u64_val; + + let f32_val: f32 = 2.5; + let f32_ref: &f32 = &f32_val; + + let f64_val: f64 = 3.5; + let f64_ref: &f64 = &f64_val; + let f64_double_ref: &f64 = &f64_ref; + + zzz(); // #break +} + +fn zzz() {()} diff --git a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir new file mode 100644 index 00000000000..5233d0489c6 --- /dev/null +++ b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir @@ -0,0 +1,12 @@ +// MIR for `copy_for_deref` after built + +fn copy_for_deref(_1: (&i32, i32)) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/projections.rs:+0:38: +0:41 + let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + _2 = deref_copy (_1.0: &i32); // scope 0 at $DIR/projections.rs:+4:13: +4:37 + _0 = (*_2); // scope 0 at $DIR/projections.rs:+5:13: +5:24 + return; // scope 0 at $DIR/projections.rs:+6:13: +6:21 + } +} diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs index 5e472e531c7..3c155deae4b 100644 --- a/tests/mir-opt/building/custom/projections.rs +++ b/tests/mir-opt/building/custom/projections.rs @@ -21,13 +21,10 @@ fn unions(u: U) -> i32 { #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn tuples(i: (u32, i32)) -> (u32, i32) { mir!( - // FIXME(JakobDegen): This is necessary because we can't give type hints for `RET` - let temp: (u32, i32); + type RET = (u32, i32); { - temp.0 = i.0; - temp.1 = i.1; - - RET = temp; + RET.0 = i.0; + RET.1 = i.1; Return() } ) @@ -71,6 +68,19 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { }) } +// EMIT_MIR projections.copy_for_deref.built.after.mir +#[custom_mir(dialect = "runtime", phase = "initial")] +fn copy_for_deref(x: (&i32, i32)) -> i32 { + mir!( + let temp: &i32; + { + temp = CopyForDeref(x.0); + RET = *temp; + Return() + } + ) +} + fn main() { assert_eq!(unions(U { a: 5 }), 5); assert_eq!(tuples((5, 6)), (5, 6)); @@ -82,4 +92,7 @@ fn main() { assert_eq!(o, Some(10)); assert_eq!(simple_index([0; 10], &[0; 10]), 0); + + let one = 1; + assert_eq!(copy_for_deref((&one, one)), 1); } diff --git a/tests/mir-opt/building/custom/projections.tuples.built.after.mir b/tests/mir-opt/building/custom/projections.tuples.built.after.mir index 65487d3c9ed..dec575200c6 100644 --- a/tests/mir-opt/building/custom/projections.tuples.built.after.mir +++ b/tests/mir-opt/building/custom/projections.tuples.built.after.mir @@ -2,12 +2,10 @@ fn tuples(_1: (u32, i32)) -> (u32, i32) { let mut _0: (u32, i32); // return place in scope 0 at $DIR/projections.rs:+0:29: +0:39 - let mut _2: (u32, i32); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL bb0: { - (_2.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+5:13: +5:25 - (_2.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+6:13: +6:25 - _0 = _2; // scope 0 at $DIR/projections.rs:+8:13: +8:23 - return; // scope 0 at $DIR/projections.rs:+9:13: +9:21 + (_0.0: u32) = (_1.0: u32); // scope 0 at $DIR/projections.rs:+4:13: +4:24 + (_0.1: i32) = (_1.1: i32); // scope 0 at $DIR/projections.rs:+5:13: +5:24 + return; // scope 0 at $DIR/projections.rs:+6:13: +6:21 } } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index abb89b91dd3..73b9ea46c44 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -21,9 +21,9 @@ let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 scope 2 { - debug v1 => _12; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 - debug v2 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 - debug v3 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 + debug v1 => &(*_2)[0 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 + debug v2 => &(*_2)[1 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 + debug v3 => &(*_2)[2 of 3]; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 } } @@ -52,15 +52,6 @@ } bb2: { - StorageLive(_12); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 - _12 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 - StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 - _13 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 - StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 - _14 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 - StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2 diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff new file mode 100644 index 00000000000..07bd48fc846 --- /dev/null +++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff @@ -0,0 +1,175 @@ +- // MIR for `debuginfo` before ReferencePropagation ++ // MIR for `debuginfo` after ReferencePropagation + + fn debuginfo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:16: +0:16 + let _1: &mut u8; // in scope 0 at $DIR/reference_prop.rs:+3:9: +3:19 + let mut _2: u8; // in scope 0 at $DIR/reference_prop.rs:+3:27: +3:31 + let _4: debuginfo::T; // in scope 0 at $DIR/reference_prop.rs:+4:18: +4:22 + let _6: (); // in scope 0 at $DIR/reference_prop.rs:+9:5: +12:6 + let mut _7: std::option::Option<i32>; // in scope 0 at $DIR/reference_prop.rs:+9:11: +9:18 + let mut _8: isize; // in scope 0 at $DIR/reference_prop.rs:+10:9: +10:13 + let _10: (); // in scope 0 at $DIR/reference_prop.rs:+16:5: +17:6 + let mut _11: &[i32]; // in scope 0 at $DIR/reference_prop.rs:+16:82: +16:94 + let _12: &[i32]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:94 + let mut _13: &[i32; 10]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:90 + let _14: [i32; 10]; // in scope 0 at $DIR/reference_prop.rs:+16:83: +16:90 + let mut _15: std::ops::RangeFull; // in scope 0 at $DIR/reference_prop.rs:+16:91: +16:93 + let mut _16: usize; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79 + let mut _17: usize; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79 + let mut _18: bool; // in scope 0 at $DIR/reference_prop.rs:+16:12: +16:79 + let _23: &&mut u8; // in scope 0 at $DIR/reference_prop.rs:+19:28: +19:40 + let _24: &mut u8; // in scope 0 at $DIR/reference_prop.rs:+19:29: +19:40 + let mut _25: debuginfo::T; // in scope 0 at $DIR/reference_prop.rs:+19:34: +19:38 + scope 1 { +- debug ref_mut_u8 => _1; // in scope 1 at $DIR/reference_prop.rs:+3:9: +3:19 ++ debug ref_mut_u8 => &_2; // in scope 1 at $DIR/reference_prop.rs:+3:9: +3:19 + let _3: &u8; // in scope 1 at $DIR/reference_prop.rs:+4:9: +4:14 + let mut _28: &debuginfo::T; // in scope 1 at $DIR/reference_prop.rs:+4:17: +4:24 + scope 2 { +- debug field => _3; // in scope 2 at $DIR/reference_prop.rs:+4:9: +4:14 ++ debug field => &((*_28).0: u8); // in scope 2 at $DIR/reference_prop.rs:+4:9: +4:14 + let _5: &u8; // in scope 2 at $DIR/reference_prop.rs:+7:9: +7:17 + scope 3 { +- debug reborrow => _5; // in scope 3 at $DIR/reference_prop.rs:+7:9: +7:17 ++ debug reborrow => &_2; // in scope 3 at $DIR/reference_prop.rs:+7:9: +7:17 + let _9: &i32; // in scope 3 at $DIR/reference_prop.rs:+11:14: +11:31 + let _22: &&&mut u8; // in scope 3 at $DIR/reference_prop.rs:+19:9: +19:24 + let mut _27: &std::option::Option<i32>; // in scope 3 at $DIR/reference_prop.rs:+11:14: +11:31 + scope 4 { +- debug variant_field => _9; // in scope 4 at $DIR/reference_prop.rs:+11:14: +11:31 ++ debug variant_field => &(((*_27) as Some).0: i32); // in scope 4 at $DIR/reference_prop.rs:+11:14: +11:31 + } + scope 5 { +- debug constant_index => _19; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34 ++ debug constant_index => &(*_11)[1 of 3]; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34 + debug subslice => _20; // in scope 5 at $DIR/reference_prop.rs:+16:36: +16:44 + debug constant_index_from_end => _21; // in scope 5 at $DIR/reference_prop.rs:+16:51: +16:78 + let _19: &i32; // in scope 5 at $DIR/reference_prop.rs:+16:16: +16:34 + let _20: &[i32]; // in scope 5 at $DIR/reference_prop.rs:+16:36: +16:44 + let _21: &i32; // in scope 5 at $DIR/reference_prop.rs:+16:51: +16:78 + let mut _26: &[i32; 10]; // in scope 5 at $DIR/reference_prop.rs:+16:83: +16:90 + } + scope 6 { +- debug multiple_borrow => _22; // in scope 6 at $DIR/reference_prop.rs:+19:9: +19:24 ++ debug multiple_borrow => &&&(_25.0: u8); // in scope 6 at $DIR/reference_prop.rs:+19:9: +19:24 + } + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+3:9: +3:19 + StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+3:27: +3:31 + _2 = const 5_u8; // scope 0 at $DIR/reference_prop.rs:+3:27: +3:31 +- _1 = &mut _2; // scope 0 at $DIR/reference_prop.rs:+3:22: +3:31 +- StorageLive(_3); // scope 1 at $DIR/reference_prop.rs:+4:9: +4:14 + _28 = const _; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:24 + // mir::Constant + // + span: $DIR/reference_prop.rs:535:17: 535:24 + // + literal: Const { ty: &T, val: Unevaluated(debuginfo, [], Some(promoted[2])) } +- _3 = &((*_28).0: u8); // scope 1 at $DIR/reference_prop.rs:+4:17: +4:24 +- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+7:9: +7:17 +- _5 = &(*_1); // scope 2 at $DIR/reference_prop.rs:+7:20: +7:32 +- StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+9:5: +12:6 + StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18 + _7 = Option::<i32>::Some(const 0_i32); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18 + _8 = discriminant(_7); // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18 + switchInt(move _8) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 3 at $DIR/reference_prop.rs:+9:5: +9:18 + } + + bb1: { +- StorageLive(_9); // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31 + _27 = const _; // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31 + // mir::Constant + // + span: $DIR/reference_prop.rs:542:14: 542:31 + // + literal: Const { ty: &Option<i32>, val: Unevaluated(debuginfo, [], Some(promoted[1])) } +- _9 = &(((*_27) as Some).0: i32); // scope 3 at $DIR/reference_prop.rs:+11:14: +11:31 +- _6 = const (); // scope 4 at $DIR/reference_prop.rs:+11:36: +11:38 +- StorageDead(_9); // scope 3 at $DIR/reference_prop.rs:+11:37: +11:38 + goto -> bb4; // scope 3 at $DIR/reference_prop.rs:+11:37: +11:38 + } + + bb2: { + unreachable; // scope 3 at $DIR/reference_prop.rs:+9:11: +9:18 + } + + bb3: { +- _6 = const (); // scope 3 at $DIR/reference_prop.rs:+10:17: +10:19 + goto -> bb4; // scope 3 at $DIR/reference_prop.rs:+10:17: +10:19 + } + + bb4: { + StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+12:5: +12:6 +- StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+12:5: +12:6 +- StorageLive(_10); // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6 + StorageLive(_11); // scope 5 at $DIR/reference_prop.rs:+16:82: +16:94 + StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:94 + StorageLive(_13); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90 + _26 = const _; // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90 + // mir::Constant + // + span: $DIR/reference_prop.rs:547:83: 547:90 + // + literal: Const { ty: &[i32; 10], val: Unevaluated(debuginfo, [], Some(promoted[0])) } + _13 = &(*_26); // scope 5 at $DIR/reference_prop.rs:+16:83: +16:90 + StorageLive(_15); // scope 5 at $DIR/reference_prop.rs:+16:91: +16:93 + _15 = RangeFull; // scope 5 at $DIR/reference_prop.rs:+16:91: +16:93 + _12 = <[i32; 10] as Index<RangeFull>>::index(move _13, move _15) -> bb5; // scope 5 at $DIR/reference_prop.rs:+16:83: +16:94 + // mir::Constant + // + span: $DIR/reference_prop.rs:547:83: 547:94 + // + literal: Const { ty: for<'a> fn(&'a [i32; 10], RangeFull) -> &'a <[i32; 10] as Index<RangeFull>>::Output {<[i32; 10] as Index<RangeFull>>::index}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_15); // scope 5 at $DIR/reference_prop.rs:+16:93: +16:94 + StorageDead(_13); // scope 5 at $DIR/reference_prop.rs:+16:93: +16:94 + _11 = &(*_12); // scope 5 at $DIR/reference_prop.rs:+16:82: +16:94 + _16 = Len((*_11)); // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79 + _17 = const 3_usize; // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79 + _18 = Ge(move _16, move _17); // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79 + switchInt(move _18) -> [0: bb7, otherwise: bb6]; // scope 5 at $DIR/reference_prop.rs:+16:12: +16:79 + } + + bb6: { +- StorageLive(_19); // scope 5 at $DIR/reference_prop.rs:+16:16: +16:34 +- _19 = &(*_11)[1 of 3]; // scope 5 at $DIR/reference_prop.rs:+16:16: +16:34 + StorageLive(_20); // scope 5 at $DIR/reference_prop.rs:+16:36: +16:44 + _20 = &(*_11)[2:-1]; // scope 5 at $DIR/reference_prop.rs:+16:36: +16:44 + StorageLive(_21); // scope 5 at $DIR/reference_prop.rs:+16:51: +16:78 + _21 = &(*_11)[-1 of 3]; // scope 5 at $DIR/reference_prop.rs:+16:51: +16:78 +- _10 = const (); // scope 5 at $DIR/reference_prop.rs:+16:95: +17:6 + StorageDead(_21); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 + StorageDead(_20); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 +- StorageDead(_19); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 + goto -> bb8; // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6 + } + + bb7: { +- _10 = const (); // scope 3 at $DIR/reference_prop.rs:+17:6: +17:6 + goto -> bb8; // scope 3 at $DIR/reference_prop.rs:+16:5: +17:6 + } + + bb8: { + StorageDead(_12); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 + StorageDead(_11); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 +- StorageDead(_10); // scope 3 at $DIR/reference_prop.rs:+17:5: +17:6 +- StorageLive(_22); // scope 3 at $DIR/reference_prop.rs:+19:9: +19:24 +- StorageLive(_23); // scope 3 at $DIR/reference_prop.rs:+19:28: +19:40 +- StorageLive(_24); // scope 3 at $DIR/reference_prop.rs:+19:29: +19:40 + StorageLive(_25); // scope 3 at $DIR/reference_prop.rs:+19:34: +19:38 + _25 = T(const 6_u8); // scope 3 at $DIR/reference_prop.rs:+19:34: +19:38 +- _24 = &mut (_25.0: u8); // scope 3 at $DIR/reference_prop.rs:+19:29: +19:40 +- _23 = &_24; // scope 3 at $DIR/reference_prop.rs:+19:28: +19:40 +- _22 = &_23; // scope 3 at $DIR/reference_prop.rs:+19:27: +19:40 + _0 = const (); // scope 0 at $DIR/reference_prop.rs:+0:16: +20:2 + StorageDead(_25); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_24); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_23); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_22); // scope 3 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_3); // scope 1 at $DIR/reference_prop.rs:+20:1: +20:2 + StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+20:1: +20:2 +- StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+20:1: +20:2 + return; // scope 0 at $DIR/reference_prop.rs:+20:2: +20:2 + } + } + diff --git a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff index 8edc83cbf67..e158f64e9c3 100644 --- a/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff @@ -24,7 +24,7 @@ _5 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL _0 = opaque::<i32>(_5) -> bb3; // scope 0 at $DIR/reference_prop.rs:+16:13: +16:38 // mir::Constant - // + span: $DIR/reference_prop.rs:383:28: 383:34 + // + span: $DIR/reference_prop.rs:455:28: 455:34 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff index 920755bdd1d..38ab16cedb7 100644 --- a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff @@ -29,7 +29,7 @@ StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+21:13: +21:27 _0 = opaque::<i32>(_6) -> bb2; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:38 // mir::Constant - // + span: $DIR/reference_prop.rs:417:28: 417:34 + // + span: $DIR/reference_prop.rs:489:28: 489:34 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } @@ -37,7 +37,7 @@ _7 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL _0 = opaque::<i32>(_7) -> bb3; // scope 0 at $DIR/reference_prop.rs:+27:13: +27:38 // mir::Constant - // + span: $DIR/reference_prop.rs:422:28: 422:34 + // + span: $DIR/reference_prop.rs:494:28: 494:34 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } @@ -45,7 +45,7 @@ _8 = (*_5); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL _0 = opaque::<i32>(_8) -> bb4; // scope 0 at $DIR/reference_prop.rs:+33:13: +33:43 // mir::Constant - // + span: $DIR/reference_prop.rs:428:33: 428:39 + // + span: $DIR/reference_prop.rs:500:33: 500:39 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff index 07bfdf0b2f1..6e451786870 100644 --- a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff @@ -16,7 +16,7 @@ _3 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL _0 = opaque::<i32>(_3) -> bb1; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:43 // mir::Constant - // + span: $DIR/reference_prop.rs:357:33: 357:39 + // + span: $DIR/reference_prop.rs:429:33: 429:39 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } diff --git a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff index af8ee2411d3..d99e110359f 100644 --- a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff @@ -13,13 +13,16 @@ debug x => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:14 let _2: &mut i32; // in scope 1 at $DIR/reference_prop.rs:+2:9: +2:13 scope 2 { - debug xref => _2; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13 +- debug xref => _2; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13 ++ debug xref => &_1; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13 let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:9: +3:13 scope 3 { - debug xraw => _3; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13 +- debug xraw => _3; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13 ++ debug xraw => &_1; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13 let _6: &i32; // in scope 3 at $DIR/reference_prop.rs:+4:9: +4:13 scope 4 { - debug xshr => _6; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13 +- debug xshr => _6; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13 ++ debug xshr => &_1; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13 let _7: i32; // in scope 4 at $DIR/reference_prop.rs:+6:9: +6:10 scope 5 { debug a => _7; // in scope 5 at $DIR/reference_prop.rs:+6:9: +6:10 @@ -35,19 +38,17 @@ StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:14 _1 = const 2_i32; // scope 0 at $DIR/reference_prop.rs:+1:17: +1:18 - StorageLive(_2); // scope 1 at $DIR/reference_prop.rs:+2:9: +2:13 - _2 = &mut _1; // scope 1 at $DIR/reference_prop.rs:+2:16: +2:22 - StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:9: +3:13 +- _2 = &mut _1; // scope 1 at $DIR/reference_prop.rs:+2:16: +2:22 +- StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:9: +3:13 - StorageLive(_4); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36 - StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26 - _5 = &mut (*_2); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26 - _4 = &raw mut (*_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26 -+ _4 = &raw mut _1; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26 - _3 = _4; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36 +- _3 = _4; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36 - StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37 - StorageDead(_4); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37 - StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+4:9: +4:13 +- StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+4:9: +4:13 - _6 = &(*_2); // scope 3 at $DIR/reference_prop.rs:+4:16: +4:22 -+ _6 = &_1; // scope 3 at $DIR/reference_prop.rs:+4:16: +4:22 StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:10 - _7 = (*_6); // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18 - StorageLive(_8); // scope 5 at $DIR/reference_prop.rs:+7:5: +7:26 @@ -64,8 +65,8 @@ StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11 StorageDead(_9); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11 StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+9:1: +9:2 - StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+9:1: +9:2 - StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+9:1: +9:2 +- StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+9:1: +9:2 +- StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+9:1: +9:2 - StorageDead(_2); // scope 1 at $DIR/reference_prop.rs:+9:1: +9:2 StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:1: +9:2 return; // scope 0 at $DIR/reference_prop.rs:+9:2: +9:2 diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff index e41fc28461a..7b31ee695ce 100644 --- a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff @@ -17,12 +17,12 @@ let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18 let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 let _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:14 - let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19 - let mut _24: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18 + let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18 + let mut _24: &&usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17 let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 let _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:14 - let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19 - let mut _31: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18 + let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18 + let mut _31: *mut &usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17 let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 let _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:14 let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18 @@ -35,16 +35,25 @@ let _48: &T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19 let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18 - let _52: &T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 - let mut _53: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28 - let _54: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28 - let _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 - let mut _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let _52: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + let _53: &T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 + let mut _54: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28 + let _55: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28 + let _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 + let mut _58: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let _59: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + let _60: usize; // in scope 0 at $DIR/reference_prop.rs:+76:13: +76:14 + let _64: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19 + let mut _65: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18 + let _66: usize; // in scope 0 at $DIR/reference_prop.rs:+85:13: +85:14 + let _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19 + let mut _71: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18 scope 1 { debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14 let _5: &usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 scope 2 { - debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 +- debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 ++ debug b => &_4; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14 scope 3 { debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 @@ -86,7 +95,7 @@ let mut _27: &usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18 scope 13 { debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18 - let _28: &mut &usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 + let _28: *mut &usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 scope 14 { debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14 let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14 @@ -131,17 +140,52 @@ } } scope 25 { - debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 +- debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 ++ debug a => _1; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14 scope 26 { debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14 } } scope 27 { - debug a => _52; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14 - let _55: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 + debug a => _53; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14 + let _56: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 scope 28 { - debug b => _55; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14 + debug b => _56; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14 + } + } + scope 29 { + debug a => _60; // in scope 29 at $DIR/reference_prop.rs:+76:13: +76:14 + let _61: &usize; // in scope 29 at $DIR/reference_prop.rs:+77:13: +77:14 + scope 30 { +- debug b => _61; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14 ++ debug b => &_60; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14 + let _62: &&usize; // in scope 30 at $DIR/reference_prop.rs:+78:13: +78:14 + scope 31 { +- debug d => _62; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14 ++ debug d => &&_60; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14 + let _63: usize; // in scope 31 at $DIR/reference_prop.rs:+79:13: +79:14 + scope 32 { + debug c => _63; // in scope 32 at $DIR/reference_prop.rs:+79:13: +79:14 + } + } + } + } + scope 33 { + debug a => _66; // in scope 33 at $DIR/reference_prop.rs:+85:13: +85:14 + let mut _67: &usize; // in scope 33 at $DIR/reference_prop.rs:+86:13: +86:18 + scope 34 { +- debug b => _67; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18 ++ debug b => &_66; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18 + let _68: &mut &usize; // in scope 34 at $DIR/reference_prop.rs:+87:13: +87:14 + scope 35 { +- debug d => _68; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14 ++ debug d => &&_66; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14 + let _69: usize; // in scope 35 at $DIR/reference_prop.rs:+88:13: +88:14 + scope 36 { + debug c => _69; // in scope 36 at $DIR/reference_prop.rs:+88:13: +88:14 + } + } } } @@ -149,8 +193,8 @@ - StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:14 _4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:17: +3:24 - StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 - _5 = &_4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:19 +- StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 +- _5 = &_4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:19 StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14 - _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19 + _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19 @@ -168,7 +212,7 @@ StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20 - _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 +- StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 @@ -215,18 +259,18 @@ _21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19 StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14 _22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19 - StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19 - StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18 - _24 = (); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18 - _23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19 + StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18 + StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17 + _24 = _21; // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17 + _23 = opaque::<&&usize>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18 // mir::Constant // + span: $DIR/reference_prop.rs:36:9: 36:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + literal: Const { ty: fn(&&usize) {opaque::<&&usize>}, val: Value(<ZST>) } } bb3: { - StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19 - StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20 + StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:17: +26:18 + StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19 - _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6 StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6 @@ -239,21 +283,21 @@ StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18 _27 = &_26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:23 StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 - _28 = &mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23 + _28 = &raw mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:27 StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14 _29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19 - StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19 - StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18 - _31 = (); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18 - _30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19 + StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18 + StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17 + _31 = _28; // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17 + _30 = opaque::<*mut &usize>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18 // mir::Constant // + span: $DIR/reference_prop.rs:45:9: 45:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + literal: Const { ty: fn(*mut &usize) {opaque::<*mut &usize>}, val: Value(<ZST>) } } bb4: { - StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19 - StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20 + StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:17: +35:18 + StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19 - _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6 StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6 @@ -321,8 +365,8 @@ StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 - StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 - _48 = &(*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:25 +- StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 +- _48 = &(*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:25 StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14 - _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19 + _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19 @@ -340,36 +384,92 @@ StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20 - _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 +- StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 - _52 = &(*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:27 - StorageLive(_53); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 -- StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 -- _54 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 -- _53 = &(*_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 -+ _53 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 - _2 = move _53; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:28 - StorageDead(_53); // scope 27 at $DIR/reference_prop.rs:+69:27: +69:28 -- StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:28: +69:29 - StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 - _55 = (*_52); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19 - StorageLive(_56); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 - StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 - _57 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 - _56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 +- StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageLive(_53); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 + _53 = &(*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:27 + StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 +- StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 +- _55 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 +- _54 = &(*_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 ++ _54 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28 + _2 = move _54; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:28 + StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:27: +69:28 +- StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+69:28: +69:29 + StorageLive(_56); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 + _56 = (*_53); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19 + StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 + StorageLive(_58); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 + _58 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 + _57 = opaque::<()>(move _58) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 // mir::Constant // + span: $DIR/reference_prop.rs:81:9: 81:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } bb8: { - StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19 - StorageDead(_56); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20 - _0 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 - StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6 - StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 - return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2 + StorageDead(_58); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19 + StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20 +- _52 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageDead(_56); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6 + StorageDead(_53); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageLive(_59); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageLive(_60); // scope 0 at $DIR/reference_prop.rs:+76:13: +76:14 + _60 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+76:17: +76:24 +- StorageLive(_61); // scope 29 at $DIR/reference_prop.rs:+77:13: +77:14 +- _61 = &_60; // scope 29 at $DIR/reference_prop.rs:+77:17: +77:19 +- StorageLive(_62); // scope 30 at $DIR/reference_prop.rs:+78:13: +78:14 +- _62 = &_61; // scope 30 at $DIR/reference_prop.rs:+78:17: +78:19 + StorageLive(_63); // scope 31 at $DIR/reference_prop.rs:+79:13: +79:14 +- _63 = (*_61); // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19 ++ _63 = _60; // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19 + StorageLive(_64); // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19 + StorageLive(_65); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18 + _65 = (); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18 + _64 = opaque::<()>(move _65) -> bb9; // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:90:9: 90:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb9: { + StorageDead(_65); // scope 32 at $DIR/reference_prop.rs:+80:18: +80:19 + StorageDead(_64); // scope 32 at $DIR/reference_prop.rs:+80:19: +80:20 +- _59 = const (); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageDead(_63); // scope 31 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_62); // scope 30 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_61); // scope 29 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageDead(_60); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_59); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageLive(_66); // scope 0 at $DIR/reference_prop.rs:+85:13: +85:14 + _66 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+85:17: +85:24 +- StorageLive(_67); // scope 33 at $DIR/reference_prop.rs:+86:13: +86:18 +- _67 = &_66; // scope 33 at $DIR/reference_prop.rs:+86:21: +86:23 +- StorageLive(_68); // scope 34 at $DIR/reference_prop.rs:+87:13: +87:14 +- _68 = &mut _67; // scope 34 at $DIR/reference_prop.rs:+87:17: +87:23 + StorageLive(_69); // scope 35 at $DIR/reference_prop.rs:+88:13: +88:14 +- _69 = (*_67); // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19 ++ _69 = _66; // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19 + StorageLive(_70); // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19 + StorageLive(_71); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18 + _71 = (); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18 + _70 = opaque::<()>(move _71) -> bb10; // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:99:9: 99:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb10: { + StorageDead(_71); // scope 36 at $DIR/reference_prop.rs:+89:18: +89:19 + StorageDead(_70); // scope 36 at $DIR/reference_prop.rs:+89:19: +89:20 + _0 = const (); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6 + StorageDead(_69); // scope 35 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_68); // scope 34 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_67); // scope 33 at $DIR/reference_prop.rs:+90:5: +90:6 + StorageDead(_66); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6 + return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2 } } diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff index 712727915d0..ddeb04e50c7 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff @@ -13,11 +13,11 @@ let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19 let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18 let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 - let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19 - let mut _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18 + let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18 + let mut _23: &*const usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17 let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 - let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19 - let mut _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18 + let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18 + let mut _30: *mut *const usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17 let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18 let mut _36: *const usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17 @@ -31,15 +31,22 @@ let mut _53: *const T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:38 let _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 let mut _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 - let _61: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19 - let mut _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18 + let _57: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + let _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19 + let mut _63: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18 + let _64: (); // in scope 0 at $DIR/reference_prop.rs:+84:5: +90:6 + let _69: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19 + let mut _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18 + let _75: (); // in scope 0 at $DIR/reference_prop.rs:+98:9: +98:19 + let mut _76: (); // in scope 0 at $DIR/reference_prop.rs:+98:16: +98:18 scope 1 { let _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14 scope 2 { debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14 let _5: *const usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 scope 3 { - debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 +- debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 ++ debug b => &_4; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 scope 4 { debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14 @@ -90,7 +97,7 @@ let mut _26: *const usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18 scope 17 { debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18 - let _27: &mut *const usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 + let _27: *mut *const usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 scope 18 { debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14 let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14 @@ -144,7 +151,8 @@ scope 31 { let _47: *const T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 scope 32 { - debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 +- debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 ++ debug a => _1; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14 scope 33 { debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14 @@ -162,18 +170,60 @@ } } scope 37 { - let _57: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14 + let _58: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14 scope 38 { - debug a => _57; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:14 - let _58: *const usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 + debug a => _58; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:14 + let _59: *const usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 scope 39 { - debug b => _58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14 - let _59: *const usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 +- debug b => _59; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14 ++ debug b => &_58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14 + let _60: *const usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 scope 40 { - debug c => _59; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14 - let _60: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 +- debug c => _60; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14 ++ debug c => &_58; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14 + let _61: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 scope 41 { - debug e => _60; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14 + debug e => _61; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14 + } + } + } + } + } + scope 42 { + let _65: usize; // in scope 42 at $DIR/reference_prop.rs:+85:13: +85:14 + scope 43 { + debug a => _65; // in scope 43 at $DIR/reference_prop.rs:+85:13: +85:14 + let _66: *const usize; // in scope 43 at $DIR/reference_prop.rs:+86:13: +86:14 + scope 44 { +- debug b => _66; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:14 ++ debug b => &_65; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:14 + let _67: &*const usize; // in scope 44 at $DIR/reference_prop.rs:+87:13: +87:14 + scope 45 { +- debug d => _67; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14 ++ debug d => &&_65; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14 + let _68: usize; // in scope 45 at $DIR/reference_prop.rs:+88:13: +88:14 + scope 46 { + debug c => _68; // in scope 46 at $DIR/reference_prop.rs:+88:13: +88:14 + } + } + } + } + } + scope 47 { + let _71: usize; // in scope 47 at $DIR/reference_prop.rs:+94:13: +94:14 + scope 48 { + debug a => _71; // in scope 48 at $DIR/reference_prop.rs:+94:13: +94:14 + let mut _72: *const usize; // in scope 48 at $DIR/reference_prop.rs:+95:13: +95:18 + scope 49 { +- debug b => _72; // in scope 49 at $DIR/reference_prop.rs:+95:13: +95:18 ++ debug b => &_71; // in scope 49 at $DIR/reference_prop.rs:+95:13: +95:18 + let _73: &mut *const usize; // in scope 49 at $DIR/reference_prop.rs:+96:13: +96:14 + scope 50 { +- debug d => _73; // in scope 50 at $DIR/reference_prop.rs:+96:13: +96:14 ++ debug d => &&_71; // in scope 50 at $DIR/reference_prop.rs:+96:13: +96:14 + let _74: usize; // in scope 50 at $DIR/reference_prop.rs:+97:13: +97:14 + scope 51 { + debug c => _74; // in scope 51 at $DIR/reference_prop.rs:+97:13: +97:14 } } } @@ -184,8 +234,8 @@ - StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:14 _4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:17: +3:24 - StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 - _5 = &raw const _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:29 +- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 +- _5 = &raw const _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:29 StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 - _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19 + _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19 @@ -194,7 +244,7 @@ _8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18 _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19 // mir::Constant - // + span: $DIR/reference_prop.rs:166:9: 166:15 + // + span: $DIR/reference_prop.rs:202:9: 202:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -203,7 +253,7 @@ StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20 - _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6 StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 +- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 @@ -224,7 +274,7 @@ _16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18 _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19 // mir::Constant - // + span: $DIR/reference_prop.rs:177:9: 177:15 + // + span: $DIR/reference_prop.rs:213:9: 213:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -246,18 +296,18 @@ _20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19 StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14 _21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19 - StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19 - StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18 - _23 = (); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18 - _22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19 + StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18 + StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17 + _23 = _20; // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17 + _22 = opaque::<&*const usize>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18 // mir::Constant - // + span: $DIR/reference_prop.rs:186:9: 186:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:222:9: 222:15 + // + literal: Const { ty: fn(&*const usize) {opaque::<&*const usize>}, val: Value(<ZST>) } } bb3: { - StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19 - StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20 + StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:17: +26:18 + StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19 - _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6 StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6 StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6 @@ -270,21 +320,21 @@ StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18 _26 = &raw const _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:33 StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 - _27 = &mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23 + _27 = &raw mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:27 StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14 _28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19 - StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19 - StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18 - _30 = (); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18 - _29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19 + StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18 + StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17 + _30 = _27; // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17 + _29 = opaque::<*mut *const usize>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18 // mir::Constant - // + span: $DIR/reference_prop.rs:195:9: 195:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:231:9: 231:15 + // + literal: Const { ty: fn(*mut *const usize) {opaque::<*mut *const usize>}, val: Value(<ZST>) } } bb4: { - StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19 - StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20 + StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:17: +35:18 + StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19 - _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6 StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6 StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6 @@ -304,7 +354,7 @@ _36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17 _35 = opaque::<*const usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18 // mir::Constant - // + span: $DIR/reference_prop.rs:203:9: 203:15 + // + span: $DIR/reference_prop.rs:239:9: 239:15 // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) } } @@ -336,7 +386,7 @@ _45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18 _44 = opaque::<*const usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19 // mir::Constant - // + span: $DIR/reference_prop.rs:216:9: 216:15 + // + span: $DIR/reference_prop.rs:252:9: 252:15 // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) } } @@ -352,8 +402,8 @@ StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 - StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 - _47 = &raw const (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:35 +- StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 +- _47 = &raw const (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:35 StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14 - _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19 + _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19 @@ -362,7 +412,7 @@ _50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18 _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19 // mir::Constant - // + span: $DIR/reference_prop.rs:223:9: 223:15 + // + span: $DIR/reference_prop.rs:259:9: 259:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -371,7 +421,7 @@ StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20 - _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6 StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6 +- StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageLive(_51); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 StorageLive(_52); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 @@ -387,7 +437,7 @@ _56 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18 _55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19 // mir::Constant - // + span: $DIR/reference_prop.rs:231:9: 231:15 + // + span: $DIR/reference_prop.rs:267:9: 267:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -398,34 +448,89 @@ StorageDead(_54); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6 StorageDead(_52); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6 - StorageDead(_51); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 - StorageLive(_57); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:14 - _57 = const 13_usize; // scope 37 at $DIR/reference_prop.rs:+76:17: +76:25 - StorageLive(_58); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 - _58 = &raw const _57; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:29 - StorageLive(_59); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 -- _59 = &raw const (*_58); // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30 -+ _59 = &raw const _57; // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30 - StorageLive(_60); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 -- _60 = (*_59); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 -+ _60 = _57; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 - StorageLive(_61); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 - StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 - _62 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 - _61 = opaque::<()>(move _62) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 +- StorageLive(_57); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageLive(_58); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:14 + _58 = const 13_usize; // scope 37 at $DIR/reference_prop.rs:+76:17: +76:25 +- StorageLive(_59); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 +- _59 = &raw const _58; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:29 +- StorageLive(_60); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 +- _60 = &raw const (*_59); // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30 + StorageLive(_61); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 +- _61 = (*_60); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 ++ _61 = _58; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 + StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 + StorageLive(_63); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 + _63 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 + _62 = opaque::<()>(move _63) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 // mir::Constant - // + span: $DIR/reference_prop.rs:240:9: 240:15 + // + span: $DIR/reference_prop.rs:276:9: 276:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } bb9: { - StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19 - StorageDead(_61); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20 - _0 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6 - StorageDead(_60); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6 - StorageDead(_59); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6 - StorageDead(_58); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6 - StorageDead(_57); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6 - return; // scope 0 at $DIR/reference_prop.rs:+82:2: +82:2 + StorageDead(_63); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19 + StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20 +- _57 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageDead(_61); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_60); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_59); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageDead(_58); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_57); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageLive(_64); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6 + StorageLive(_65); // scope 42 at $DIR/reference_prop.rs:+85:13: +85:14 + _65 = const 5_usize; // scope 42 at $DIR/reference_prop.rs:+85:17: +85:24 +- StorageLive(_66); // scope 43 at $DIR/reference_prop.rs:+86:13: +86:14 +- _66 = &raw const _65; // scope 43 at $DIR/reference_prop.rs:+86:17: +86:29 +- StorageLive(_67); // scope 44 at $DIR/reference_prop.rs:+87:13: +87:14 +- _67 = &_66; // scope 44 at $DIR/reference_prop.rs:+87:17: +87:19 + StorageLive(_68); // scope 45 at $DIR/reference_prop.rs:+88:13: +88:14 +- _68 = (*_66); // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19 ++ _68 = _65; // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19 + StorageLive(_69); // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19 + StorageLive(_70); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18 + _70 = (); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18 + _69 = opaque::<()>(move _70) -> bb10; // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:285:9: 285:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb10: { + StorageDead(_70); // scope 46 at $DIR/reference_prop.rs:+89:18: +89:19 + StorageDead(_69); // scope 46 at $DIR/reference_prop.rs:+89:19: +89:20 +- _64 = const (); // scope 42 at $DIR/reference_prop.rs:+84:5: +90:6 + StorageDead(_68); // scope 45 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_67); // scope 44 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_66); // scope 43 at $DIR/reference_prop.rs:+90:5: +90:6 + StorageDead(_65); // scope 42 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_64); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6 + StorageLive(_71); // scope 47 at $DIR/reference_prop.rs:+94:13: +94:14 + _71 = const 5_usize; // scope 47 at $DIR/reference_prop.rs:+94:17: +94:24 +- StorageLive(_72); // scope 48 at $DIR/reference_prop.rs:+95:13: +95:18 +- _72 = &raw const _71; // scope 48 at $DIR/reference_prop.rs:+95:21: +95:33 +- StorageLive(_73); // scope 49 at $DIR/reference_prop.rs:+96:13: +96:14 +- _73 = &mut _72; // scope 49 at $DIR/reference_prop.rs:+96:17: +96:23 + StorageLive(_74); // scope 50 at $DIR/reference_prop.rs:+97:13: +97:14 +- _74 = (*_72); // scope 50 at $DIR/reference_prop.rs:+97:17: +97:19 ++ _74 = _71; // scope 50 at $DIR/reference_prop.rs:+97:17: +97:19 + StorageLive(_75); // scope 51 at $DIR/reference_prop.rs:+98:9: +98:19 + StorageLive(_76); // scope 51 at $DIR/reference_prop.rs:+98:16: +98:18 + _76 = (); // scope 51 at $DIR/reference_prop.rs:+98:16: +98:18 + _75 = opaque::<()>(move _76) -> bb11; // scope 51 at $DIR/reference_prop.rs:+98:9: +98:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:294:9: 294:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb11: { + StorageDead(_76); // scope 51 at $DIR/reference_prop.rs:+98:18: +98:19 + StorageDead(_75); // scope 51 at $DIR/reference_prop.rs:+98:19: +98:20 + _0 = const (); // scope 47 at $DIR/reference_prop.rs:+93:5: +99:6 + StorageDead(_74); // scope 50 at $DIR/reference_prop.rs:+99:5: +99:6 +- StorageDead(_73); // scope 49 at $DIR/reference_prop.rs:+99:5: +99:6 +- StorageDead(_72); // scope 48 at $DIR/reference_prop.rs:+99:5: +99:6 + StorageDead(_71); // scope 47 at $DIR/reference_prop.rs:+99:5: +99:6 + return; // scope 0 at $DIR/reference_prop.rs:+100:2: +100:2 } } diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff index 44ddbbc3066..8d059de5b87 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff @@ -17,12 +17,12 @@ let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18 let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 let mut _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:18 - let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19 - let mut _24: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18 + let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18 + let mut _24: &&mut usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17 let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 let mut _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:18 - let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19 - let mut _31: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18 + let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18 + let mut _31: *mut &mut usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17 let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 let mut _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:18 let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18 @@ -35,16 +35,25 @@ let _48: &mut T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19 let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18 - let _52: &mut T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 - let mut _53: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32 + let _52: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + let _53: &mut T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 let mut _54: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32 - let _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 - let mut _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let mut _55: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32 + let _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 + let mut _58: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let _59: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + let mut _60: usize; // in scope 0 at $DIR/reference_prop.rs:+76:13: +76:18 + let _64: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19 + let mut _65: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18 + let mut _66: usize; // in scope 0 at $DIR/reference_prop.rs:+85:13: +85:18 + let _70: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19 + let mut _71: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18 scope 1 { debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18 let _5: &mut usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 scope 2 { - debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 +- debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 ++ debug b => &_4; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14 scope 3 { debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 @@ -86,7 +95,7 @@ let mut _27: &mut usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18 scope 13 { debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18 - let _28: &mut &mut usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 + let _28: *mut &mut usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 scope 14 { debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14 let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14 @@ -131,17 +140,52 @@ } } scope 25 { - debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 +- debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 ++ debug a => _1; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14 let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14 scope 26 { debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14 } } scope 27 { - debug a => _52; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14 - let _55: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 + debug a => _53; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14 + let _56: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 scope 28 { - debug b => _55; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14 + debug b => _56; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14 + } + } + scope 29 { + debug a => _60; // in scope 29 at $DIR/reference_prop.rs:+76:13: +76:18 + let _61: &mut usize; // in scope 29 at $DIR/reference_prop.rs:+77:13: +77:14 + scope 30 { +- debug b => _61; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14 ++ debug b => &_60; // in scope 30 at $DIR/reference_prop.rs:+77:13: +77:14 + let _62: &&mut usize; // in scope 30 at $DIR/reference_prop.rs:+78:13: +78:14 + scope 31 { +- debug d => _62; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14 ++ debug d => &&_60; // in scope 31 at $DIR/reference_prop.rs:+78:13: +78:14 + let _63: usize; // in scope 31 at $DIR/reference_prop.rs:+79:13: +79:14 + scope 32 { + debug c => _63; // in scope 32 at $DIR/reference_prop.rs:+79:13: +79:14 + } + } + } + } + scope 33 { + debug a => _66; // in scope 33 at $DIR/reference_prop.rs:+85:13: +85:18 + let mut _67: &mut usize; // in scope 33 at $DIR/reference_prop.rs:+86:13: +86:18 + scope 34 { +- debug b => _67; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18 ++ debug b => &_66; // in scope 34 at $DIR/reference_prop.rs:+86:13: +86:18 + let _68: &mut &mut usize; // in scope 34 at $DIR/reference_prop.rs:+87:13: +87:14 + scope 35 { +- debug d => _68; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14 ++ debug d => &&_66; // in scope 35 at $DIR/reference_prop.rs:+87:13: +87:14 + let _69: usize; // in scope 35 at $DIR/reference_prop.rs:+88:13: +88:14 + scope 36 { + debug c => _69; // in scope 36 at $DIR/reference_prop.rs:+88:13: +88:14 + } + } } } @@ -149,8 +193,8 @@ - StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:18 _4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:21: +3:28 - StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 - _5 = &mut _4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:23 +- StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14 +- _5 = &mut _4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:23 StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14 - _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19 + _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19 @@ -159,7 +203,7 @@ _8 = (); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18 _7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19 // mir::Constant - // + span: $DIR/reference_prop.rs:91:9: 91:15 + // + span: $DIR/reference_prop.rs:109:9: 109:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -168,7 +212,7 @@ StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20 - _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 +- StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 @@ -193,7 +237,7 @@ _17 = (); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18 _16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19 // mir::Constant - // + span: $DIR/reference_prop.rs:102:9: 102:15 + // + span: $DIR/reference_prop.rs:120:9: 120:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -215,18 +259,18 @@ _21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19 StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14 _22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19 - StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19 - StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18 - _24 = (); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18 - _23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19 + StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18 + StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17 + _24 = _21; // scope 11 at $DIR/reference_prop.rs:+26:16: +26:17 + _23 = opaque::<&&mut usize>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:18 // mir::Constant - // + span: $DIR/reference_prop.rs:111:9: 111:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:129:9: 129:15 + // + literal: Const { ty: fn(&&mut usize) {opaque::<&&mut usize>}, val: Value(<ZST>) } } bb3: { - StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19 - StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20 + StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:17: +26:18 + StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19 - _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6 StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6 @@ -239,21 +283,21 @@ StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18 _27 = &mut _26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:27 StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14 - _28 = &mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23 + _28 = &raw mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:27 StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14 _29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19 - StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19 - StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18 - _31 = (); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18 - _30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19 + StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18 + StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17 + _31 = _28; // scope 15 at $DIR/reference_prop.rs:+35:16: +35:17 + _30 = opaque::<*mut &mut usize>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:18 // mir::Constant - // + span: $DIR/reference_prop.rs:120:9: 120:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:138:9: 138:15 + // + literal: Const { ty: fn(*mut &mut usize) {opaque::<*mut &mut usize>}, val: Value(<ZST>) } } bb4: { - StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19 - StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20 + StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:17: +35:18 + StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19 - _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6 StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6 @@ -272,7 +316,7 @@ _37 = move _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17 _36 = opaque::<&mut usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18 // mir::Constant - // + span: $DIR/reference_prop.rs:128:9: 128:15 + // + span: $DIR/reference_prop.rs:146:9: 146:15 // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) } } @@ -302,7 +346,7 @@ _46 = move _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18 _45 = opaque::<&mut usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19 // mir::Constant - // + span: $DIR/reference_prop.rs:141:9: 141:15 + // + span: $DIR/reference_prop.rs:159:9: 159:15 // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) } } @@ -318,8 +362,8 @@ StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 - StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 - _48 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:29 +- StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14 +- _48 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:29 StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14 - _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19 + _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19 @@ -328,7 +372,7 @@ _51 = (); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18 _50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19 // mir::Constant - // + span: $DIR/reference_prop.rs:148:9: 148:15 + // + span: $DIR/reference_prop.rs:166:9: 166:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -337,36 +381,92 @@ StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20 - _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 +- StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 - _52 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:31 - StorageLive(_53); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 -- StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 -- _54 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 -- _53 = &mut (*_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 -+ _53 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 - _2 = move _53; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:32 - StorageDead(_53); // scope 27 at $DIR/reference_prop.rs:+69:31: +69:32 -- StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:32: +69:33 - StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 - _55 = (*_52); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19 - StorageLive(_56); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 - StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 - _57 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 - _56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 +- StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageLive(_53); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14 + _53 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:31 + StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 +- StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 +- _55 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 +- _54 = &mut (*_55); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 ++ _54 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32 + _2 = move _54; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:32 + StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:31: +69:32 +- StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+69:32: +69:33 + StorageLive(_56); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14 + _56 = (*_53); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19 + StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 + StorageLive(_58); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 + _58 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18 + _57 = opaque::<()>(move _58) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19 // mir::Constant - // + span: $DIR/reference_prop.rs:156:9: 156:15 + // + span: $DIR/reference_prop.rs:174:9: 174:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } bb8: { - StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19 - StorageDead(_56); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20 - _0 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 - StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6 - StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 - return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2 + StorageDead(_58); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19 + StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20 +- _52 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageDead(_56); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6 + StorageDead(_53); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageLive(_59); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageLive(_60); // scope 0 at $DIR/reference_prop.rs:+76:13: +76:18 + _60 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+76:21: +76:28 +- StorageLive(_61); // scope 29 at $DIR/reference_prop.rs:+77:13: +77:14 +- _61 = &mut _60; // scope 29 at $DIR/reference_prop.rs:+77:17: +77:23 +- StorageLive(_62); // scope 30 at $DIR/reference_prop.rs:+78:13: +78:14 +- _62 = &_61; // scope 30 at $DIR/reference_prop.rs:+78:17: +78:19 + StorageLive(_63); // scope 31 at $DIR/reference_prop.rs:+79:13: +79:14 +- _63 = (*_61); // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19 ++ _63 = _60; // scope 31 at $DIR/reference_prop.rs:+79:17: +79:19 + StorageLive(_64); // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19 + StorageLive(_65); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18 + _65 = (); // scope 32 at $DIR/reference_prop.rs:+80:16: +80:18 + _64 = opaque::<()>(move _65) -> bb9; // scope 32 at $DIR/reference_prop.rs:+80:9: +80:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:183:9: 183:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb9: { + StorageDead(_65); // scope 32 at $DIR/reference_prop.rs:+80:18: +80:19 + StorageDead(_64); // scope 32 at $DIR/reference_prop.rs:+80:19: +80:20 +- _59 = const (); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageDead(_63); // scope 31 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_62); // scope 30 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_61); // scope 29 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageDead(_60); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_59); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageLive(_66); // scope 0 at $DIR/reference_prop.rs:+85:13: +85:18 + _66 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+85:21: +85:28 +- StorageLive(_67); // scope 33 at $DIR/reference_prop.rs:+86:13: +86:18 +- _67 = &mut _66; // scope 33 at $DIR/reference_prop.rs:+86:21: +86:27 +- StorageLive(_68); // scope 34 at $DIR/reference_prop.rs:+87:13: +87:14 +- _68 = &mut _67; // scope 34 at $DIR/reference_prop.rs:+87:17: +87:23 + StorageLive(_69); // scope 35 at $DIR/reference_prop.rs:+88:13: +88:14 +- _69 = (*_67); // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19 ++ _69 = _66; // scope 35 at $DIR/reference_prop.rs:+88:17: +88:19 + StorageLive(_70); // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19 + StorageLive(_71); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18 + _71 = (); // scope 36 at $DIR/reference_prop.rs:+89:16: +89:18 + _70 = opaque::<()>(move _71) -> bb10; // scope 36 at $DIR/reference_prop.rs:+89:9: +89:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:192:9: 192:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb10: { + StorageDead(_71); // scope 36 at $DIR/reference_prop.rs:+89:18: +89:19 + StorageDead(_70); // scope 36 at $DIR/reference_prop.rs:+89:19: +89:20 + _0 = const (); // scope 0 at $DIR/reference_prop.rs:+84:5: +90:6 + StorageDead(_69); // scope 35 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_68); // scope 34 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_67); // scope 33 at $DIR/reference_prop.rs:+90:5: +90:6 + StorageDead(_66); // scope 0 at $DIR/reference_prop.rs:+90:5: +90:6 + return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2 } } diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff index c55b5eb4bed..c93aa52be11 100644 --- a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff @@ -13,11 +13,11 @@ let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19 let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18 let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 - let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19 - let mut _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18 + let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:18 + let mut _23: &*mut usize; // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:17 let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 - let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19 - let mut _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18 + let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:18 + let mut _30: *mut *mut usize; // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:17 let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18 let mut _36: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17 @@ -27,16 +27,23 @@ let _46: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 let _49: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19 let mut _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18 - let mut _52: *mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:36 - let _54: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 - let mut _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let _51: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + let mut _53: *mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:36 + let _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19 + let mut _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18 + let _57: (); // in scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + let _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19 + let mut _63: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18 + let _68: (); // in scope 0 at $DIR/reference_prop.rs:+89:9: +89:19 + let mut _69: (); // in scope 0 at $DIR/reference_prop.rs:+89:16: +89:18 scope 1 { let mut _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18 scope 2 { debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:18 let _5: *mut usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 scope 3 { - debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 +- debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 ++ debug b => &_4; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14 let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 scope 4 { debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14 @@ -87,7 +94,7 @@ let mut _26: *mut usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18 scope 17 { debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18 - let _27: &mut *mut usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 + let _27: *mut *mut usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 scope 18 { debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14 let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14 @@ -141,7 +148,8 @@ scope 31 { let _47: *mut T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 scope 32 { - debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 +- debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 ++ debug a => _1; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14 let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14 scope 33 { debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14 @@ -149,12 +157,52 @@ } } scope 34 { - let _51: *mut T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 + let _52: *mut T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 scope 35 { - debug a => _51; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14 - let _53: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14 + debug a => _52; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14 + let _54: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14 scope 36 { - debug b => _53; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14 + debug b => _54; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14 + } + } + } + scope 37 { + let mut _58: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:18 + scope 38 { + debug a => _58; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:18 + let _59: *mut usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 + scope 39 { +- debug b => _59; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14 ++ debug b => &_58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14 + let _60: &*mut usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 + scope 40 { +- debug d => _60; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14 ++ debug d => &&_58; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14 + let _61: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 + scope 41 { + debug c => _61; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14 + } + } + } + } + } + scope 42 { + let mut _64: usize; // in scope 42 at $DIR/reference_prop.rs:+85:13: +85:18 + scope 43 { + debug a => _64; // in scope 43 at $DIR/reference_prop.rs:+85:13: +85:18 + let mut _65: *mut usize; // in scope 43 at $DIR/reference_prop.rs:+86:13: +86:18 + scope 44 { +- debug b => _65; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:18 ++ debug b => &_64; // in scope 44 at $DIR/reference_prop.rs:+86:13: +86:18 + let _66: &mut *mut usize; // in scope 44 at $DIR/reference_prop.rs:+87:13: +87:14 + scope 45 { +- debug d => _66; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14 ++ debug d => &&_64; // in scope 45 at $DIR/reference_prop.rs:+87:13: +87:14 + let _67: usize; // in scope 45 at $DIR/reference_prop.rs:+88:13: +88:14 + scope 46 { + debug c => _67; // in scope 46 at $DIR/reference_prop.rs:+88:13: +88:14 + } + } } } } @@ -163,8 +211,8 @@ - StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:18 _4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:21: +3:28 - StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 - _5 = &raw mut _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:27 +- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14 +- _5 = &raw mut _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:27 StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14 - _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19 + _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19 @@ -173,7 +221,7 @@ _8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18 _7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19 // mir::Constant - // + span: $DIR/reference_prop.rs:250:9: 250:15 + // + span: $DIR/reference_prop.rs:304:9: 304:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -182,7 +230,7 @@ StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20 - _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6 StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 +- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 - StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 @@ -203,7 +251,7 @@ _16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18 _15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19 // mir::Constant - // + span: $DIR/reference_prop.rs:261:9: 261:15 + // + span: $DIR/reference_prop.rs:315:9: 315:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -225,18 +273,18 @@ _20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19 StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14 _21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19 - StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19 - StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18 - _23 = (); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18 - _22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19 + StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18 + StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17 + _23 = _20; // scope 14 at $DIR/reference_prop.rs:+26:16: +26:17 + _22 = opaque::<&*mut usize>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:18 // mir::Constant - // + span: $DIR/reference_prop.rs:270:9: 270:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:324:9: 324:15 + // + literal: Const { ty: fn(&*mut usize) {opaque::<&*mut usize>}, val: Value(<ZST>) } } bb3: { - StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19 - StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20 + StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:17: +26:18 + StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19 - _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6 StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6 StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6 @@ -249,21 +297,21 @@ StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18 _26 = &raw mut _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:31 StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14 - _27 = &mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23 + _27 = &raw mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:27 StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14 _28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19 - StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19 - StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18 - _30 = (); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18 - _29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19 + StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18 + StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17 + _30 = _27; // scope 19 at $DIR/reference_prop.rs:+35:16: +35:17 + _29 = opaque::<*mut *mut usize>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:18 // mir::Constant - // + span: $DIR/reference_prop.rs:279:9: 279:15 - // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + // + span: $DIR/reference_prop.rs:333:9: 333:15 + // + literal: Const { ty: fn(*mut *mut usize) {opaque::<*mut *mut usize>}, val: Value(<ZST>) } } bb4: { - StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19 - StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20 + StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:17: +35:18 + StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19 - _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6 StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6 StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6 @@ -282,7 +330,7 @@ _36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17 _35 = opaque::<*mut usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18 // mir::Constant - // + span: $DIR/reference_prop.rs:287:9: 287:15 + // + span: $DIR/reference_prop.rs:341:9: 341:15 // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) } } @@ -312,7 +360,7 @@ _45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18 _44 = opaque::<*mut usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19 // mir::Constant - // + span: $DIR/reference_prop.rs:300:9: 300:15 + // + span: $DIR/reference_prop.rs:354:9: 354:15 // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) } } @@ -328,8 +376,8 @@ StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6 - StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 - StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 - _47 = &raw mut (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:33 +- StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14 +- _47 = &raw mut (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:33 StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14 - _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19 + _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19 @@ -338,7 +386,7 @@ _50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18 _49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19 // mir::Constant - // + span: $DIR/reference_prop.rs:307:9: 307:15 + // + span: $DIR/reference_prop.rs:361:9: 361:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } @@ -347,32 +395,88 @@ StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20 - _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6 StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6 +- StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 - StorageLive(_51); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 - _51 = &raw mut (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:35 - StorageLive(_52); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36 - _52 = &raw mut (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36 - _2 = move _52; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:36 - StorageDead(_52); // scope 35 at $DIR/reference_prop.rs:+69:35: +69:36 - StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14 - _53 = (*_51); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19 - StorageLive(_54); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19 - StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18 - _55 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18 - _54 = opaque::<()>(move _55) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19 +- StorageLive(_51); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageLive(_52); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 + _52 = &raw mut (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:35 + StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36 + _53 = &raw mut (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36 + _2 = move _53; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:36 + StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+69:35: +69:36 + StorageLive(_54); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14 + _54 = (*_52); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19 + StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19 + StorageLive(_56); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18 + _56 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18 + _55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19 // mir::Constant - // + span: $DIR/reference_prop.rs:315:9: 315:15 + // + span: $DIR/reference_prop.rs:369:9: 369:15 // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } } bb8: { - StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19 - StorageDead(_54); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20 - _0 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6 - StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6 - StorageDead(_51); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6 - return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2 + StorageDead(_56); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19 + StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20 +- _51 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6 + StorageDead(_54); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6 + StorageDead(_52); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageDead(_51); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6 +- StorageLive(_57); // scope 0 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageLive(_58); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:18 + _58 = const 5_usize; // scope 37 at $DIR/reference_prop.rs:+76:21: +76:28 +- StorageLive(_59); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14 +- _59 = &raw mut _58; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:27 +- StorageLive(_60); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14 +- _60 = &_59; // scope 39 at $DIR/reference_prop.rs:+78:17: +78:19 + StorageLive(_61); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14 +- _61 = (*_59); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 ++ _61 = _58; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19 + StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 + StorageLive(_63); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 + _63 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18 + _62 = opaque::<()>(move _63) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:378:9: 378:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb9: { + StorageDead(_63); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19 + StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20 +- _57 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6 + StorageDead(_61); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_60); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_59); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageDead(_58); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6 +- StorageDead(_57); // scope 0 at $DIR/reference_prop.rs:+81:5: +81:6 + StorageLive(_64); // scope 42 at $DIR/reference_prop.rs:+85:13: +85:18 + _64 = const 5_usize; // scope 42 at $DIR/reference_prop.rs:+85:21: +85:28 +- StorageLive(_65); // scope 43 at $DIR/reference_prop.rs:+86:13: +86:18 +- _65 = &raw mut _64; // scope 43 at $DIR/reference_prop.rs:+86:21: +86:31 +- StorageLive(_66); // scope 44 at $DIR/reference_prop.rs:+87:13: +87:14 +- _66 = &mut _65; // scope 44 at $DIR/reference_prop.rs:+87:17: +87:23 + StorageLive(_67); // scope 45 at $DIR/reference_prop.rs:+88:13: +88:14 +- _67 = (*_65); // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19 ++ _67 = _64; // scope 45 at $DIR/reference_prop.rs:+88:17: +88:19 + StorageLive(_68); // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19 + StorageLive(_69); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18 + _69 = (); // scope 46 at $DIR/reference_prop.rs:+89:16: +89:18 + _68 = opaque::<()>(move _69) -> bb10; // scope 46 at $DIR/reference_prop.rs:+89:9: +89:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:387:9: 387:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb10: { + StorageDead(_69); // scope 46 at $DIR/reference_prop.rs:+89:18: +89:19 + StorageDead(_68); // scope 46 at $DIR/reference_prop.rs:+89:19: +89:20 + _0 = const (); // scope 42 at $DIR/reference_prop.rs:+84:5: +90:6 + StorageDead(_67); // scope 45 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_66); // scope 44 at $DIR/reference_prop.rs:+90:5: +90:6 +- StorageDead(_65); // scope 43 at $DIR/reference_prop.rs:+90:5: +90:6 + StorageDead(_64); // scope 42 at $DIR/reference_prop.rs:+90:5: +90:6 + return; // scope 0 at $DIR/reference_prop.rs:+91:2: +91:2 } } diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs index 93f8d1df8e8..4083b45470b 100644 --- a/tests/mir-opt/reference_prop.rs +++ b/tests/mir-opt/reference_prop.rs @@ -33,16 +33,16 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { let b = &a; let d = &b; let c = *b; // `b` is immutably borrowed, we know its value, but do not propagate it - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through a borrowed reference. { let a = 5_usize; let mut b = &a; - let d = &mut b; + let d = &raw mut b; let c = *b; // `b` is mutably borrowed, we cannot know its value. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through an escaping borrow. @@ -80,6 +80,24 @@ fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { let b = *a; // This should not be optimized. opaque(()); } + + // Fixed-point propagation through a borrowed reference. + { + let a = 5_usize; + let b = &a; + let d = &b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } + + // Fixed-point propagation through a borrowed reference. + { + let a = 5_usize; + let mut b = &a; + let d = &mut b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } } fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a mut T) { @@ -108,16 +126,16 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m let b = &mut a; let d = &b; let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through a borrowed reference. { let mut a = 5_usize; let mut b = &mut a; - let d = &mut b; + let d = &raw mut b; let c = *b; // `b` is mutably borrowed, we cannot know its value. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through an escaping borrow. @@ -155,6 +173,24 @@ fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a m let b = *a; // This should not be optimized. opaque(()); } + + // Fixed-point propagation through a borrowed reference. + { + let mut a = 5_usize; + let b = &mut a; + let d = &b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } + + // Fixed-point propagation through a borrowed reference. + { + let mut a = 5_usize; + let mut b = &mut a; + let d = &mut b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } } fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *const T) { @@ -183,16 +219,16 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con let b = &raw const a; let d = &b; let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through a borrowed reference. unsafe { let a = 5_usize; let mut b = &raw const a; - let d = &mut b; + let d = &raw mut b; let c = *b; // `b` is mutably borrowed, we cannot know its value. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through an escaping borrow. @@ -239,6 +275,24 @@ fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *con let e = *c; opaque(()); } + + // Fixed-point propagation through a borrowed reference. + unsafe { + let a = 5_usize; + let b = &raw const a; + let d = &b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } + + // Fixed-point propagation through a borrowed reference. + unsafe { + let a = 5_usize; + let mut b = &raw const a; + let d = &mut b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } } fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) { @@ -267,16 +321,16 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) let b = &raw mut a; let d = &b; let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through a borrowed reference. unsafe { let mut a = 5_usize; let mut b = &raw mut a; - let d = &mut b; + let d = &raw mut b; let c = *b; // `b` is mutably borrowed, we cannot know its value. - opaque(()); + opaque(d); // prevent `d` from being removed. } // Propagation through an escaping borrow. @@ -314,6 +368,24 @@ fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) let b = *a; // This should not be optimized. opaque(()); } + + // Fixed-point propagation through a borrowed reference. + unsafe { + let mut a = 5_usize; + let b = &raw mut a; + let d = &b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } + + // Fixed-point propagation through a borrowed reference. + unsafe { + let mut a = 5_usize; + let mut b = &raw mut a; + let d = &mut b; // first round promotes debuginfo for `d` + let c = *b; // second round propagates this dereference + opaque(()); + } } #[custom_mir(dialect = "runtime", phase = "post-cleanup")] @@ -456,6 +528,40 @@ fn unique_with_copies() { unsafe { opaque(*y) }; } +fn debuginfo() { + struct T(u8); + + let ref_mut_u8 = &mut 5_u8; + let field = &T(0).0; + + // Verify that we don't emit `&*` in debuginfo. + let reborrow = &*ref_mut_u8; + + match Some(0) { + None => {} + Some(ref variant_field) => {} + } + + // `constant_index_from_end` and `subslice` should not be promoted, as their value depends + // on the slice length. + if let [_, ref constant_index, subslice @ .., ref constant_index_from_end] = &[6; 10][..] { + } + + let multiple_borrow = &&&mut T(6).0; +} + +fn many_debuginfo() { + let a = 0; + + // Verify that we do not ICE on deeply nested borrows. + let many_borrow = + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&a; +} + fn main() { let mut x = 5_usize; let mut y = 7_usize; @@ -469,6 +575,8 @@ fn main() { maybe_dead(true); mut_raw_then_mut_shr(); unique_with_copies(); + debuginfo(); + many_debuginfo(); } // EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff @@ -481,3 +589,4 @@ fn main() { // EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff // EMIT_MIR reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff // EMIT_MIR reference_prop.unique_with_copies.ReferencePropagation.diff +// EMIT_MIR reference_prop.debuginfo.ReferencePropagation.diff diff --git a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff index 2cda2409e80..b754aff4755 100644 --- a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff @@ -10,7 +10,8 @@ let _6: (); // in scope 0 at $DIR/reference_prop.rs:+9:14: +9:24 let mut _7: i32; // in scope 0 at $DIR/reference_prop.rs:+9:21: +9:23 scope 1 { - debug y => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10 +- debug y => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10 ++ debug y => _3; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10 scope 5 { } } @@ -25,7 +26,7 @@ } bb0: { - StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:10 +- StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+2:13: +2:18 _2 = const 0_i32; // scope 0 at $DIR/reference_prop.rs:+2:21: +2:22 - StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:13: +3:14 @@ -35,14 +36,14 @@ _5 = (*_3); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27 _4 = opaque::<i32>(move _5) -> bb1; // scope 4 at $DIR/reference_prop.rs:+5:18: +5:28 // mir::Constant - // + span: $DIR/reference_prop.rs:452:18: 452:24 + // + span: $DIR/reference_prop.rs:524:18: 524:24 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } bb1: { StorageDead(_5); // scope 4 at $DIR/reference_prop.rs:+5:27: +5:28 StorageDead(_4); // scope 3 at $DIR/reference_prop.rs:+5:30: +5:31 - _1 = _3; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:10 +- _1 = _3; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:10 - StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6 StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6 StorageLive(_6); // scope 1 at $DIR/reference_prop.rs:+9:5: +9:26 @@ -51,7 +52,7 @@ + _7 = (*_3); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23 _6 = opaque::<i32>(move _7) -> bb2; // scope 5 at $DIR/reference_prop.rs:+9:14: +9:24 // mir::Constant - // + span: $DIR/reference_prop.rs:456:14: 456:20 + // + span: $DIR/reference_prop.rs:528:14: 528:20 // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } } @@ -59,7 +60,7 @@ StorageDead(_7); // scope 5 at $DIR/reference_prop.rs:+9:23: +9:24 StorageDead(_6); // scope 1 at $DIR/reference_prop.rs:+9:26: +9:27 _0 = const (); // scope 0 at $DIR/reference_prop.rs:+0:25: +10:2 - StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+10:1: +10:2 +- StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+10:1: +10:2 return; // scope 0 at $DIR/reference_prop.rs:+10:2: +10:2 } } diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff index 7ad1ccf28a6..afdcf57815f 100644 --- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff +++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.DestinationPropagation.diff @@ -3,136 +3,79 @@ fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool { let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40 - let _3: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 - let _4: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 - let _5: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 - let _6: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 - let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56 - let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46 - let mut _9: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41 - let mut _10: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46 - let _11: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46 - let mut _12: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56 - let mut _13: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51 - let mut _14: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56 - let _15: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56 - let mut _16: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76 - let mut _17: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66 - let mut _18: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61 - let mut _19: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66 - let _20: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66 - let mut _21: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76 - let mut _22: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71 - let mut _23: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 - let _24: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 - let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 - let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 - let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 - let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 + let mut _3: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56 + let mut _4: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46 + let mut _5: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56 + let mut _6: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76 + let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66 + let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76 + let mut _9: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 + let mut _10: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 + let mut _11: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 + let mut _12: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 scope 1 { -- debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 -- debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 -- debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 -- debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 -+ debug a => _20; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 -+ debug b => _15; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 -+ debug c => _11; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 -+ debug d => _24; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 + debug a => &((*_9).0: usize); // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 + debug b => &((*_10).1: usize); // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 + debug c => &((*_11).2: usize); // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 + debug d => &((*_12).3: usize); // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46 - debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &&((*_9).0: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &&((*_11).2: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _31: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _32: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &((*_9).0: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &((*_11).2: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _13: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _14: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66 - debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _33: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _34: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &&((*_11).2: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &&((*_9).0: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _33; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _34; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _35: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _36: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &((*_11).2: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &((*_9).0: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _15: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _16: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56 - debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _37: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _38: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &&((*_12).3: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &&((*_10).1: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _37; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _38; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _39: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _40: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &((*_12).3: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &((*_10).1: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _17: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _18: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76 - debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _41: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _42: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &&((*_10).1: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &&((*_12).3: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _41; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _42; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _43: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _44: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug self => &((*_10).1: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + debug other => &((*_12).3: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _19: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _20: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL } } } bb0: { -- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 - _25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 -- _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 -- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 -+ _20 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 - _26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 -- _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 -- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 -+ _15 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 - _27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 -- _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 -- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 -+ _11 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 - _28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 -- _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 -- StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 -+ _24 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 + _9 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 + _10 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 + _11 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 + _12 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 +- StorageLive(_3); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 + nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 - StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46 - StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41 - StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -- StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -- _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -- _29 = deref_copy _3; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -+ _29 = deref_copy _20; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - _30 = deref_copy _11; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - _31 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - _32 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - _8 = Le(move _31, move _32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 + StorageLive(_4); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46 + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + _13 = ((*_9).0: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + _14 = ((*_11).2: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + _4 = Le(move _13, move _14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_14); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL + switchInt(move _4) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 } bb1: { @@ -141,127 +84,80 @@ } bb2: { -- StorageLive(_16); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 +- StorageLive(_6); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 - StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66 - StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61 - StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -- StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -- _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -- _33 = deref_copy _5; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -+ _33 = deref_copy _11; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - _34 = deref_copy _20; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - _35 = (*_33); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - _36 = (*_34); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - _17 = Le(move _35, move _36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 + StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66 + StorageLive(_15); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _15 = ((*_11).2: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _16 = ((*_9).0: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + _7 = Le(move _15, move _16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_16); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_15); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL + switchInt(move _7) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 } bb3: { -- StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_6); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_3); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76 } bb4: { -- StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageDead(_5); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 + nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 + StorageDead(_4); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 } bb5: { -- StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56 +- StorageLive(_5); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56 + nop; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56 - StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51 - StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- _37 = deref_copy _6; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -+ _37 = deref_copy _24; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - _38 = deref_copy _15; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - _39 = (*_37); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - _40 = (*_38); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - _12 = Le(move _39, move _40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- _7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 -- StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 + StorageLive(_17); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + _17 = ((*_12).3: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + _18 = ((*_10).1: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + _5 = Le(move _17, move _18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_18); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_17); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _3 = move _5; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 +- StorageDead(_5); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 + nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 + nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 -+ switchInt(move _12) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + StorageDead(_4); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- switchInt(move _3) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 ++ switchInt(move _5) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 } bb6: { -- _16 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 +- _6 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 + _0 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 } bb7: { -- StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76 +- StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76 - StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71 - StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- _41 = deref_copy _4; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -+ _41 = deref_copy _15; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - _42 = deref_copy _24; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - _43 = (*_41); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageLive(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - _44 = (*_42); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _21 = Le(move _43, move _44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _0 = Le(move _43, move _44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- _16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 + StorageLive(_19); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + _19 = ((*_10).1: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageLive(_20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + _20 = ((*_12).3: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _8 = Le(move _19, move _20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _0 = Le(move _19, move _20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_20); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL + StorageDead(_19); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _6 = move _8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 } bb8: { -- StorageDead(_21); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_17); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- _0 = move _16; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- _0 = move _6; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 } diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff index f6350b3812a..2534eeef432 100644 --- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff +++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff @@ -38,54 +38,74 @@ let mut _49: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _50: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 1 { - debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 - debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 - debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 - debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 +- debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 +- debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 +- debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 +- debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 ++ debug a => &((*_25).0: usize); // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 ++ debug b => &((*_26).1: usize); // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 ++ debug c => &((*_27).2: usize); // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34 ++ debug d => &((*_28).3: usize); // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37 scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46 - debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &&((*_25).0: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &&((*_27).2: usize); // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &((*_25).0: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &((*_27).2: usize); // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _33: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _34: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66 - debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &&((*_27).2: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &&((*_25).0: usize); // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _35: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _36: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &((*_27).2: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &((*_25).0: usize); // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _39: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _40: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56 - debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &&((*_28).3: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &&((*_26).1: usize); // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _41: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _42: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &((*_28).3: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &((*_26).1: usize); // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _45: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _46: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL } } scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76 - debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &&((*_26).1: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &&((*_28).3: usize); // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _47: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _48: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL - debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => &((*_26).1: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => &((*_28).3: usize); // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _51: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _52: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL } @@ -93,40 +113,40 @@ } bb0: { - StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 +- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 _25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 - _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 - StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 +- _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28 +- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 _26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 - _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 - StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 +- _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31 +- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 _27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 - _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 - StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 +- _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34 +- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 _28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 - _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 +- _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37 StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46 - StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41 - _9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41 - StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - _10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41 +- _9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41 +- StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- _10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - _29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - _30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _29 = deref_copy _3; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _30 = deref_copy _11; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - _33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _33 = ((*_25).0: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - _34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _34 = ((*_27).2: usize); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL _8 = Le(move _33, move _34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 - StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 +- StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 } @@ -138,36 +158,36 @@ bb2: { StorageLive(_16); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66 - StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61 - _18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61 - StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - _19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61 +- _18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61 +- StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- _19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - _35 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - _36 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _35 = deref_copy _5; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _36 = deref_copy _20; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - _39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _39 = ((*_27).2: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - _40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _40 = ((*_25).0: usize); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL _17 = Le(move _39, move _40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 - StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 +- StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 } bb3: { StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76 return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76 } @@ -180,26 +200,26 @@ bb5: { StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56 - StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51 - _13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51 - StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - _14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51 +- _13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51 +- StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- _14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - _41 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - _42 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _41 = deref_copy _6; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _42 = deref_copy _15; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - _45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _45 = ((*_28).3: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - _46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _46 = ((*_26).1: usize); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL _12 = Le(move _45, move _46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 - StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 +- StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 _7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 @@ -213,26 +233,26 @@ bb7: { StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76 - StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71 - _22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71 - StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - _23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71 +- _22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71 +- StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- _23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - _47 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - _48 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _47 = deref_copy _4; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _48 = deref_copy _24; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - _51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _51 = ((*_26).1: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - _52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _52 = ((*_28).3: usize); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL _21 = Le(move _51, move _52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL - StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 - StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 +- StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 _16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76 } diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir index 2af864998cb..4b2a16b50b4 100644 --- a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir +++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir @@ -3,16 +3,13 @@ fn process_void(_1: *const Void) -> () { debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26 let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41 - let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + debug _input => _1; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 } scope 2 { } bb0: { - StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2 return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2 } } diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 7bd7bb7c1ea..12cbb5a5f12 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -24,8 +24,8 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_interface::interface::Compiler; use rustc_interface::{Config, Queries}; -use rustc_middle::ty::query::query_values::mir_borrowck; -use rustc_middle::ty::query::{ExternProviders, Providers}; +use rustc_middle::query::query_values::mir_borrowck; +use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use std::cell::RefCell; diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index da46a90df90..90f7160b724 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -47,89 +47,89 @@ reload: wait-for: "#search-tabs" assert-css: ( "#search-tabs > button > .count", - {"color": "rgb(136, 136, 136)"}, + {"color": "#888"}, ALL, ) assert-css: ( "//*[@class='desc'][text()='Just a normal struct.']", - {"color": "rgb(197, 197, 197)"}, + {"color": "#c5c5c5"}, ) assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(0, 150, 207)"}, + {"color": "#0096cf"}, ) // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} + {"border-bottom-color": "#aaa3"} ) // Checking the color of "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", - {"color": "rgb(120, 135, 151)"}, + {"color": "#788797"}, ) -store-value: (entry_color, "rgb(0, 150, 207)") // color of the search entry -store-value: (hover_entry_color, "rgb(255, 255, 255)") // color of the hovered/focused search entry -store-value: (background_color, "rgba(0, 0, 0, 0)") // background color -store-value: (hover_background_color, "rgb(60, 60, 60)") // hover background color +store-value: (entry_color, "#0096cf") // color of the search entry +store-value: (hover_entry_color, "#fff") // color of the hovered/focused search entry +store-value: (background_color, "transparent") // background color +store-value: (hover_background_color, "#3c3c3c") // hover background color call-function: ( "check-result-color", ( "keyword", // item kind - "rgb(57, 175, 215)", // color of item kind - "rgb(57, 175, 215)", // color of hovered/focused item kind + "#39afd7", // color of item kind + "#39afd7", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "struct", // item kind - "rgb(255, 160, 165)", // color of item kind - "rgb(255, 160, 165)", // color of hovered/focused item kind + "#ffa0a5", // color of item kind + "#ffa0a5", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "associatedtype", // item kind - "rgb(57, 175, 215)", // color of item kind - "rgb(57, 175, 215)", // color of hovered/focused item kind + "#39afd7", // color of item kind + "#39afd7", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "tymethod", // item kind - "rgb(253, 214, 135)", // color of item kind - "rgb(253, 214, 135)", // color of hovered/focused item kind + "#fdd687", // color of item kind + "#fdd687", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "method", // item kind - "rgb(253, 214, 135)", // color of item kind - "rgb(253, 214, 135)", // color of hovered/focused item kind + "#fdd687", // color of item kind + "#fdd687", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "structfield", // item kind - "rgb(0, 150, 207)", // color of item kind - "rgb(255, 255, 255)", // color of hovered/focused item kind + "#0096cf", // color of item kind + "#fff", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "macro", // item kind - "rgb(163, 122, 204)", // color of item kind - "rgb(163, 122, 204)", // color of hovered/focused item kind + "#a37acc", // color of item kind + "#a37acc", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "fn", // item kind - "rgb(253, 214, 135)", // color of item kind - "rgb(253, 214, 135)", // color of hovered/focused item kind + "#fdd687", // color of item kind + "#fdd687", // color of hovered/focused item kind ), ) @@ -138,7 +138,7 @@ move-cursor-to: ".search-input" focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, + {"color": "#0096cf", "background-color": "transparent"}, ALL, ) @@ -146,11 +146,11 @@ assert-css: ( move-cursor-to: "//*[@class='desc'][text()='Just a normal struct.']" assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(255, 255, 255)"}, + {"color": "#fff"}, ) assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, + {"color": "#fff", "background-color": "rgb(60, 60, 60)"}, ) // Dark theme @@ -164,89 +164,89 @@ reload: wait-for: "#search-tabs" assert-css: ( "#search-tabs > button > .count", - {"color": "rgb(136, 136, 136)"}, + {"color": "#888"}, ALL, ) assert-css: ( "//*[@class='desc'][text()='Just a normal struct.']", - {"color": "rgb(221, 221, 221)"}, + {"color": "#ddd"}, ) assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(221, 221, 221)"}, + {"color": "#ddd"}, ) // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} + {"border-bottom-color": "#aaa3"} ) // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", - {"color": "rgb(221, 221, 221)"}, + {"color": "#ddd"}, ) -store-value: (entry_color, "rgb(221, 221, 221)") // color of the search entry -store-value: (hover_entry_color, "rgb(221, 221, 221)") // color of the hovered/focused search entry -store-value: (background_color, "rgba(0, 0, 0, 0)") // background color -store-value: (hover_background_color, "rgb(97, 97, 97)") // hover background color +store-value: (entry_color, "#ddd") // color of the search entry +store-value: (hover_entry_color, "#ddd") // color of the hovered/focused search entry +store-value: (background_color, "transparent") // background color +store-value: (hover_background_color, "#616161") // hover background color call-function: ( "check-result-color", ( "keyword", // item kind - "rgb(210, 153, 29)", // color of item kind - "rgb(210, 153, 29)", // color of hovered/focused item kind + "#d2991d", // color of item kind + "#d2991d", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "struct", // item kind - "rgb(45, 191, 184)", // color of item kind - "rgb(45, 191, 184)", // color of hovered/focused item kind + "#2dbfb8", // color of item kind + "#2dbfb8", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "associatedtype", // item kind - "rgb(210, 153, 29)", // color of item kind - "rgb(210, 153, 29)", // color of hovered/focused item kind + "#d2991d", // color of item kind + "#d2991d", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "tymethod", // item kind - "rgb(43, 171, 99)", // color of item kind - "rgb(43, 171, 99)", // color of hovered/focused item kind + "#2bab63", // color of item kind + "#2bab63", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "method", // item kind - "rgb(43, 171, 99)", // color of item kind - "rgb(43, 171, 99)", // color of hovered/focused item kind + "#2bab63", // color of item kind + "#2bab63", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "structfield", // item kind - "rgb(221, 221, 221)", // color of item kind - "rgb(221, 221, 221)", // color of hovered/focused item kind + "#ddd", // color of item kind + "#ddd", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "macro", // item kind - "rgb(9, 189, 0)", // color of item kind - "rgb(9, 189, 0)", // color of hovered/focused item kind + "#09bd00", // color of item kind + "#09bd00", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "fn", // item kind - "rgb(43, 171, 99)", // color of item kind - "rgb(43, 171, 99)", // color of hovered/focused item kind + "#2bab63", // color of item kind + "#2bab63", // color of hovered/focused item kind ), ) @@ -255,7 +255,7 @@ move-cursor-to: ".search-input" focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, + {"color": "#ddd", "background-color": "transparent"}, ) // Light theme @@ -266,89 +266,89 @@ reload: wait-for: "#search-tabs" assert-css: ( "#search-tabs > button > .count", - {"color": "rgb(136, 136, 136)"}, + {"color": "#888"}, ALL, ) assert-css: ( "//*[@class='desc'][text()='Just a normal struct.']", - {"color": "rgb(0, 0, 0)"}, + {"color": "#000"}, ) assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(0, 0, 0)"}, + {"color": "#000"}, ) // Checking the color of the bottom border. assert-css: ( ".search-results > a", - {"border-bottom-color": "rgba(170, 170, 170, 0.2)"} + {"border-bottom-color": "#aaa3"} ) // Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", - {"color": "rgb(0, 0, 0)"}, + {"color": "#000"}, ) -store-value: (entry_color, "rgb(0, 0, 0)") // color of the search entry -store-value: (hover_entry_color, "rgb(0, 0, 0)") // color of the hovered/focused search entry -store-value: (background_color, "rgba(0, 0, 0, 0)") // background color -store-value: (hover_background_color, "rgb(204, 204, 204)") // hover background color +store-value: (entry_color, "#000") // color of the search entry +store-value: (hover_entry_color, "#000") // color of the hovered/focused search entry +store-value: (background_color, "transparent") // background color +store-value: (hover_background_color, "#ccc") // hover background color call-function: ( "check-result-color", ( "keyword", // item kind - "rgb(56, 115, 173)", // color of item kind - "rgb(56, 115, 173)", // color of hovered/focused item kind + "#3873ad", // color of item kind + "#3873ad", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "struct", // item kind - "rgb(173, 55, 138)", // color of item kind - "rgb(173, 55, 138)", // color of hovered/focused item kind + "#ad378a", // color of item kind + "#ad378a", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "associatedtype", // item kind - "rgb(56, 115, 173)", // color of item kind - "rgb(56, 115, 173)", // color of hovered/focused item kind + "#3873ad", // color of item kind + "#3873ad", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "tymethod", // item kind - "rgb(173, 124, 55)", // color of item kind - "rgb(173, 124, 55)", // color of hovered/focused item kind + "#ad7c37", // color of item kind + "#ad7c37", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "method", // item kind - "rgb(173, 124, 55)", // color of item kind - "rgb(173, 124, 55)", // color of hovered/focused item kind + "#ad7c37", // color of item kind + "#ad7c37", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "structfield", // item kind - "rgb(0, 0, 0)", // color of item kind - "rgb(0, 0, 0)", // color of hovered/focused item kind + "#000", // color of item kind + "#000", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "macro", // item kind - "rgb(6, 128, 0)", // color of item kind - "rgb(6, 128, 0)", // color of hovered/focused item kind + "#068000", // color of item kind + "#068000", // color of hovered/focused item kind ), ) call-function: ( "check-result-color", ( "fn", // item kind - "rgb(173, 124, 55)", // color of item kind - "rgb(173, 124, 55)", // color of hovered/focused item kind + "#ad7c37", // color of item kind + "#ad7c37", // color of hovered/focused item kind ), ) @@ -357,7 +357,7 @@ move-cursor-to: ".search-input" focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, + {"color": "#000", "background-color": "transparent"}, ) // Check the alias. @@ -386,16 +386,16 @@ define-function: ( call-function: ("check-alias", { "theme": "ayu", - "alias": "rgb(197, 197, 197)", - "grey": "rgb(153, 153, 153)", + "alias": "#c5c5c5", + "grey": "#999", }) call-function: ("check-alias", { "theme": "dark", - "alias": "rgb(255, 255, 255)", - "grey": "rgb(204, 204, 204)", + "alias": "#fff", + "grey": "#ccc", }) call-function: ("check-alias", { "theme": "light", - "alias": "rgb(0, 0, 0)", - "grey": "rgb(153, 153, 153)", + "alias": "#000", + "grey": "#999", }) diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs new file mode 100644 index 00000000000..ed63def93df --- /dev/null +++ b/tests/rustdoc-json/type/inherent_associated_type.rs @@ -0,0 +1,29 @@ +// ignore-tidy-linelength +#![feature(inherent_associated_types)] +#![feature(no_core)] +#![allow(incomplete_features)] +#![no_core] + +// @set OwnerMetadata = '$.index[*][?(@.name=="OwnerMetadata")].id' +pub struct OwnerMetadata; +// @set Owner = '$.index[*][?(@.name=="Owner")].id' +pub struct Owner; + +pub fn create() -> Owner::Metadata { + OwnerMetadata +} +// @is '$.index[*][?(@.name=="create")].inner.decl.output.kind' '"qualified_path"' +// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.name' '"Metadata"' +// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.trait' null +// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.kind' '"resolved_path"' +// @is '$.index[*][?(@.name=="create")].inner.decl.output.inner.self_type.inner.id' $Owner + +/// impl +impl Owner { + /// iat + pub type Metadata = OwnerMetadata; +} +// @set iat = '$.index[*][?(@.docs=="iat")].id' +// @is '$.index[*][?(@.docs=="impl")].inner.items[*]' $iat +// @is '$.index[*][?(@.docs=="iat")].kind' '"assoc_type"' +// @is '$.index[*][?(@.docs=="iat")].inner.default.inner.id' $OwnerMetadata diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs new file mode 100644 index 00000000000..a089600b692 --- /dev/null +++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs @@ -0,0 +1,21 @@ +// ignore-tidy-linelength +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// @set Carrier = '$.index[*][?(@.name=="Carrier")].id' +pub struct Carrier<'a>(&'a ()); + +// @is '$.index[*][?(@.name=="User")].inner.type.kind' '"function_pointer"' +// @is '$.index[*][?(@.name=="User")].inner.type.inner.generic_params[*].name' \""'b"\" +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].kind' '"qualified_path"' +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.id' $Carrier +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.self_type.inner.args.angle_bracketed.args[0].lifetime' \""'b"\" +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.name' '"Focus"' +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.trait' null +// @is '$.index[*][?(@.name=="User")].inner.type.inner.decl.inputs[0][1].inner.args.angle_bracketed.args[0].type.inner' '"i32"' + +pub type User = for<'b> fn(Carrier<'b>::Focus<i32>); + +impl<'a> Carrier<'a> { + pub type Focus<T> = &'a mut T; +} diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs new file mode 100644 index 00000000000..30c68bfe56c --- /dev/null +++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs @@ -0,0 +1,33 @@ +// ignore-tidy-linelength +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// @set Parametrized = '$.index[*][?(@.name=="Parametrized")].id' +pub struct Parametrized<T>(T); + +// @is '$.index[*][?(@.name=="Test")].inner.type.kind' '"qualified_path"' +// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.id' $Parametrized +// @is '$.index[*][?(@.name=="Test")].inner.type.inner.self_type.inner.args.angle_bracketed.args[0].type' '{"inner": "i32", "kind": "primitive"}' +// @is '$.index[*][?(@.name=="Test")].inner.type.inner.name' '"Proj"' +// @is '$.index[*][?(@.name=="Test")].inner.type.inner.trait' null +pub type Test = Parametrized<i32>::Proj; + +/// param_bool +impl Parametrized<bool> { + /// param_bool_proj + pub type Proj = (); +} + +/// param_i32 +impl Parametrized<i32> { + /// param_i32_proj + pub type Proj = String; +} + +// @set param_bool = '$.index[*][?(@.docs=="param_bool")].id' +// @set param_i32 = '$.index[*][?(@.docs=="param_i32")].id' +// @set param_bool_proj = '$.index[*][?(@.docs=="param_bool_proj")].id' +// @set param_i32_proj = '$.index[*][?(@.docs=="param_i32_proj")].id' + +// @is '$.index[*][?(@.docs=="param_bool")].inner.items[*]' $param_bool_proj +// @is '$.index[*][?(@.docs=="param_i32")].inner.items[*]' $param_i32_proj diff --git a/tests/ui/attr-bad-crate-attr.rc b/tests/ui/attr-bad-crate-attr.rs index 89ba26dfd6f..89ba26dfd6f 100644 --- a/tests/ui/attr-bad-crate-attr.rc +++ b/tests/ui/attr-bad-crate-attr.rs diff --git a/tests/ui/attr-bad-crate-attr.stderr b/tests/ui/attr-bad-crate-attr.stderr new file mode 100644 index 00000000000..ff420eeea4a --- /dev/null +++ b/tests/ui/attr-bad-crate-attr.stderr @@ -0,0 +1,8 @@ +error: expected item after attributes + --> $DIR/attr-bad-crate-attr.rs:4:1 + | +LL | #[attr = "val"] // Unterminated + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs new file mode 100644 index 00000000000..addbe5d658a --- /dev/null +++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs @@ -0,0 +1,23 @@ +// compile-flags: -Zdrop-tracking-mir +// edition:2021 + +use std::future::Future; + +trait Client { + type Connecting<'a>: Future + Send + where + Self: 'a; + + fn connect(&'_ self) -> Self::Connecting<'a>; + //~^ ERROR use of undeclared lifetime name `'a` +} + +fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send +where + C: Client + Send + Sync, +{ + async move { c.connect().await } + //~^ ERROR `C` does not live long enough +} + +fn main() {} diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr new file mode 100644 index 00000000000..53abe3dc952 --- /dev/null +++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr @@ -0,0 +1,24 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/erase-error-in-mir-drop-tracking.rs:11:46 + | +LL | fn connect(&'_ self) -> Self::Connecting<'a>; + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn connect<'a>(&'_ self) -> Self::Connecting<'a>; + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Client<'a> { + | ++++ + +error: `C` does not live long enough + --> $DIR/erase-error-in-mir-drop-tracking.rs:19:5 + | +LL | async move { c.connect().await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 70a1abb0a95..434b0744304 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -43,62 +43,6 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used - --> $DIR/format.rs:2:12 - | -LL | panic!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:2:12 - | -LL | panic!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:2:20 - | -LL | panic!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:2:20 - | -LL | panic!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:8:14 - | -LL | println!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:8:14 - | -LL | println!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:8:22 - | -LL | println!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:8:22 - | -LL | println!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-integer-bool-ops.rs b/tests/ui/consts/const-integer-bool-ops.rs index 4110ae3e456..35915a7a606 100644 --- a/tests/ui/consts/const-integer-bool-ops.rs +++ b/tests/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ constant const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +15,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ constant const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +24,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ constant const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +33,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ constant const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ constant const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ constant const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ constant const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ constant const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ constant const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ constant fn main() { let _ = ARR; diff --git a/tests/ui/consts/const-integer-bool-ops.stderr b/tests/ui/consts/const-integer-bool-ops.stderr index b5c3b22fdbe..4e503e5a5c0 100644 --- a/tests/ui/consts/const-integer-bool-ops.stderr +++ b/tests/ui/consts/const-integer-bool-ops.stderr @@ -16,156 +16,96 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:8:18 - | -LL | const ARR: [i32; X] = [99; 34]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:25 + --> $DIR/const-integer-bool-ops.rs:10:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:18:19 - | -LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:26 + --> $DIR/const-integer-bool-ops.rs:19:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:28:19 - | -LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:26 + --> $DIR/const-integer-bool-ops.rs:28:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:38:19 - | -LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:41:18 + --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:44:19 - | -LL | const ARRR: [i32; Y] = [99; 1]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:50:20 - | -LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:53:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:56:20 - | -LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:59:19 + --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:62:20 - | -LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:65:19 + --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:68:20 - | -LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:71:19 + --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:74:20 - | -LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ - error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr index 109d15a8e4d..61b00be345f 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr @@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -note: erroneous constant used - --> $DIR/issue-76510.rs:11:70 - | -LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3)); - | ^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0596, E0658, E0764. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr index 109d15a8e4d..61b00be345f 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -note: erroneous constant used - --> $DIR/issue-76510.rs:11:70 - | -LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3)); - | ^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0596, E0658, E0764. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.rs b/tests/ui/consts/const-mut-refs/issue-76510.rs index b853e2737f1..143d2fb6b9a 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.rs +++ b/tests/ui/consts/const-mut-refs/issue-76510.rs @@ -9,7 +9,6 @@ const S: &'static mut str = &mut " hello "; const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3)); - //~^ constant 0 }] { [(); 0] diff --git a/tests/ui/consts/const-tup-index-span.rs b/tests/ui/consts/const-tup-index-span.rs index 18f4f59d378..e77d392e694 100644 --- a/tests/ui/consts/const-tup-index-span.rs +++ b/tests/ui/consts/const-tup-index-span.rs @@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected `(usize,)`, found `usize` const ARR: [i32; TUP.0] = []; -//~^ constant fn main() { } diff --git a/tests/ui/consts/const-tup-index-span.stderr b/tests/ui/consts/const-tup-index-span.stderr index 65f0520f8a4..d5df0df9525 100644 --- a/tests/ui/consts/const-tup-index-span.stderr +++ b/tests/ui/consts/const-tup-index-span.stderr @@ -11,12 +11,6 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ -note: erroneous constant used - --> $DIR/const-tup-index-span.rs:6:18 - | -LL | const ARR: [i32; TUP.0] = []; - | ^^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/issue-54954.rs b/tests/ui/consts/issue-54954.rs index 520bf508ff3..7bcfa057019 100644 --- a/tests/ui/consts/issue-54954.rs +++ b/tests/ui/consts/issue-54954.rs @@ -9,8 +9,6 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ constant - //~| constant z } diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr index 85055828737..b0701bab793 100644 --- a/tests/ui/consts/issue-54954.stderr +++ b/tests/ui/consts/issue-54954.stderr @@ -16,18 +16,6 @@ LL | | core::mem::size_of::<T>() LL | | } | |_____- `Tt::const_val` defined here -note: erroneous constant used - --> $DIR/issue-54954.rs:11:15 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - -note: erroneous constant used - --> $DIR/issue-54954.rs:11:34 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - error: aborting due to 2 previous errors Some errors have detailed explanations: E0379, E0790. diff --git a/tests/ui/consts/issue-56164.stderr b/tests/ui/consts/issue-56164.stderr index 003f8474463..e46c649faf0 100644 --- a/tests/ui/consts/issue-56164.stderr +++ b/tests/ui/consts/issue-56164.stderr @@ -28,18 +28,6 @@ error: function pointer calls are not allowed in constant functions LL | input() | ^^^^^^^ -note: erroneous constant used - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^ - -note: erroneous constant used - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0015, E0277. diff --git a/tests/ui/consts/issue-66693.stderr b/tests/ui/consts/issue-66693.stderr index e9a3fced61c..f4898fd9732 100644 --- a/tests/ui/consts/issue-66693.stderr +++ b/tests/ui/consts/issue-66693.stderr @@ -22,17 +22,5 @@ LL | panic!(&1); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used - --> $DIR/issue-66693.rs:11:12 - | -LL | panic!(&1); - | ^^ - -note: erroneous constant used - --> $DIR/issue-66693.rs:11:12 - | -LL | panic!(&1); - | ^^ - error: aborting due to 3 previous errors diff --git a/tests/ui/dupe-first-attr.rc b/tests/ui/dupe-first-attr.rs index 8b7025b7be7..d950743b41c 100644 --- a/tests/ui/dupe-first-attr.rc +++ b/tests/ui/dupe-first-attr.rs @@ -1,24 +1,26 @@ +// run-pass + // Regression test for a problem with the first mod attribute // being applied to every mod // pretty-expanded FIXME #23616 #[cfg(target_os = "linux")] -mod hello; +mod hello {} #[cfg(target_os = "macos")] -mod hello; +mod hello {} #[cfg(target_os = "windows")] -mod hello; +mod hello {} #[cfg(target_os = "freebsd")] -mod hello; +mod hello {} #[cfg(target_os = "dragonfly")] -mod hello; +mod hello {} #[cfg(target_os = "android")] -mod hello; +mod hello {} -pub fn main() { } +fn main() {} diff --git a/tests/ui/enum-discriminant/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs index 07cad8796e1..06a33081340 100644 --- a/tests/ui/enum-discriminant/issue-41394.rs +++ b/tests/ui/enum-discriminant/issue-41394.rs @@ -5,7 +5,6 @@ enum Foo { enum Bar { A = Foo::A as isize - //~^ const } fn main() {} diff --git a/tests/ui/enum-discriminant/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr index 1b5c64628a1..fa95ca9c18a 100644 --- a/tests/ui/enum-discriminant/issue-41394.stderr +++ b/tests/ui/enum-discriminant/issue-41394.stderr @@ -6,12 +6,6 @@ LL | A = "" + 1 | | | &str -note: erroneous constant used - --> $DIR/issue-41394.rs:7:9 - | -LL | A = Foo::A as isize - | ^^^^^^^^^^^^^^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/extenv/extenv-escaped-var.rs b/tests/ui/extenv/extenv-escaped-var.rs new file mode 100644 index 00000000000..d898feb78c6 --- /dev/null +++ b/tests/ui/extenv/extenv-escaped-var.rs @@ -0,0 +1,3 @@ +fn main() { + env!("\t"); //~ERROR environment variable `\t` not defined at compile time +} diff --git a/tests/ui/extenv/extenv-escaped-var.stderr b/tests/ui/extenv/extenv-escaped-var.stderr new file mode 100644 index 00000000000..25e218c63f3 --- /dev/null +++ b/tests/ui/extenv/extenv-escaped-var.stderr @@ -0,0 +1,11 @@ +error: environment variable `\t` not defined at compile time + --> $DIR/extenv-escaped-var.rs:2:5 + | +LL | env!("\t"); + | ^^^^^^^^^^ + | + = help: use `std::env::var("\t")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr index 1219630d346..10589ec2f54 100644 --- a/tests/ui/extenv/issue-110547.stderr +++ b/tests/ui/extenv/issue-110547.stderr @@ -1,28 +1,28 @@ -error: environment variable ` ` not defined at compile time +error: environment variable `\t` not defined at compile time --> $DIR/issue-110547.rs:4:5 | LL | env!{"\t"}; | ^^^^^^^^^^ | - = help: use `std::env::var(" ")` to read the variable at run time + = help: use `std::env::var("\t")` to read the variable at run time = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) -error: environment variable ` ` not defined at compile time +error: environment variable `\t` not defined at compile time --> $DIR/issue-110547.rs:5:5 | LL | env!("\t"); | ^^^^^^^^^^ | - = help: use `std::env::var(" ")` to read the variable at run time + = help: use `std::env::var("\t")` to read the variable at run time = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) -error: environment variable `` not defined at compile time +error: environment variable `\u{2069}` not defined at compile time --> $DIR/issue-110547.rs:6:5 | LL | env!("\u{2069}"); | ^^^^^^^^^^^^^^^^ | - = help: use `std::env::var("")` to read the variable at run time + = help: use `std::env::var("\u{2069}")` to read the variable at run time = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/extern/auxiliary/invalid-utf8.txt b/tests/ui/extern/auxiliary/invalid-utf8.txt deleted file mode 100644 index dc1115b82db..00000000000 --- a/tests/ui/extern/auxiliary/invalid-utf8.txt +++ /dev/null @@ -1 +0,0 @@ -Ã(
\ No newline at end of file diff --git a/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis b/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis deleted file mode 100644 index 6eb47e3d85b..00000000000 --- a/tests/ui/feature-gates/auxiliary/debugger-visualizer.natvis +++ /dev/null @@ -1,3 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> -</AutoVisualizer> diff --git a/tests/ui/generator/drop-tracking-error-body.rs b/tests/ui/generator/drop-tracking-error-body.rs new file mode 100644 index 00000000000..f99d9ab6bf8 --- /dev/null +++ b/tests/ui/generator/drop-tracking-error-body.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zdrop-tracking-mir --edition=2021 + +#![feature(generators)] + +pub async fn async_bad_body() { + match true {} //~ ERROR non-exhaustive patterns: type `bool` is non-empty +} + +pub fn generator_bad_body() { + || { + // 'non-exhaustive pattern' only seems to be reported once, so this annotation doesn't work + // keep the function around so we can make sure it doesn't ICE + match true {}; // ERROR non-exhaustive patterns: type `bool` is non-empty + yield (); + }; +} + +fn main() {} diff --git a/tests/ui/generator/drop-tracking-error-body.stderr b/tests/ui/generator/drop-tracking-error-body.stderr new file mode 100644 index 00000000000..28a6892336f --- /dev/null +++ b/tests/ui/generator/drop-tracking-error-body.stderr @@ -0,0 +1,17 @@ +error[E0004]: non-exhaustive patterns: type `bool` is non-empty + --> $DIR/drop-tracking-error-body.rs:6:11 + | +LL | match true {} + | ^^^^ + | + = note: the matched value is of type `bool` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match true { +LL + _ => todo!(), +LL ~ } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index d78f7a7fbce..b21ff30a27d 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -36,7 +36,10 @@ error[E0433]: failed to resolve: use of undeclared type `I` --> $DIR/equality-bound.rs:9:41 | LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 { - | ^ use of undeclared type `I` + | ^ + | | + | use of undeclared type `I` + | help: a type parameter with a similar name exists: `J` error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed new file mode 100644 index 00000000000..cd4f2610d3f --- /dev/null +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed @@ -0,0 +1,19 @@ +// run-rustfix + +struct S<T>(T); +struct S2; + +impl<T: Default> Default for S<T> { + //~^ ERROR: unexpected `impl` keyword + //~| HELP: remove the extra `impl` + fn default() -> Self { todo!() } +} + +impl Default for S2 { + //~^ ERROR: unexpected `impl` keyword + //~| HELP: remove the extra `impl` + fn default() -> Self { todo!() } +} + + +fn main() {} diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs new file mode 100644 index 00000000000..024b703e6f2 --- /dev/null +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs @@ -0,0 +1,19 @@ +// run-rustfix + +struct S<T>(T); +struct S2; + +impl<T: Default> impl Default for S<T> { + //~^ ERROR: unexpected `impl` keyword + //~| HELP: remove the extra `impl` + fn default() -> Self { todo!() } +} + +impl impl Default for S2 { + //~^ ERROR: unexpected `impl` keyword + //~| HELP: remove the extra `impl` + fn default() -> Self { todo!() } +} + + +fn main() {} diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr new file mode 100644 index 00000000000..5aafc8b64d4 --- /dev/null +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr @@ -0,0 +1,26 @@ +error: unexpected `impl` keyword + --> $DIR/extra-impl-in-trait-impl.rs:6:18 + | +LL | impl<T: Default> impl Default for S<T> { + | ^^^^^ help: remove the extra `impl` + | +note: this is parsed as an `impl Trait` type, but a trait is expected at this position + --> $DIR/extra-impl-in-trait-impl.rs:6:18 + | +LL | impl<T: Default> impl Default for S<T> { + | ^^^^^^^^^^^^ + +error: unexpected `impl` keyword + --> $DIR/extra-impl-in-trait-impl.rs:12:6 + | +LL | impl impl Default for S2 { + | ^^^^^ help: remove the extra `impl` + | +note: this is parsed as an `impl Trait` type, but a trait is expected at this position + --> $DIR/extra-impl-in-trait-impl.rs:12:6 + | +LL | impl impl Default for S2 { + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/issue-103181-1.stderr b/tests/ui/impl-trait/issue-103181-1.current.stderr index cd026607d52..e87a9d28ae1 100644 --- a/tests/ui/impl-trait/issue-103181-1.stderr +++ b/tests/ui/impl-trait/issue-103181-1.current.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `Error` - --> $DIR/issue-103181-1.rs:9:5 + --> $DIR/issue-103181-1.rs:11:5 | LL | type Error; | ---------- `Error` from trait diff --git a/tests/ui/impl-trait/issue-103181-1.next.stderr b/tests/ui/impl-trait/issue-103181-1.next.stderr new file mode 100644 index 00000000000..e87a9d28ae1 --- /dev/null +++ b/tests/ui/impl-trait/issue-103181-1.next.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Error` + --> $DIR/issue-103181-1.rs:11:5 + | +LL | type Error; + | ---------- `Error` from trait +LL | } +LL | impl HttpBody for () { + | ^^^^^^^^^^^^^^^^^^^^ missing `Error` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/issue-103181-1.rs b/tests/ui/impl-trait/issue-103181-1.rs index 197aedf9d98..5154abcd690 100644 --- a/tests/ui/impl-trait/issue-103181-1.rs +++ b/tests/ui/impl-trait/issue-103181-1.rs @@ -1,3 +1,5 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next // edition:2021 mod hyper { diff --git a/tests/ui/issues/auxiliary/issue-3136-a.rc b/tests/ui/issues/auxiliary/issue-3136-a.rc deleted file mode 100644 index cd5fd314505..00000000000 --- a/tests/ui/issues/auxiliary/issue-3136-a.rc +++ /dev/null @@ -1,4 +0,0 @@ -#![crate_type = "lib"] - -#[path = "issue-3136-a.rs"] -pub mod issue_3136_a; diff --git a/tests/ui/issues/auxiliary/issue-3136-a.rs b/tests/ui/issues/auxiliary/issue-3136-a.rs index 9bb546ab393..22bb1c8f977 100644 --- a/tests/ui/issues/auxiliary/issue-3136-a.rs +++ b/tests/ui/issues/auxiliary/issue-3136-a.rs @@ -1,11 +1,14 @@ +#![crate_type = "lib"] + trait x { fn use_x<T>(&self); } struct y(()); impl x for y { fn use_x<T>(&self) { - struct foo { //~ ERROR quux - i: () + struct foo { + //~ ERROR quux + i: (), } fn new_foo<T>(i: ()) -> foo { foo { i: i } diff --git a/tests/ui/issues/issue-3136-b.rs b/tests/ui/issues/issue-3136-b.rs index c4ca7236e76..33d97fe7c83 100644 --- a/tests/ui/issues/issue-3136-b.rs +++ b/tests/ui/issues/issue-3136-b.rs @@ -1,5 +1,5 @@ // run-pass -// aux-build:issue-3136-a.rc +// aux-build:issue-3136-a.rs // pretty-expanded FIXME #23616 diff --git a/tests/ui/kindck/kindck-send-unsafe.rs b/tests/ui/kindck/kindck-send-unsafe.rs index 4ef30a71fa3..eb1f2a549b1 100644 --- a/tests/ui/kindck/kindck-send-unsafe.rs +++ b/tests/ui/kindck/kindck-send-unsafe.rs @@ -1,11 +1,15 @@ extern crate core; -fn assert_send<T:Send>() { } +fn assert_send<T: Send>() {} + +fn test70() { + assert_send::<*mut isize>(); + //~^ ERROR `*mut isize` cannot be sent between threads safely +} fn test71<'a>() { assert_send::<*mut &'a isize>(); //~^ ERROR `*mut &'a isize` cannot be sent between threads safely } -fn main() { -} +fn main() {} diff --git a/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master b/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master deleted file mode 100644 index 3f0444ec9c8..00000000000 --- a/tests/ui/kindck/kindck-send-unsafe.rs~rust-lang_master +++ /dev/null @@ -1,12 +0,0 @@ -fn assert_send<T:Send>() { } - -// unsafe ptrs are ok unless they point at unsendable things -fn test70() { - assert_send::<*mut int>(); -} -fn test71<'a>() { - assert_send::<*mut &'a int>(); //~ ERROR does not fulfill the required lifetime -} - -fn main() { -} diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr index ceed0053caa..f1a5054abbc 100644 --- a/tests/ui/kindck/kindck-send-unsafe.stderr +++ b/tests/ui/kindck/kindck-send-unsafe.stderr @@ -1,16 +1,29 @@ -error[E0277]: `*mut &'a isize` cannot be sent between threads safely +error[E0277]: `*mut isize` cannot be sent between threads safely --> $DIR/kindck-send-unsafe.rs:6:19 | +LL | assert_send::<*mut isize>(); + | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `*mut isize` +note: required by a bound in `assert_send` + --> $DIR/kindck-send-unsafe.rs:3:19 + | +LL | fn assert_send<T: Send>() {} + | ^^^^ required by this bound in `assert_send` + +error[E0277]: `*mut &'a isize` cannot be sent between threads safely + --> $DIR/kindck-send-unsafe.rs:11:19 + | LL | assert_send::<*mut &'a isize>(); | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut &'a isize` note: required by a bound in `assert_send` - --> $DIR/kindck-send-unsafe.rs:3:18 + --> $DIR/kindck-send-unsafe.rs:3:19 | -LL | fn assert_send<T:Send>() { } - | ^^^^ required by this bound in `assert_send` +LL | fn assert_send<T: Send>() {} + | ^^^^ required by this bound in `assert_send` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/lint/issue-111359.rs b/tests/ui/lint/issue-111359.rs new file mode 100644 index 00000000000..e390c3fc565 --- /dev/null +++ b/tests/ui/lint/issue-111359.rs @@ -0,0 +1,27 @@ +#[deny(missing_debug_implementations)] +#[deny(missing_copy_implementations)] + +mod priv_mod { + use std::convert::TryFrom; + + pub struct BarPub; + //~^ ERROR type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation + //~| ERROR type could implement `Copy`; consider adding `impl Copy` + struct BarPriv; + + impl<'a> TryFrom<BarPriv> for u8 { + type Error = (); + fn try_from(o: BarPriv) -> Result<Self, ()> { + unimplemented!() + } + } + + impl<'a> TryFrom<BarPub> for u8 { + type Error = (); + fn try_from(o: BarPub) -> Result<Self, ()> { + unimplemented!() + } + } +} + +fn main() {} diff --git a/tests/ui/lint/issue-111359.stderr b/tests/ui/lint/issue-111359.stderr new file mode 100644 index 00000000000..2296d8413d6 --- /dev/null +++ b/tests/ui/lint/issue-111359.stderr @@ -0,0 +1,26 @@ +error: type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation + --> $DIR/issue-111359.rs:7:5 + | +LL | pub struct BarPub; + | ^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-111359.rs:1:8 + | +LL | #[deny(missing_debug_implementations)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type could implement `Copy`; consider adding `impl Copy` + --> $DIR/issue-111359.rs:7:5 + | +LL | pub struct BarPub; + | ^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-111359.rs:2:8 + | +LL | #[deny(missing_copy_implementations)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr index 56af618d484..8cd9a63b808 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.stderr +++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr @@ -4,18 +4,21 @@ error[E0433]: failed to resolve: use of undeclared crate or module `env` LL | env::current_dir; | ^^^ use of undeclared crate or module `env` +error[E0433]: failed to resolve: use of undeclared crate or module `vec` + --> $DIR/builtin-prelude-no-accidents.rs:7:14 + | +LL | type B = vec::Vec<u8>; + | ^^^ + | | + | use of undeclared crate or module `vec` + | help: a struct with a similar name exists (notice the capitalization): `Vec` + error[E0433]: failed to resolve: use of undeclared crate or module `panic` --> $DIR/builtin-prelude-no-accidents.rs:6:14 | LL | type A = panic::PanicInfo; | ^^^^^ use of undeclared crate or module `panic` -error[E0433]: failed to resolve: use of undeclared crate or module `vec` - --> $DIR/builtin-prelude-no-accidents.rs:7:14 - | -LL | type B = vec::Vec<u8>; - | ^^^ use of undeclared crate or module `vec` - error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/macros/panic-temporaries.rs b/tests/ui/macros/panic-temporaries.rs new file mode 100644 index 00000000000..5b5b8b7c2d9 --- /dev/null +++ b/tests/ui/macros/panic-temporaries.rs @@ -0,0 +1,19 @@ +// check-pass +// edition:2021 + +#![allow(unreachable_code)] + +async fn f(_: u8) {} + +async fn g() { + // Todo returns `!`, so the await is never reached, and in particular the + // temporaries inside the formatting machinery are not still alive at the + // await point. + f(todo!("...")).await; +} + +fn require_send(_: impl Send) {} + +fn main() { + require_send(g()); +} diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout index ad97f7a4a75..b69b5bc3b53 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout @@ -26,7 +26,7 @@ fn arbitrary_consuming_method_for_demonstration_purposes() { { ::std::rt::panic_fmt(format_args!("Assertion failed: elem as usize\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -42,7 +42,7 @@ fn addr_of() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: &elem\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -58,7 +58,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem == 1\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -71,7 +71,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem >= 1\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -84,7 +84,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem > 0\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -97,7 +97,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem < 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -110,7 +110,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem <= 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -123,7 +123,7 @@ fn binary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: elem != 3\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; @@ -139,7 +139,7 @@ fn unary() { (&::core::asserting::Wrapper(__local_bind0)).try_capture(&mut __capture0); { ::std::rt::panic_fmt(format_args!("Assertion failed: *elem\nWith captures:\n elem = {0:?}\n", - __capture0)) + __capture0)); } } }; diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index 653be5b3b71..e34d855a9d4 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `dyn` - --> $DIR/dyn-trait-compatibility.rs:3:11 - | -LL | type A1 = dyn::dyn; - | ^^^ use of undeclared crate or module `dyn` - error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:1:11 | @@ -46,6 +40,12 @@ error[E0412]: cannot find type `dyn` in this scope LL | type A3 = dyn<<dyn as dyn>::dyn>; | ^^^ not found in this scope +error[E0433]: failed to resolve: use of undeclared crate or module `dyn` + --> $DIR/dyn-trait-compatibility.rs:3:11 + | +LL | type A1 = dyn::dyn; + | ^^^ use of undeclared crate or module `dyn` + error: aborting due to 8 previous errors Some errors have detailed explanations: E0405, E0412, E0433. diff --git a/tests/ui/parser/impl-on-unsized-typo.rs b/tests/ui/parser/impl-on-unsized-typo.rs new file mode 100644 index 00000000000..e09c0463045 --- /dev/null +++ b/tests/ui/parser/impl-on-unsized-typo.rs @@ -0,0 +1,6 @@ +trait Tr {} + +impl<T ?Sized> Tr for T {} +//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `?` + +fn main() {} diff --git a/tests/ui/parser/impl-on-unsized-typo.stderr b/tests/ui/parser/impl-on-unsized-typo.stderr new file mode 100644 index 00000000000..23dcc1efd68 --- /dev/null +++ b/tests/ui/parser/impl-on-unsized-typo.stderr @@ -0,0 +1,8 @@ +error: expected one of `,`, `:`, `=`, or `>`, found `?` + --> $DIR/impl-on-unsized-typo.rs:3:8 + | +LL | impl<T ?Sized> Tr for T {} + | ^ expected one of `,`, `:`, `=`, or `>` + +error: aborting due to previous error + diff --git a/tests/ui/parser/issues/issue-111416.rs b/tests/ui/parser/issues/issue-111416.rs new file mode 100644 index 00000000000..cfd1b6b99ba --- /dev/null +++ b/tests/ui/parser/issues/issue-111416.rs @@ -0,0 +1,3 @@ +fn main() { + let my = monad_bind(mx, T: Try); //~ ERROR invalid `struct` delimiters or `fn` call arguments +} diff --git a/tests/ui/parser/issues/issue-111416.stderr b/tests/ui/parser/issues/issue-111416.stderr new file mode 100644 index 00000000000..ddacf4d6dfc --- /dev/null +++ b/tests/ui/parser/issues/issue-111416.stderr @@ -0,0 +1,18 @@ +error: invalid `struct` delimiters or `fn` call arguments + --> $DIR/issue-111416.rs:2:14 + | +LL | let my = monad_bind(mx, T: Try); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: if `monad_bind` is a struct, use braces as delimiters + | +LL | let my = monad_bind { mx, T: Try }; + | ~ ~ +help: if `monad_bind` is a function, use the arguments directly + | +LL - let my = monad_bind(mx, T: Try); +LL + let my = monad_bind(mx, Try); + | + +error: aborting due to previous error + diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index e1349fb02ea..10fcccb0301 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared type `E` - --> $DIR/pattern-error-continue.rs:33:9 - | -LL | E::V => {} - | ^ use of undeclared type `E` - error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D` --> $DIR/pattern-error-continue.rs:18:9 | @@ -56,6 +50,15 @@ note: function defined here LL | fn f(_c: char) {} | ^ -------- +error[E0433]: failed to resolve: use of undeclared type `E` + --> $DIR/pattern-error-continue.rs:33:9 + | +LL | E::V => {} + | ^ + | | + | use of undeclared type `E` + | help: an enum with a similar name exists: `A` + error: aborting due to 5 previous errors Some errors have detailed explanations: E0023, E0308, E0433, E0532. diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs index ca4fcd85bb6..c10c6205a08 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.rs +++ b/tests/ui/pattern/usefulness/consts-opaque.rs @@ -20,11 +20,12 @@ const BAR: Bar = Bar; #[derive(PartialEq)] enum Baz { Baz1, - Baz2 + Baz2, } impl Eq for Baz {} const BAZ: Baz = Baz::Baz1; +#[rustfmt::skip] fn main() { match FOO { FOO => {} @@ -124,8 +125,16 @@ fn main() { match WRAPQUUX { Wrap(_) => {} - WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer - //~^ ERROR unreachable pattern + WRAPQUUX => {} + } + + match WRAPQUUX { + Wrap(_) => {} + } + + match WRAPQUUX { + //~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered + WRAPQUUX => {} } #[derive(PartialEq, Eq)] @@ -138,8 +147,7 @@ fn main() { match WHOKNOWSQUUX { WHOKNOWSQUUX => {} WhoKnows::Yay(_) => {} - WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer - //~^ ERROR unreachable pattern + WHOKNOWSQUUX => {} WhoKnows::Nope => {} } } diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 3f0b4a9f26a..e01b06ccc82 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:30:9 + --> $DIR/consts-opaque.rs:31:9 | LL | FOO => {} | ^^^ @@ -8,7 +8,7 @@ LL | FOO => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:37:9 + --> $DIR/consts-opaque.rs:38:9 | LL | FOO_REF => {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | FOO_REF => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:45:9 + --> $DIR/consts-opaque.rs:46:9 | LL | FOO_REF_REF => {} | ^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | FOO_REF_REF => {} = note: `#[warn(indirect_structural_match)]` on by default error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:53:9 + --> $DIR/consts-opaque.rs:54:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ @@ -38,7 +38,7 @@ LL | BAR => {} // should not be emitting unreachable warning = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:61:9 + --> $DIR/consts-opaque.rs:62:9 | LL | BAR => {} | ^^^ @@ -47,7 +47,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:70:9 + --> $DIR/consts-opaque.rs:71:9 | LL | BAR => {} | ^^^ @@ -56,7 +56,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:72:9 + --> $DIR/consts-opaque.rs:73:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ @@ -65,7 +65,7 @@ LL | BAR => {} // should not be emitting unreachable warning = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:80:9 + --> $DIR/consts-opaque.rs:81:9 | LL | BAZ => {} | ^^^ @@ -74,7 +74,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:90:9 + --> $DIR/consts-opaque.rs:91:9 | LL | BAZ => {} | ^^^ @@ -83,7 +83,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:97:9 + --> $DIR/consts-opaque.rs:98:9 | LL | BAZ => {} | ^^^ @@ -92,7 +92,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern - --> $DIR/consts-opaque.rs:32:9 + --> $DIR/consts-opaque.rs:33:9 | LL | FOO => {} | --- matches any value @@ -107,7 +107,7 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:39:9 + --> $DIR/consts-opaque.rs:40:9 | LL | FOO_REF => {} | ------- matches any value @@ -116,7 +116,7 @@ LL | Foo(_) => {} // should not be emitting unreachable warning | ^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:53:9 + --> $DIR/consts-opaque.rs:54:9 | LL | Bar => {} | --- matches any value @@ -124,7 +124,7 @@ LL | BAR => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:56:9 + --> $DIR/consts-opaque.rs:57:9 | LL | Bar => {} | --- matches any value @@ -133,7 +133,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:63:9 + --> $DIR/consts-opaque.rs:64:9 | LL | BAR => {} | --- matches any value @@ -142,7 +142,7 @@ LL | Bar => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:65:9 + --> $DIR/consts-opaque.rs:66:9 | LL | BAR => {} | --- matches any value @@ -151,7 +151,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:72:9 + --> $DIR/consts-opaque.rs:73:9 | LL | BAR => {} | --- matches any value @@ -160,7 +160,7 @@ LL | BAR => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:75:9 + --> $DIR/consts-opaque.rs:76:9 | LL | BAR => {} | --- matches any value @@ -169,7 +169,7 @@ LL | _ => {} // should not be emitting unreachable warning | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:82:9 + --> $DIR/consts-opaque.rs:83:9 | LL | BAZ => {} | --- matches any value @@ -178,7 +178,7 @@ LL | Baz::Baz1 => {} // should not be emitting unreachable warning | ^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:84:9 + --> $DIR/consts-opaque.rs:85:9 | LL | BAZ => {} | --- matches any value @@ -187,7 +187,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:92:9 + --> $DIR/consts-opaque.rs:93:9 | LL | BAZ => {} | --- matches any value @@ -196,7 +196,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:99:9 + --> $DIR/consts-opaque.rs:100:9 | LL | BAZ => {} | --- matches any value @@ -205,7 +205,7 @@ LL | Baz::Baz2 => {} // should not be emitting unreachable warning | ^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:101:9 + --> $DIR/consts-opaque.rs:102:9 | LL | BAZ => {} | --- matches any value @@ -213,19 +213,24 @@ LL | BAZ => {} LL | _ => {} // should not be emitting unreachable warning | ^ unreachable pattern -error: unreachable pattern - --> $DIR/consts-opaque.rs:127:9 +error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered + --> $DIR/consts-opaque.rs:135:11 | -LL | Wrap(_) => {} - | ------- matches any value -LL | WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer - | ^^^^^^^^ unreachable pattern - -error: unreachable pattern - --> $DIR/consts-opaque.rs:141:9 +LL | match WRAPQUUX { + | ^^^^^^^^ pattern `Wrap(_)` not covered + | +note: `Wrap<fn(usize, usize) -> usize>` defined here + --> $DIR/consts-opaque.rs:117:12 + | +LL | struct Wrap<T>(T); + | ^^^^ + = note: the matched value is of type `Wrap<fn(usize, usize) -> usize>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ WRAPQUUX => {}, +LL + Wrap(_) => todo!() | -LL | WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer - | ^^^^^^^^^^^^ -error: aborting due to 24 previous errors; 1 warning emitted +error: aborting due to 23 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/resolve/issue-109250.rs b/tests/ui/resolve/issue-109250.rs new file mode 100644 index 00000000000..68e33f693ce --- /dev/null +++ b/tests/ui/resolve/issue-109250.rs @@ -0,0 +1,3 @@ +fn main() { //~ HELP consider importing + HashMap::new; //~ ERROR failed to resolve: use of undeclared type `HashMap` +} diff --git a/tests/ui/resolve/issue-109250.stderr b/tests/ui/resolve/issue-109250.stderr new file mode 100644 index 00000000000..d5b8c08ced7 --- /dev/null +++ b/tests/ui/resolve/issue-109250.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: use of undeclared type `HashMap` + --> $DIR/issue-109250.rs:2:5 + | +LL | HashMap::new; + | ^^^^^^^ use of undeclared type `HashMap` + | +help: consider importing this struct + | +LL + use std::collections::HashMap; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/resolve/issue-50599.rs b/tests/ui/resolve/issue-50599.rs index 72238a59198..00588735b9a 100644 --- a/tests/ui/resolve/issue-50599.rs +++ b/tests/ui/resolve/issue-50599.rs @@ -2,5 +2,4 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ constant } diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index d7419b64fac..d58b6ca5b5c 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -16,12 +16,6 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; LL + const M: usize = (f64::from(N) * LOG10_2) as usize; | -note: erroneous constant used - --> $DIR/issue-50599.rs:4:29 - | -LL | let mut digits = [0u32; M]; - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/resolve-variant-assoc-item.stderr b/tests/ui/resolve/resolve-variant-assoc-item.stderr index 4be1019968b..ed157197d17 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.stderr +++ b/tests/ui/resolve/resolve-variant-assoc-item.stderr @@ -3,12 +3,26 @@ error[E0433]: failed to resolve: `V` is a variant, not a module | LL | E::V::associated_item; | ^ `V` is a variant, not a module + | +help: there is an enum variant `E::V`; try using the variant's enum + | +LL | E; + | ~ error[E0433]: failed to resolve: `V` is a variant, not a module --> $DIR/resolve-variant-assoc-item.rs:6:5 | LL | V::associated_item; | ^ `V` is a variant, not a module + | +help: there is an enum variant `E::V`; try using the variant's enum + | +LL | E; + | ~ +help: an enum with a similar name exists + | +LL | E::associated_item; + | ~ error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-99597.rs b/tests/ui/suggestions/issue-99597.rs new file mode 100644 index 00000000000..8ba9e1fdd62 --- /dev/null +++ b/tests/ui/suggestions/issue-99597.rs @@ -0,0 +1,15 @@ +#![allow(dead_code)] + +trait T1 { } + +trait T2 { + fn test(&self) { } +} + +fn go(s: &impl T1) { + //~^ SUGGESTION ( + s.test(); + //~^ ERROR no method named `test` +} + +fn main() { } diff --git a/tests/ui/suggestions/issue-99597.stderr b/tests/ui/suggestions/issue-99597.stderr new file mode 100644 index 00000000000..bdf2a07c143 --- /dev/null +++ b/tests/ui/suggestions/issue-99597.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `test` found for reference `&impl T1` in the current scope + --> $DIR/issue-99597.rs:11:7 + | +LL | s.test(); + | ^^^^ method not found in `&impl T1` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl T1` with it: + | +LL | fn go(s: &(impl T1 + T2)) { + | + +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index 307e3101849..fc6f5f23d92 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -1,6 +1,9 @@ // compile-flags: -Z track-diagnostics // error-pattern: created at +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" pub trait Foo { diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr index 1c7537633ff..89438aea9ad 100644 --- a/tests/ui/track-diagnostics/track6.stderr +++ b/tests/ui/track-diagnostics/track6.stderr @@ -1,9 +1,9 @@ error[E0658]: specialization is unstable - --> $DIR/track6.rs:11:5 + --> $DIR/track6.rs:LL:CC | LL | default fn bar() {} | ^^^^^^^^^^^^^^^^^^^ --Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:93:5 +-Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:LL:CC | = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: add `#![feature(specialization)]` to the crate attributes to enable diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs new file mode 100644 index 00000000000..eadee6b711e --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs @@ -0,0 +1,18 @@ +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Other<U: ?Sized> {} + +impl<U: ?Sized> Other<U> for U {} + +#[rustfmt::skip] +fn foo<U: ?Sized>() +where + for<T> T: Other<U> {} + +fn bar() { + foo::<_>(); + //~^ ERROR the trait bound `T: Other<_>` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr new file mode 100644 index 00000000000..bfcad72e352 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.stderr @@ -0,0 +1,27 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/universe-error1.rs:1:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `T: Other<_>` is not satisfied + --> $DIR/universe-error1.rs:14:11 + | +LL | foo::<_>(); + | ^ the trait `Other<_>` is not implemented for `T` + | +note: required by a bound in `foo` + --> $DIR/universe-error1.rs:11:15 + | +LL | fn foo<U: ?Sized>() + | --- required by a bound in this function +LL | where +LL | for<T> T: Other<U> {} + | ^^^^^^^^ required by this bound in `foo` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type/type-dependent-def-issue-49241.rs b/tests/ui/type/type-dependent-def-issue-49241.rs index caf5bade5c7..4b6bc6124db 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.rs +++ b/tests/ui/type/type-dependent-def-issue-49241.rs @@ -2,5 +2,4 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ constant } diff --git a/tests/ui/type/type-dependent-def-issue-49241.stderr b/tests/ui/type/type-dependent-def-issue-49241.stderr index af16a6e8f84..64c7687f7a8 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.stderr +++ b/tests/ui/type/type-dependent-def-issue-49241.stderr @@ -6,12 +6,6 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -note: erroneous constant used - --> $DIR/type-dependent-def-issue-49241.rs:4:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0435`. diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index 1aed1dbe4ba..8b12aa1a393 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared type `NonExistent` - --> $DIR/type-path-err-node-types.rs:15:5 - | -LL | NonExistent::Assoc::<u8>; - | ^^^^^^^^^^^ use of undeclared type `NonExistent` - error[E0412]: cannot find type `Nonexistent` in this scope --> $DIR/type-path-err-node-types.rs:7:12 | @@ -22,6 +16,12 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::<u8>(); | ^^^^^^^^^^^ not found in this scope +error[E0433]: failed to resolve: use of undeclared type `NonExistent` + --> $DIR/type-path-err-node-types.rs:15:5 + | +LL | NonExistent::Assoc::<u8>; + | ^^^^^^^^^^^ use of undeclared type `NonExistent` + error[E0282]: type annotations needed --> $DIR/type-path-err-node-types.rs:23:14 | diff --git a/tests/ui/unsized-locals/align.rs b/tests/ui/unsized-locals/align.rs new file mode 100644 index 00000000000..01be8f3bb9c --- /dev/null +++ b/tests/ui/unsized-locals/align.rs @@ -0,0 +1,30 @@ +// Test that unsized locals uphold alignment requirements. +// Regression test for #71416. +// run-pass +#![feature(unsized_locals)] +#![allow(incomplete_features)] +use std::any::Any; + +#[repr(align(256))] +#[allow(dead_code)] +struct A { + v: u8 +} + +impl A { + fn f(&self) -> *const A { + assert_eq!(self as *const A as usize % 256, 0); + self + } +} + +fn mk() -> Box<dyn Any> { + Box::new(A { v: 4 }) +} + +fn main() { + let x = *mk(); + let dwncst = x.downcast_ref::<A>().unwrap(); + let addr = dwncst.f(); + assert_eq!(addr as usize % 256, 0); +} diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs index d65703ef5ca..c4fa850a4f9 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/weird-exprs.rs @@ -5,13 +5,16 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] +#![allow(redundant_semicolons)] #![allow(unreachable_code)] #![allow(unused_braces, unused_must_use, unused_parens)] #![allow(uncommon_codepoints, confusable_idents)] +#![allow(unused_imports)] #![allow(unreachable_patterns)] #![recursion_limit = "256"] +extern crate core; use std::cell::Cell; use std::mem::swap; @@ -204,6 +207,30 @@ fn closure_matching() { assert!(matches!(x(..), |_| Some(4))); } +fn semisemisemisemisemi() { + ;;;;;;; ;;;;;;; ;;; ;;; ;; + ;; ;; ;;;; ;;;; ;; + ;;;;;;; ;;;;; ;; ;;;; ;; ;; + ;; ;; ;; ;; ;; ;; + ;;;;;;; ;;;;;;; ;; ;; ;; +} + +fn useful_syntax() { + use {{std::{{collections::{{HashMap}}}}}}; + use ::{{{{core}, {std}}}}; + use {{::{{core as core2}}}}; +} + +fn infcx() { + pub mod cx { + pub mod cx { + pub use super::cx; + pub struct Cx; + } + } + let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx; +} + pub fn main() { strange(); funny(); @@ -227,4 +254,7 @@ pub fn main() { function(); bathroom_stall(); closure_matching(); + semisemisemisemisemi(); + useful_syntax(); + infcx(); } diff --git a/triagebot.toml b/triagebot.toml index 54c8b2060c5..a5152434d89 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -512,6 +512,7 @@ compiler-team = [ ] compiler-team-contributors = [ "@compiler-errors", + "@eholk", "@jackh726", "@TaKO8Ki", "@WaffleLapkin", @@ -532,6 +533,7 @@ bootstrap = [ "@Mark-Simulacrum", "@albertlarsan68", "@ozkanonur", + "@clubby789", ] infra-ci = [ "@Mark-Simulacrum", |