diff options
1248 files changed, 32162 insertions, 11479 deletions
diff --git a/Cargo.lock b/Cargo.lock index 6d77c2b0b88..be95e63eb76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -741,7 +741,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows 0.46.0", + "windows", ] [[package]] @@ -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" @@ -1444,6 +1454,13 @@ dependencies = [ ] [[package]] +name = "generate-windows-sys" +version = "0.1.0" +dependencies = [ + "windows-bindgen", +] + +[[package]] name = "generic-array" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1640,7 +1657,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows", ] [[package]] @@ -2183,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" @@ -2191,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" @@ -3252,7 +3287,7 @@ dependencies = [ "tempfile", "thorin-dwp", "tracing", - "windows 0.46.0", + "windows", ] [[package]] @@ -3299,6 +3334,7 @@ dependencies = [ "rustc-hash", "rustc-rayon", "rustc-rayon-core", + "rustc_arena", "rustc_graphviz", "rustc_index", "rustc_macros", @@ -3308,7 +3344,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows 0.46.0", + "windows", ] [[package]] @@ -3353,6 +3389,7 @@ dependencies = [ "rustc_middle", "rustc_mir_build", "rustc_mir_dataflow", + "rustc_mir_transform", "rustc_monomorphize", "rustc_parse", "rustc_passes", @@ -3368,7 +3405,7 @@ dependencies = [ "rustc_ty_utils", "serde_json", "tracing", - "windows 0.46.0", + "windows", ] [[package]] @@ -3418,7 +3455,7 @@ dependencies = [ "termize", "tracing", "unicode-width", - "windows 0.46.0", + "windows", ] [[package]] @@ -3773,6 +3810,7 @@ dependencies = [ "chalk-ir", "derive_more", "either", + "field-offset", "gsgdt", "measureme", "polonius-engine", @@ -3861,8 +3899,10 @@ dependencies = [ "rustc_const_eval", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", + "rustc_macros", "rustc_middle", "rustc_mir_dataflow", "rustc_serialize", @@ -3985,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", @@ -4086,7 +4128,7 @@ dependencies = [ "smallvec", "termize", "tracing", - "windows 0.46.0", + "windows", ] [[package]] @@ -5112,9 +5154,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "ui_test" -version = "0.6.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba" +checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2" dependencies = [ "bstr 1.3.0", "cargo-platform", @@ -5490,23 +5532,30 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.46.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.48.0", ] [[package]] -name = "windows" -version = "0.48.0" +name = "windows-bindgen" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "b6935fb09b84ee57929ae92518b475f5dfdfbeb87c5334756acc28ee8e202b60" dependencies = [ - "windows-targets 0.48.0", + "windows-metadata", + "windows-tokens", ] [[package]] +name = "windows-metadata" +version = "0.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5bca94a32bf1e6a376522b6601275a3b611ee885ec0f1b6a05f17e8cfd3385" + +[[package]] name = "windows-sys" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5570,6 +5619,12 @@ dependencies = [ ] [[package]] +name = "windows-tokens" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34c9a3b28cb41db7385546f7f9a8179348dffc89923dde66857b1ba5312f6b4" + +[[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 7aaa34a68e6..53331e2869f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ members = [ "src/tools/collect-license-metadata", "src/tools/generate-copyright", "src/tools/suggest-tests", + "src/tools/generate-windows-sys", ] exclude = [ 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/ast.rs b/compiler/rustc_ast/src/ast.rs index e3ac8a8784a..43b429f6947 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -120,6 +120,12 @@ impl Path { pub fn is_global(&self) -> bool { !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot } + + /// If this path is a single identifier with no arguments, does not ensure + /// that the path resolves to a const param, the caller should check this. + pub fn is_potential_trivial_const_arg(&self) -> bool { + self.segments.len() == 1 && self.segments[0].args.is_none() + } } /// A segment of a path: an identifier, an optional lifetime, and a set of types. @@ -1154,7 +1160,9 @@ impl Expr { /// /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. - pub fn is_potential_trivial_const_param(&self) -> bool { + /// + /// Does not ensure that the path resolves to a const param, the caller should check this. + pub fn is_potential_trivial_const_arg(&self) -> bool { let this = if let ExprKind::Block(block, None) = &self.kind && block.stmts.len() == 1 && let StmtKind::Expr(expr) = &block.stmts[0].kind @@ -1165,8 +1173,7 @@ impl Expr { }; if let ExprKind::Path(None, path) = &this.kind - && path.segments.len() == 1 - && path.segments[0].args.is_none() + && path.is_potential_trivial_const_arg() { true } else { 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_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1526ffa0b03..275692ad5dd 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized { fn visit_variant(&mut self, v: &'ast Variant) { walk_variant(self, v) } + fn visit_variant_discr(&mut self, discr: &'ast AnonConst) { + self.visit_anon_const(discr); + } fn visit_label(&mut self, label: &'ast Label) { walk_label(self, label) } @@ -380,7 +383,7 @@ where visitor.visit_ident(variant.ident); visitor.visit_vis(&variant.vis); visitor.visit_variant_data(&variant.data); - walk_list!(visitor, visit_anon_const, &variant.disr_expr); + walk_list!(visitor, visit_variant_discr, &variant.disr_expr); walk_list!(visitor, visit_attribute, &variant.attrs); } diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 9b295339d94..afcf8b15cd8 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -446,7 +446,30 @@ fn expand_format_args<'hir>( && argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j) && arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr)); - let args = if use_simple_array { + let args = if arguments.is_empty() { + // Generate: + // &<core::fmt::Argument>::none() + // + // Note: + // `none()` just returns `[]`. We use `none()` rather than `[]` to limit the lifetime. + // + // This makes sure that this still fails to compile, even when the argument is inlined: + // + // ``` + // let f = format_args!("{}", "a"); + // println!("{f}"); // error E0716 + // ``` + // + // Cases where keeping the object around is allowed, such as `format_args!("a")`, + // are handled above by the `allow_const` case. + let none_fn = ctx.arena.alloc(ctx.expr_lang_item_type_relative( + macsp, + hir::LangItem::FormatArgument, + sym::none, + )); + let none = ctx.expr_call(macsp, none_fn, &[]); + ctx.expr(macsp, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, none)) + } else if use_simple_array { // Generate: // &[ // <core::fmt::Argument>::new_display(&arg0), diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3d154a93fb2..08ee3761bac 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -305,7 +305,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); this.arena.alloc(this.ty(span, hir::TyKind::Err(guar))) } - Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy), + Some(ty) => this.lower_ty( + ty, + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false }, + ), }, ); hir::ItemKind::TyAlias(ty, generics) @@ -852,7 +855,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ImplItemKind::Type(ty) } Some(ty) => { - let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy); + let ty = this.lower_ty( + ty, + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true }, + ); hir::ImplItemKind::Type(ty) } }, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0d21c8a84d0..cd6614a54a4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -247,7 +247,7 @@ enum ImplTraitContext { in_trait: bool, }, /// Impl trait in type aliases. - TypeAliasesOpaqueTy, + TypeAliasesOpaqueTy { in_assoc_ty: bool }, /// `impl Trait` is unstably accepted in this position. FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. @@ -1190,13 +1190,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // parsing. We try to resolve that ambiguity by attempting resolution in both the // type and value namespaces. If we resolved the path in the value namespace, we // transform it into a generic const argument. - TyKind::Path(qself, path) => { + TyKind::Path(None, path) => { if let Some(res) = self .resolver .get_partial_res(ty.id) .and_then(|partial_res| partial_res.full_res()) { - if !res.matches_ns(Namespace::TypeNS) { + if !res.matches_ns(Namespace::TypeNS) + && path.is_potential_trivial_const_arg() + { debug!( "lower_generic_arg: Lowering type argument as const argument: {:?}", ty, @@ -1218,7 +1220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let path_expr = Expr { id: ty.id, - kind: ExprKind::Path(qself.clone(), path.clone()), + kind: ExprKind::Path(None, path.clone()), span, attrs: AttrVec::new(), tokens: None, @@ -1405,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { *in_trait, itctx, ), - ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait( - span, - hir::OpaqueTyOrigin::TyAlias, - *def_node_id, - bounds, - false, - itctx, - ), + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self + .lower_opaque_impl_trait( + span, + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty }, + *def_node_id, + bounds, + false, + itctx, + ), ImplTraitContext::Universal => { let span = t.span; self.create_def( @@ -1532,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want // to capture the lifetimes that appear in the bounds. So visit the bounds to find out // exactly which ones those are. - let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias { - // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters - Vec::new() - } else { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example, - // we only keep the lifetimes that appear in the `impl Debug` itself: - lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + let lifetimes_to_remap = match origin { + hir::OpaqueTyOrigin::TyAlias { .. } => { + // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters + Vec::new() + } + hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example, + // we only keep the lifetimes that appear in the `impl Debug` itself: + lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + } }; debug!(?lifetimes_to_remap); diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b960671bf6e..3d5056d82c5 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -603,6 +603,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(yeet_expr, "`do yeet` expression is experimental"); gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); + gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); if !visitor.features.negative_bounds { for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index b74c59bca30..87c32ffce12 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -556,8 +556,7 @@ impl<'a> State<'a> { self.pclose(); } ast::ExprKind::OffsetOf(container, fields) => { - // FIXME: This should have its own syntax, distinct from a macro invocation. - self.word("offset_of!"); + self.word("builtin # offset_of"); self.popen(); self.rbox(0, Inconsistent); self.print_type(container); diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 94939c7e4cd..167f245361a 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -328,7 +328,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { // bottom = nothing is reserved or activated yet; - BitSet::new_empty(self.borrow_set.len() * 2) + BitSet::new_empty(self.borrow_set.len()) } fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 74e6ce37e97..b775739fed2 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -55,7 +55,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not // contain dangling references. PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) | - PlaceContext::NonUse(NonUseContext::AscribeUserTy) | + PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 7558247948f..6286033e067 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{Applicability, Diagnostic}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; @@ -478,179 +478,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { match self.local_names[local] { Some(name) if !local_decl.from_compiler_desugaring() => { - let label = match *local_decl.local_info() { - LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => { - let (span, suggestion) = - suggest_ampmut_self(self.infcx.tcx, local_decl); - Some((true, span, suggestion)) - } - - LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { - binding_mode: ty::BindingMode::BindByValue(_), - opt_ty_info, - .. - })) => { - // check if the RHS is from desugaring - let opt_assignment_rhs_span = - self.body.find_assignments(local).first().map(|&location| { - if let Some(mir::Statement { - source_info: _, - kind: - mir::StatementKind::Assign(box ( - _, - mir::Rvalue::Use(mir::Operand::Copy(place)), - )), - }) = self.body[location.block] - .statements - .get(location.statement_index) - { - self.body.local_decls[place.local].source_info.span - } else { - self.body.source_info(location).span - } - }); - match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) { - // on for loops, RHS points to the iterator part - Some(DesugaringKind::ForLoop) => { - self.suggest_similar_mut_method_for_for_loop(&mut err); - err.span_label(opt_assignment_rhs_span.unwrap(), format!( - "this iterator yields `{pointer_sigil}` {pointer_desc}s", - )); - None - } - // don't create labels for compiler-generated spans - Some(_) => None, - None => { - let label = if name != kw::SelfLower { - suggest_ampmut( - self.infcx.tcx, - local_decl, - opt_assignment_rhs_span, - opt_ty_info, - ) - } else { - match local_decl.local_info() { - LocalInfo::User(mir::BindingForm::Var( - mir::VarBindingForm { - opt_ty_info: None, .. - }, - )) => { - let (span, sugg) = suggest_ampmut_self( - self.infcx.tcx, - local_decl, - ); - (true, span, sugg) - } - // explicit self (eg `self: &'a Self`) - _ => suggest_ampmut( - self.infcx.tcx, - local_decl, - opt_assignment_rhs_span, - opt_ty_info, - ), - } - }; - Some(label) - } - } - } - - LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { - binding_mode: ty::BindingMode::BindByReference(_), - .. - })) => { - let pattern_span = local_decl.source_info.span; - suggest_ref_mut(self.infcx.tcx, pattern_span) - .map(|replacement| (true, pattern_span, replacement)) - } - - _ => unreachable!(), - }; - - match label { - Some((true, err_help_span, suggested_code)) => { - let (is_trait_sig, local_trait) = self.is_error_in_trait(local); - if !is_trait_sig { - err.span_suggestion_verbose( - err_help_span, - format!( - "consider changing this to be a mutable {pointer_desc}" - ), - suggested_code, - Applicability::MachineApplicable, - ); - } else if let Some(x) = local_trait { - err.span_suggestion_verbose( - x, - format!( - "consider changing that to be a mutable {pointer_desc}" - ), - suggested_code, - Applicability::MachineApplicable, - ); - } - } - Some((false, err_label_span, message)) => { - struct BindingFinder { - span: Span, - hir_id: Option<hir::HirId>, - } - - impl<'tcx> Visitor<'tcx> for BindingFinder { - fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { - if let hir::StmtKind::Local(local) = s.kind { - if local.pat.span == self.span { - self.hir_id = Some(local.hir_id); - } - } - hir::intravisit::walk_stmt(self, s); - } - } - let hir_map = self.infcx.tcx.hir(); - let def_id = self.body.source.def_id(); - let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local()); - let node = hir_map.find(hir_id); - let hir_id = if let Some(hir::Node::Item(item)) = node - && let hir::ItemKind::Fn(.., body_id) = item.kind - { - let body = hir_map.body(body_id); - let mut v = BindingFinder { - span: err_label_span, - hir_id: None, - }; - v.visit_body(body); - v.hir_id - } else { - None - }; - if let Some(hir_id) = hir_id - && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) - { - let (changing, span, sugg) = match local.ty { - Some(ty) => ("changing", ty.span, message), - None => ( - "specifying", - local.pat.span.shrink_to_hi(), - format!(": {message}"), - ), - }; - err.span_suggestion_verbose( - span, - format!("consider {changing} this binding's type"), - sugg, - Applicability::HasPlaceholders, - ); - } else { - err.span_label( - err_label_span, - format!( - "consider changing this binding's type to be: `{message}`" - ), - ); - } - } - None => {} - } err.span_label( span, format!( @@ -658,6 +485,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { so the data it refers to cannot be {acted_on}", ), ); + + self.suggest_make_local_mut(&mut err, local, name); } _ => { err.span_label( @@ -1131,6 +960,184 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } } + + fn suggest_make_local_mut( + &self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + local: Local, + name: Symbol, + ) { + let local_decl = &self.body.local_decls[local]; + + let (pointer_sigil, pointer_desc) = + if local_decl.ty.is_ref() { ("&", "reference") } else { ("*const", "pointer") }; + + let (is_trait_sig, local_trait) = self.is_error_in_trait(local); + if is_trait_sig && local_trait.is_none() { + return; + } + + let decl_span = match local_trait { + Some(span) => span, + None => local_decl.source_info.span, + }; + + let label = match *local_decl.local_info() { + LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => { + let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span); + Some((true, decl_span, suggestion)) + } + + LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(_), + opt_ty_info, + .. + })) => { + // check if the RHS is from desugaring + let opt_assignment_rhs_span = + self.body.find_assignments(local).first().map(|&location| { + if let Some(mir::Statement { + source_info: _, + kind: + mir::StatementKind::Assign(box ( + _, + mir::Rvalue::Use(mir::Operand::Copy(place)), + )), + }) = self.body[location.block].statements.get(location.statement_index) + { + self.body.local_decls[place.local].source_info.span + } else { + self.body.source_info(location).span + } + }); + match opt_assignment_rhs_span.and_then(|s| s.desugaring_kind()) { + // on for loops, RHS points to the iterator part + Some(DesugaringKind::ForLoop) => { + self.suggest_similar_mut_method_for_for_loop(err); + err.span_label( + opt_assignment_rhs_span.unwrap(), + format!("this iterator yields `{pointer_sigil}` {pointer_desc}s",), + ); + None + } + // don't create labels for compiler-generated spans + Some(_) => None, + None => { + let label = if name != kw::SelfLower { + suggest_ampmut( + self.infcx.tcx, + local_decl.ty, + decl_span, + opt_assignment_rhs_span, + opt_ty_info, + ) + } else { + match local_decl.local_info() { + LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { + opt_ty_info: None, + .. + })) => { + let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span); + (true, decl_span, sugg) + } + // explicit self (eg `self: &'a Self`) + _ => suggest_ampmut( + self.infcx.tcx, + local_decl.ty, + decl_span, + opt_assignment_rhs_span, + opt_ty_info, + ), + } + }; + Some(label) + } + } + } + + LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByReference(_), + .. + })) => { + let pattern_span: Span = local_decl.source_info.span; + suggest_ref_mut(self.infcx.tcx, pattern_span) + .map(|span| (true, span, "mut ".to_owned())) + } + + _ => unreachable!(), + }; + + match label { + Some((true, err_help_span, suggested_code)) => { + err.span_suggestion_verbose( + err_help_span, + format!("consider changing this to be a mutable {pointer_desc}"), + suggested_code, + Applicability::MachineApplicable, + ); + } + Some((false, err_label_span, message)) => { + struct BindingFinder { + span: Span, + hir_id: Option<hir::HirId>, + } + + impl<'tcx> Visitor<'tcx> for BindingFinder { + fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { + if let hir::StmtKind::Local(local) = s.kind { + if local.pat.span == self.span { + self.hir_id = Some(local.hir_id); + } + } + hir::intravisit::walk_stmt(self, s); + } + } + let hir_map = self.infcx.tcx.hir(); + let def_id = self.body.source.def_id(); + let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local()); + let node = hir_map.find(hir_id); + let hir_id = if let Some(hir::Node::Item(item)) = node + && let hir::ItemKind::Fn(.., body_id) = item.kind + { + let body = hir_map.body(body_id); + let mut v = BindingFinder { + span: err_label_span, + hir_id: None, + }; + v.visit_body(body); + v.hir_id + } else { + None + }; + if let Some(hir_id) = hir_id + && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) + { + let (changing, span, sugg) = match local.ty { + Some(ty) => ("changing", ty.span, message), + None => ( + "specifying", + local.pat.span.shrink_to_hi(), + format!(": {message}"), + ), + }; + err.span_suggestion_verbose( + span, + format!("consider {changing} this binding's type"), + sugg, + Applicability::HasPlaceholders, + ); + } else { + err.span_label( + err_label_span, + format!( + "consider changing this binding's type to be: `{message}`" + ), + ); + } + } + None => {} + } + } } pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool { @@ -1160,25 +1167,18 @@ pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option< } } -fn suggest_ampmut_self<'tcx>( - tcx: TyCtxt<'tcx>, - local_decl: &mir::LocalDecl<'tcx>, -) -> (Span, String) { - let sp = local_decl.source_info.span; - ( - sp, - match tcx.sess.source_map().span_to_snippet(sp) { - Ok(snippet) => { - let lt_pos = snippet.find('\''); - if let Some(lt_pos) = lt_pos { - format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4]) - } else { - "&mut self".to_string() - } +fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String { + match tcx.sess.source_map().span_to_snippet(span) { + Ok(snippet) => { + let lt_pos = snippet.find('\''); + if let Some(lt_pos) = lt_pos { + format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4]) + } else { + "&mut self".to_string() } - _ => "&mut self".to_string(), - }, - ) + } + _ => "&mut self".to_string(), + } } // When we want to suggest a user change a local variable to be a `&mut`, there @@ -1198,72 +1198,89 @@ fn suggest_ampmut_self<'tcx>( // by trying (3.), then (2.) and finally falling back on (1.). fn suggest_ampmut<'tcx>( tcx: TyCtxt<'tcx>, - local_decl: &mir::LocalDecl<'tcx>, + decl_ty: Ty<'tcx>, + decl_span: Span, opt_assignment_rhs_span: Option<Span>, opt_ty_info: Option<Span>, ) -> (bool, Span, String) { + // if there is a RHS and it starts with a `&` from it, then check if it is + // mutable, and if not, put suggest putting `mut ` to make it mutable. + // we don't have to worry about lifetime annotations here because they are + // not valid when taking a reference. For example, the following is not valid Rust: + // + // let x: &i32 = &'a 5; + // ^^ lifetime annotation not allowed + // if let Some(assignment_rhs_span) = opt_assignment_rhs_span && let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) + && let Some(stripped) = src.strip_prefix('&') { - let is_mutbl = |ty: &str| -> bool { - if let Some(rest) = ty.strip_prefix("mut") { - match rest.chars().next() { - // e.g. `&mut x` - Some(c) if c.is_whitespace() => true, - // e.g. `&mut(x)` - Some('(') => true, - // e.g. `&mut{x}` - Some('{') => true, - // e.g. `&mutablevar` - _ => false, - } - } else { - false + let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") { + match rest.chars().next() { + // e.g. `&mut x` + Some(c) if c.is_whitespace() => true, + // e.g. `&mut(x)` + Some('(') => true, + // e.g. `&mut{x}` + Some('{') => true, + // e.g. `&mutablevar` + _ => false, } + } else { + false }; - if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) { - let lt_name = &src[1..ws_pos]; - let ty = src[ws_pos..].trim_start(); - if !is_mutbl(ty) { - return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}")); - } - } else if let Some(stripped) = src.strip_prefix('&') { - let stripped = stripped.trim_start(); - if !is_mutbl(stripped) { - return (true, assignment_rhs_span, format!("&mut {stripped}")); - } + // if the reference is already mutable then there is nothing we can do + // here. + if !is_mut { + let span = assignment_rhs_span; + // shrink the span to just after the `&` in `&variable` + let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo(); + + // FIXME(Ezrashaw): returning is bad because we still might want to + // update the annotated type, see #106857. + return (true, span, "mut ".to_owned()); } } - let (suggestibility, highlight_span) = match opt_ty_info { + let (binding_exists, span) = match opt_ty_info { // if this is a variable binding with an explicit type, - // try to highlight that for the suggestion. + // then we will suggest changing it to be mutable. + // this is `Applicability::MachineApplicable`. Some(ty_span) => (true, ty_span), - // otherwise, just highlight the span associated with - // the (MIR) LocalDecl. - None => (false, local_decl.source_info.span), + // otherwise, we'll suggest *adding* an annotated type, we'll suggest + // the RHS's type for that. + // this is `Applicability::HasPlaceholders`. + None => (false, decl_span), }; - if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span) - && let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) + // if the binding already exists and is a reference with a explicit + // lifetime, then we can suggest adding ` mut`. this is special-cased from + // the path without a explicit lifetime. + if let Ok(src) = tcx.sess.source_map().span_to_snippet(span) + && src.starts_with("&'") + // note that `& 'a T` is invalid so this is correct. + && let Some(ws_pos) = src.find(char::is_whitespace) { - let lt_name = &src[1..ws_pos]; - let ty = &src[ws_pos..]; - return (true, highlight_span, format!("&{lt_name} mut{ty}")); - } + let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo(); + (true, span, " mut".to_owned()) + // if there is already a binding, we modify it to be `mut` + } else if binding_exists { + // shrink the span to just after the `&` in `&variable` + let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo(); + (true, span, "mut ".to_owned()) + } else { + // otherwise, suggest that the user annotates the binding; we provide the + // type of the local. + let ty_mut = decl_ty.builtin_deref(true).unwrap(); + assert_eq!(ty_mut.mutbl, hir::Mutability::Not); - let ty_mut = local_decl.ty.builtin_deref(true).unwrap(); - assert_eq!(ty_mut.mutbl, hir::Mutability::Not); - ( - suggestibility, - highlight_span, - if local_decl.ty.is_ref() { - format!("&mut {}", ty_mut.ty) - } else { - format!("*mut {}", ty_mut.ty) - }, - ) + ( + false, + span, + format!("{}mut {}", if decl_ty.is_ref() {"&"} else {"*"}, ty_mut.ty) + ) + } } fn is_closure_or_generator(ty: Ty<'_>) -> bool { @@ -1300,11 +1317,13 @@ fn get_mut_span_in_struct_field<'tcx>( } /// If possible, suggest replacing `ref` with `ref mut`. -fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> { - let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?; - if hi_src.starts_with("ref") && hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace) { - let replacement = format!("ref mut{}", &hi_src["ref".len()..]); - Some(replacement) +fn suggest_ref_mut(tcx: TyCtxt<'_>, span: Span) -> Option<Span> { + let pattern_str = tcx.sess.source_map().span_to_snippet(span).ok()?; + if pattern_str.starts_with("ref") + && pattern_str["ref".len()..].starts_with(rustc_lexer::is_whitespace) + { + let span = span.with_lo(span.lo() + BytePos(4)).shrink_to_lo(); + Some(span) } else { None } 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_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 4970ece5e7d..309f23d9226 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -265,7 +265,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` // on stable and we'd break that. - let OpaqueTyOrigin::TyAlias = origin else { + let OpaqueTyOrigin::TyAlias { .. } = origin else { return definition_ty; }; let def_id = opaque_type_key.def_id; @@ -360,7 +360,7 @@ fn check_opaque_type_parameter_valid( // which would error here on all of the `'static` args. OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()), // Check these - OpaqueTyOrigin::TyAlias => {} + OpaqueTyOrigin::TyAlias { .. } => {} } let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index dcabeb792be..33b24b68f7c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -777,7 +777,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf | Projection, ) => ty::Covariant, - PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, + PlaceContext::NonUse(AscribeUserTy(variance)) => variance, } } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 0d7cf7cdb26..3b458b1d30b 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -150,10 +150,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n -> *[more] arguments } in format string, but {$desc} -builtin_macros_offset_of_expected_field = expected field - -builtin_macros_offset_of_expected_two_args = expected 2 arguments - builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs index 8c737f04323..ee56d45c9c8 100644 --- a/compiler/rustc_builtin_macros/src/concat_idents.rs +++ b/compiler/rustc_builtin_macros/src/concat_idents.rs @@ -19,7 +19,7 @@ pub fn expand_concat_idents<'cx>( } let mut res_str = String::new(); - for (i, e) in tts.into_trees().enumerate() { + for (i, e) in tts.trees().enumerate() { if i & 1 == 1 { match e { TokenTree::Token(Token { kind: token::Comma, .. }, _) => {} diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 0481a118906..2c8e6f99c67 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -27,3 +27,26 @@ pub fn expand_deriving_copy( trait_def.expand(cx, mitem, item, push); } + +pub fn expand_deriving_const_param_ty( + cx: &mut ExtCtxt<'_>, + span: Span, + mitem: &MetaItem, + item: &Annotatable, + push: &mut dyn FnMut(Annotatable), + is_const: bool, +) { + let trait_def = TraitDef { + span, + path: path_std!(marker::ConstParamTy), + skip_path_as_bound: false, + needs_copy_as_bound_if_packed: false, + additional_bounds: Vec::new(), + supports_unions: false, + methods: Vec::new(), + associated_types: Vec::new(), + is_const, + }; + + trait_def.expand(cx, mitem, item, push); +} 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_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index bd9e903b6ba..bd5356575ca 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -562,15 +562,13 @@ pub(crate) mod printf { } if let Type = state { - drop(c); type_ = at.slice_between(next).unwrap(); // Don't use `move_to!` here, as we *can* be at the end of the input. at = next; } - drop(c); - drop(next); + let _ = c; // to avoid never used value end = at; let position = InnerSpan::new(start.at, end.at); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c7da61d72b3..ebf1448f55c 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -44,7 +44,6 @@ mod format; mod format_foreign; mod global_allocator; mod log_syntax; -mod offset_of; mod source_util; mod test; mod trace_macros; @@ -92,7 +91,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { line: source_util::expand_line, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, - offset_of: offset_of::expand_offset_of, option_env: env::expand_option_env, core_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic, @@ -117,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { register_derive! { Clone: clone::expand_deriving_clone, Copy: bounds::expand_deriving_copy, + ConstParamTy: bounds::expand_deriving_const_param_ty, Debug: debug::expand_deriving_debug, Default: default::expand_deriving_default, Eq: eq::expand_deriving_eq, diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs deleted file mode 100644 index 0ef3e000e41..00000000000 --- a/compiler/rustc_builtin_macros/src/offset_of.rs +++ /dev/null @@ -1,99 +0,0 @@ -use rustc_ast as ast; -use rustc_ast::ptr::P; -use rustc_ast::token; -use rustc_ast::tokenstream::TokenStream; -use rustc_errors::PResult; -use rustc_expand::base::{self, *}; -use rustc_macros::Diagnostic; -use rustc_parse::parser::Parser; -use rustc_span::{symbol::Ident, Span}; - -#[derive(Diagnostic)] -#[diag(builtin_macros_offset_of_expected_field)] -struct ExpectedField { - #[primary_span] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(builtin_macros_offset_of_expected_two_args)] -struct ExpectedTwoArgs { - #[primary_span] - span: Span, -} - -fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> { - let token = p.token.uninterpolate(); - let field = match token.kind { - token::Ident(name, _) => Ident::new(name, token.span), - token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => { - Ident::new(symbol, token.span) - } - _ => return Err(cx.create_err(ExpectedField { span: p.token.span })), - }; - - p.bump(); - - Ok(field) -} - -fn parse_args<'a>( - cx: &mut ExtCtxt<'a>, - sp: Span, - tts: TokenStream, -) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> { - let mut p = cx.new_parser_from_tts(tts); - - let container = p.parse_ty()?; - - p.expect(&token::Comma)?; - - if p.eat(&token::Eof) { - return Err(cx.create_err(ExpectedTwoArgs { span: sp })); - } - - let mut fields = Vec::new(); - - loop { - let field = parse_field(cx, &mut p)?; - fields.push(field); - - if p.eat(&token::Dot) { - continue; - } - - p.eat(&token::Comma); - - if !p.eat(&token::Eof) { - return Err(cx.create_err(ExpectedTwoArgs { span: sp })); - } - - break; - } - - Ok((container, fields.into())) -} - -pub fn expand_offset_of<'cx>( - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - tts: TokenStream, -) -> Box<dyn base::MacResult + 'cx> { - match parse_args(cx, sp, tts) { - Ok((container, fields)) => { - let expr = P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::OffsetOf(container, fields), - span: sp, - attrs: ast::AttrVec::new(), - tokens: None, - }); - - MacEager::expr(expr) - } - Err(mut err) => { - err.emit(); - DummyResult::any(sp) - } - } -} diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs index cc5ae6894e6..9c98723e1f4 100644 --- a/compiler/rustc_builtin_macros/src/trace_macros.rs +++ b/compiler/rustc_builtin_macros/src/trace_macros.rs @@ -8,7 +8,7 @@ pub fn expand_trace_macros( sp: Span, tt: TokenStream, ) -> Box<dyn base::MacResult + 'static> { - let mut cursor = tt.into_trees(); + let mut cursor = tt.trees(); let mut err = false; let value = match &cursor.next() { Some(TokenTree::Token(token, _)) if token.is_keyword(kw::True) => true, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index e9dbea1be67..25fd5ca3ae8 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -966,11 +966,7 @@ fn codegen_panic_inner<'tcx>( args: &[Value], span: Span, ) { - let def_id = fx - .tcx - .lang_items() - .require(lang_item) - .unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string())); + let def_id = fx.tcx.require_lang_item(lang_item, Some(span)); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let symbol_name = fx.tcx.symbol_name(instance).name; diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index a66ddb6a09f..869344ce92d 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1227,6 +1227,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (value1, value2) } + fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + // TODO(antoyo): generate the correct landing pad + self.cleanup_landing_pad(pers_fn) + } + #[cfg(feature="master")] fn resume(&mut self, exn0: RValue<'gcc>, _exn1: RValue<'gcc>) { let exn_type = exn0.get_type(); 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/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2fd6db8cbfe..4d0bcd53d15 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -985,13 +985,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) { let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false); - let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */); + let landing_pad = self.landing_pad(ty, pers_fn, 0); unsafe { llvm::LLVMSetCleanup(landing_pad, llvm::True); } (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1)) } + fn filter_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) { + let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false); + let landing_pad = self.landing_pad(ty, pers_fn, 1); + self.add_clause(landing_pad, self.const_array(self.type_i8p(), &[])); + (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1)) + } + fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) { let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false); let mut exn = self.const_poison(ty); diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 30a0cf1d019..4b9ca2e7d19 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -94,11 +94,11 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> // LLVM will prefix the name with `__imp_`. Ideally, we'd like the // existing logic below to set the Storage Class, but it has an // exemption for MinGW for backwards compatability. - let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi); + let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi, Some(instance)); unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } llfn } else { - cx.declare_fn(sym, fn_abi) + cx.declare_fn(sym, fn_abi, Some(instance)) }; debug!("get_fn: not casting pointer!"); diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 3dc0ac03312..cd261293e9b 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -207,6 +207,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance< )), ty::List::empty(), ), + None, ); llvm::set_linkage(llfn, llvm::Linkage::PrivateLinkage); diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index cc2a5d158be..164b12cf8d4 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -19,8 +19,11 @@ use crate::llvm::AttributePlace::Function; use crate::type_::Type; use crate::value::Value; use rustc_codegen_ssa::traits::TypeMembershipMethods; -use rustc_middle::ty::Ty; -use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions}; +use rustc_middle::ty::{Instance, Ty}; +use rustc_symbol_mangling::typeid::{ + kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance, + TypeIdOptions, +}; use smallvec::SmallVec; /// Declare a function. @@ -116,7 +119,12 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value { + pub fn declare_fn( + &self, + name: &str, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + instance: Option<Instance<'tcx>>, + ) -> &'ll Value { debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi); // Function addresses in Rust are never significant, allowing functions to @@ -132,18 +140,35 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { fn_abi.apply_attrs_llfn(self, llfn); if self.tcx.sess.is_sanitizer_cfi_enabled() { - let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::empty()); - self.set_type_metadata(llfn, typeid); - let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::GENERALIZE_POINTERS); - self.add_type_metadata(llfn, typeid); - let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::NORMALIZE_INTEGERS); - self.add_type_metadata(llfn, typeid); - let typeid = typeid_for_fnabi( - self.tcx, - fn_abi, - TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS, - ); - self.add_type_metadata(llfn, typeid); + if let Some(instance) = instance { + let typeid = typeid_for_instance(self.tcx, &instance, TypeIdOptions::empty()); + self.set_type_metadata(llfn, typeid); + let typeid = + typeid_for_instance(self.tcx, &instance, TypeIdOptions::GENERALIZE_POINTERS); + self.add_type_metadata(llfn, typeid); + let typeid = + typeid_for_instance(self.tcx, &instance, TypeIdOptions::NORMALIZE_INTEGERS); + self.add_type_metadata(llfn, typeid); + let typeid = typeid_for_instance( + self.tcx, + &instance, + TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS, + ); + self.add_type_metadata(llfn, typeid); + } else { + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::empty()); + self.set_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::GENERALIZE_POINTERS); + self.add_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, TypeIdOptions::NORMALIZE_INTEGERS); + self.add_type_metadata(llfn, typeid); + let typeid = typeid_for_fnabi( + self.tcx, + fn_abi, + TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS, + ); + self.add_type_metadata(llfn, typeid); + } } if self.tcx.sess.is_sanitizer_kcfi_enabled() { @@ -156,8 +181,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { options.insert(TypeIdOptions::NORMALIZE_INTEGERS); } - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); - self.set_kcfi_type_metadata(llfn, kcfi_typeid); + if let Some(instance) = instance { + let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, &instance, options); + self.set_kcfi_type_metadata(llfn, kcfi_typeid); + } else { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); + self.set_kcfi_type_metadata(llfn, kcfi_typeid); + } } llfn diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 00d1796f210..4e28034a850 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -772,7 +772,7 @@ fn gen_fn<'ll, 'tcx>( ) -> (&'ll Type, &'ll Value) { let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty()); let llty = fn_abi.llvm_type(cx); - let llfn = cx.declare_fn(name, fn_abi); + let llfn = cx.declare_fn(name, fn_abi, None); cx.set_frame_pointer_type(llfn); cx.apply_target_cpu_attr(llfn); // FIXME(eddyb) find a nicer way to do this. 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/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index d5be678c1bb..de93a64c0d6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -680,7 +680,9 @@ pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_v pub mod coverageinfo { use super::coverage_map; - /// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L209-L230) + /// Corresponds to enum `llvm::coverage::CounterMappingRegion::RegionKind`. + /// + /// Must match the layout of `LLVMRustCounterMappingRegionKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum RegionKind { @@ -714,7 +716,9 @@ pub mod coverageinfo { /// array", encoded separately), and source location (start and end positions of the represented /// code region). /// - /// Matches LLVMRustCounterMappingRegion. + /// Corresponds to struct `llvm::coverage::CounterMappingRegion`. + /// + /// Must match the layout of `LLVMRustCounterMappingRegion`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct CounterMappingRegion { 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_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 59bdc60830f..e8f8c321510 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -51,7 +51,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> { assert!(!instance.substs.has_infer()); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - let lldecl = self.declare_fn(symbol_name, fn_abi); + let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance)); unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) }; let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); base::set_link_section(lldecl, attrs); diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 4f73b731f5a..02be88df103 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -51,5 +51,5 @@ default-features = false features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"] [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = ["Win32_Globalization"] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8a7809a1468..ea06cb02d8b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -546,12 +546,38 @@ fn link_staticlib<'a>( ab.build(out_filename); - if !all_native_libs.is_empty() { - if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) { - print_native_static_libs(sess, &all_native_libs); + let crates = codegen_results.crate_info.used_crates.iter(); + + let fmts = codegen_results + .crate_info + .dependency_formats + .iter() + .find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None }) + .expect("no dependency formats for staticlib"); + + let mut all_rust_dylibs = vec![]; + for &cnum in crates { + match fmts.get(cnum.as_usize() - 1) { + Some(&Linkage::Dynamic) => {} + _ => continue, + } + let crate_name = codegen_results.crate_info.crate_name[&cnum]; + let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; + if let Some((path, _)) = &used_crate_source.dylib { + all_rust_dylibs.push(&**path); + } else { + if used_crate_source.rmeta.is_some() { + sess.emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name }); + } else { + sess.emit_fatal(errors::LinkRlibError::NotFound { crate_name }); + } } } + if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) { + print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs); + } + Ok(()) } @@ -1370,8 +1396,12 @@ enum RlibFlavor { StaticlibBase, } -fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { - let lib_args: Vec<_> = all_native_libs +fn print_native_static_libs( + sess: &Session, + all_native_libs: &[NativeLib], + all_rust_dylibs: &[&Path], +) { + let mut lib_args: Vec<_> = all_native_libs .iter() .filter(|l| relevant_lib(sess, l)) .filter_map(|lib| { @@ -1401,6 +1431,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { } }) .collect(); + for path in all_rust_dylibs { + // FIXME deduplicate with add_dynamic_crate + + // Just need to tell the linker about where the library lives and + // what its name is + let parent = path.parent(); + if let Some(dir) = parent { + let dir = fix_windows_verbatim_for_gcc(dir); + if sess.target.is_like_msvc { + let mut arg = String::from("/LIBPATH:"); + arg.push_str(&dir.display().to_string()); + lib_args.push(arg); + } else { + lib_args.push("-L".to_owned()); + lib_args.push(dir.display().to_string()); + } + } + let stem = path.file_stem().unwrap().to_str().unwrap(); + // Convert library file-stem into a cc -l argument. + let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 }; + let lib = &stem[prefix..]; + let path = parent.unwrap_or_else(|| Path::new("")); + if sess.target.is_like_msvc { + // When producing a dll, the MSVC linker may not actually emit a + // `foo.lib` file if the dll doesn't actually export any symbols, so we + // check to see if the file is there and just omit linking to it if it's + // not present. + let name = format!("{}.dll.lib", lib); + if path.join(&name).exists() { + lib_args.push(name); + } + } else { + lib_args.push(format!("-l{}", lib)); + } + } if !lib_args.is_empty() { sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index d5d843702c0..8bf84772f08 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -12,9 +12,9 @@ use object::{ use snap::write::FrameEncoder; +use object::elf::NT_GNU_PROPERTY_TYPE_0; use rustc_data_structures::memmap::Mmap; -use rustc_data_structures::owned_slice::try_slice_owned; -use rustc_data_structures::sync::MetadataRef; +use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice}; use rustc_metadata::fs::METADATA_FILENAME; use rustc_metadata::EncodedMetadata; use rustc_session::cstore::MetadataLoader; @@ -38,7 +38,7 @@ pub struct DefaultMetadataLoader; fn load_metadata_with( path: &Path, f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, -) -> Result<MetadataRef, String> { +) -> Result<OwnedSlice, String> { let file = File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?; @@ -48,7 +48,7 @@ fn load_metadata_with( } impl MetadataLoader for DefaultMetadataLoader { - fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { + fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> { load_metadata_with(path, |data| { let archive = object::read::archive::ArchiveFile::parse(&*data) .map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?; @@ -68,7 +68,7 @@ impl MetadataLoader for DefaultMetadataLoader { }) } - fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> { + fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> { load_metadata_with(path, |data| search_for_section(path, data, ".rustc")) } } @@ -93,6 +93,54 @@ pub(super) fn search_for_section<'a>( .map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e)) } +fn add_gnu_property_note( + file: &mut write::Object<'static>, + architecture: Architecture, + binary_format: BinaryFormat, + endianness: Endianness, +) { + // check bti protection + if binary_format != BinaryFormat::Elf + || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64) + { + return; + } + + let section = file.add_section( + file.segment_name(StandardSegment::Data).to_vec(), + b".note.gnu.property".to_vec(), + SectionKind::Note, + ); + let mut data: Vec<u8> = Vec::new(); + let n_namsz: u32 = 4; // Size of the n_name field + let n_descsz: u32 = 16; // Size of the n_desc field + let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor + let header_values = [n_namsz, n_descsz, n_type]; + header_values.iter().for_each(|v| { + data.extend_from_slice(&match endianness { + Endianness::Little => v.to_le_bytes(), + Endianness::Big => v.to_be_bytes(), + }) + }); + data.extend_from_slice(b"GNU\0"); // Owner of the program property note + let pr_type: u32 = match architecture { + Architecture::X86_64 => 0xc0000002, + Architecture::Aarch64 => 0xc0000000, + _ => unreachable!(), + }; + let pr_datasz: u32 = 4; //size of the pr_data field + let pr_data: u32 = 3; //program property descriptor + let pr_padding: u32 = 0; + let property_values = [pr_type, pr_datasz, pr_data, pr_padding]; + property_values.iter().for_each(|v| { + data.extend_from_slice(&match endianness { + Endianness::Little => v.to_le_bytes(), + Endianness::Big => v.to_be_bytes(), + }) + }); + file.append_section_data(section, &data, 8); +} + pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> { let endianness = match sess.target.options.endian { Endian::Little => Endianness::Little, @@ -205,6 +253,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static _ => elf::ELFOSABI_NONE, }; let abi_version = 0; + add_gnu_property_note(&mut file, architecture, binary_format, endianness); file.flags = FileFlags::Elf { os_abi, abi_version, e_flags }; Some(file) } 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/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs index e288760a02b..1791ce4b315 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs @@ -1,6 +1,6 @@ use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex}; -/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95) +/// Must match the layout of `LLVMRustCounterKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum CounterKind { @@ -17,8 +17,10 @@ pub enum CounterKind { /// `instrprof.increment()`) /// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of /// counter expressions. -/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103) -/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart. +/// +/// Corresponds to struct `llvm::coverage::Counter`. +/// +/// Must match the layout of `LLVMRustCounter`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct Counter { @@ -59,7 +61,9 @@ impl Counter { } } -/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150) +/// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`. +/// +/// Must match the layout of `LLVMRustCounterExprKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub enum ExprKind { @@ -67,9 +71,9 @@ pub enum ExprKind { Add = 1, } -/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152) -/// Important: The Rust struct layout (order and types of fields) must match its C++ -/// counterpart. +/// Corresponds to struct `llvm::coverage::CounterExpression`. +/// +/// Must match the layout of `LLVMRustCounterExpression`. #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct CounterExpression { 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/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index c1613a9640a..a832999225a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1600,7 +1600,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx = Bx::build(self.cx, llbb); let llpersonality = self.cx.eh_personality(); - bx.cleanup_landing_pad(llpersonality); + bx.filter_landing_pad(llpersonality); funclet = None; } 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..d83bfc74082 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,3 +1,5 @@ +use std::any::Any; + use super::write::WriteBackendMethods; use super::CodegenObject; use crate::back::write::TargetMachineFactoryFn; @@ -5,11 +7,12 @@ use crate::{CodegenResults, ModuleCodegen}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::{DynSend, DynSync}; 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}, @@ -20,10 +23,6 @@ use rustc_span::symbol::Symbol; use rustc_target::abi::call::FnAbi; use rustc_target::spec::Target; -pub use rustc_data_structures::sync::MetadataRef; - -use std::any::Any; - pub trait BackendTypes { type Value: CodegenObject; type Function: CodegenObject; @@ -117,7 +116,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_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 57de7e9620e..853c6934c2c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -274,6 +274,7 @@ pub trait BuilderMethods<'a, 'tcx>: // These are used by everyone except msvc fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value); + fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value); fn resume(&mut self, exn0: Self::Value, exn1: Self::Value); // These are used only by msvc diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index cdef3fb2339..c591ff75ab8 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -3,7 +3,8 @@ use std::fmt; use rustc_errors::Diagnostic; use rustc_middle::mir::AssertKind; -use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt}; +use rustc_middle::query::TyCtxtAt; +use rustc_middle::ty::{layout::LayoutError, ConstInt}; use rustc_span::{Span, Symbol}; use super::InterpCx; @@ -169,14 +170,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..040eba10eb4 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,14 +7,13 @@ 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::query::TyCtxtAt; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{ - self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, -}; +use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; @@ -470,7 +469,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 +516,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 +904,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 5e05fe463ed..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" } @@ -37,7 +38,7 @@ itertools = "0.10.1" version = "0.11" [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = [ "Win32_Foundation", "Win32_Storage_FileSystem", 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.rs b/compiler/rustc_data_structures/src/owned_slice.rs index 048401f66c2..cbb3047d884 100644 --- a/compiler/rustc_data_structures/src/owned_slice.rs +++ b/compiler/rustc_data_structures/src/owned_slice.rs @@ -1,5 +1,6 @@ use std::{borrow::Borrow, ops::Deref}; +use crate::sync::Lrc; // Use our fake Send/Sync traits when on not parallel compiler, // so that `OwnedSlice` only implements/requires Send/Sync // for parallel compiler builds. @@ -7,7 +8,7 @@ use crate::sync::{Send, Sync}; /// An owned slice. /// -/// This is similar to `Box<[u8]>` but allows slicing and using anything as the +/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the /// backing buffer. /// /// See [`slice_owned`] for `OwnedSlice` construction and examples. @@ -16,6 +17,7 @@ use crate::sync::{Send, Sync}; /// /// This is essentially a replacement for `owning_ref` which is a lot simpler /// and even sound! 🌸 +#[derive(Clone)] pub struct OwnedSlice { /// This is conceptually a `&'self.owner [u8]`. bytes: *const [u8], @@ -31,7 +33,7 @@ pub struct OwnedSlice { // \/ // ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770) #[expect(dead_code)] - owner: Box<dyn Send + Sync>, + owner: Lrc<dyn Send + Sync>, } /// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function. @@ -72,10 +74,10 @@ where O: Send + Sync + 'static, F: FnOnce(&O) -> Result<&[u8], E>, { - // We box the owner of the bytes, so it doesn't move. + // We wrap the owner of the bytes in, so it doesn't move. // // Since the owner does not move and we don't access it in any way - // before drop, there is nothing that can invalidate the bytes pointer. + // before dropping, there is nothing that can invalidate the bytes pointer. // // Thus, "extending" the lifetime of the reference returned from `F` is fine. // We pretend that we pass it a reference that lives as long as the returned slice. @@ -83,12 +85,39 @@ where // N.B. the HRTB on the `slicer` is important — without it the caller could provide // a short lived slice, unrelated to the owner. - let owner = Box::new(owner); + let owner = Lrc::new(owner); let bytes = slicer(&*owner)?; Ok(OwnedSlice { bytes, owner }) } +impl OwnedSlice { + /// Slice this slice by `slicer`. + /// + /// # Examples + /// + /// ```rust + /// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned}; + /// let vec = vec![1, 2, 3, 4]; + /// + /// // Identical to slicing via `&v[1..3]` but produces an owned slice + /// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]); + /// assert_eq!(&*slice, [1, 2, 3, 4]); + /// + /// let slice = slice.slice(|slice| &slice[1..][..2]); + /// assert_eq!(&*slice, [2, 3]); + /// ``` + /// + pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice { + // This is basically identical to `try_slice_owned`, + // `slicer` can only return slices of its argument or some static data, + // both of which are valid while `owner` is alive. + + let bytes = slicer(&self); + OwnedSlice { bytes, ..self } + } +} + impl Deref for OwnedSlice { type Target = [u8]; @@ -108,10 +137,12 @@ impl Borrow<[u8]> for OwnedSlice { } } -// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Send` +// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Send` +#[cfg(parallel_compiler)] unsafe impl Send for OwnedSlice {} -// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Sync` +// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Sync` +#[cfg(parallel_compiler)] unsafe impl Sync for OwnedSlice {} #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/owned_slice/tests.rs b/compiler/rustc_data_structures/src/owned_slice/tests.rs index e715fb55362..1eb5378cd1a 100644 --- a/compiler/rustc_data_structures/src/owned_slice/tests.rs +++ b/compiler/rustc_data_structures/src/owned_slice/tests.rs @@ -26,7 +26,7 @@ fn static_storage() { } #[test] -fn slice_the_slice() { +fn slice_owned_the_slice() { let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice); let slice = slice_owned(slice, |s| &s[1..][..4]); let slice = slice_owned(slice, |s| s); @@ -36,6 +36,16 @@ fn slice_the_slice() { } #[test] +fn slice_the_slice() { + let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice) + .slice(|s| &s[1..][..4]) + .slice(|s| s) + .slice(|s| &s[1..]); + + assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]); +} + +#[test] fn try_and_fail() { let res = try_slice_owned(vec![0], |v| v.get(12..).ok_or(())); @@ -69,6 +79,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/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 5e13e7c8aaf..3c76c2b7991 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -865,14 +865,16 @@ cfg_if! { use std::mem; use windows::{ - Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, + // FIXME: change back to K32GetProcessMemoryInfo when windows crate + // updated to 0.49.0+ to drop dependency on psapi.dll + Win32::System::ProcessStatus::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, Win32::System::Threading::GetCurrentProcess, }; let mut pmc = PROCESS_MEMORY_COUNTERS::default(); let pmc_size = mem::size_of_val(&pmc); unsafe { - K32GetProcessMemoryInfo( + GetProcessMemoryInfo( GetCurrentProcess(), &mut pmc, pmc_size as u32, diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index e73ca56efa0..6c3197d8ec2 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -39,7 +39,7 @@ //! //! [^2] `MTLockRef` is a typedef. -use crate::owned_slice::OwnedSlice; +pub use crate::marker::*; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use std::ops::{Deref, DerefMut}; @@ -55,6 +55,43 @@ 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,7 +221,28 @@ cfg_if! { } } - pub type MetadataRef = OwnedSlice; + 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 use std::rc::Rc as Lrc; pub use std::rc::Weak as Weak; @@ -302,49 +354,166 @@ 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_iter<T: IntoParallelIterator>(t: T) -> T::Iter { - t.into_par_iter() - } - - pub fn par_for_each_in<T: IntoParallelIterator>( + pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>( t: T, - for_each: impl Fn(T::Item) + Sync + Send, + for_each: impl Fn(I) + DynSync + DynSend ) { - 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) - }); + 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) + } + }); + + 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 type MetadataRef = OwnedSlice; + pub fn par_map< + I, + T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>, + R: std::marker::Send, + C: FromIterator<R> + FromParallelIterator<R> + >( + t: T, + 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 + } + } /// This makes locks panic if they are already held. /// It is only useful when you are running in a single thread @@ -352,11 +521,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/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index cc4c5a0cacd..67352c55c90 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -51,12 +51,13 @@ rustc_interface = { path = "../rustc_interface" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } +rustc_mir_transform = { path = "../rustc_mir_transform" } [target.'cfg(unix)'.dependencies] libc = "0.2" [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = [ "Win32_System_Diagnostics_Debug", ] @@ -64,5 +65,8 @@ features = [ [features] llvm = ['rustc_interface/llvm'] max_level_info = ['rustc_log/max_level_info'] -rustc_use_parallel_compiler = ['rustc_data_structures/rustc_use_parallel_compiler', 'rustc_interface/rustc_use_parallel_compiler', - 'rustc_middle/rustc_use_parallel_compiler'] +rustc_use_parallel_compiler = [ + 'rustc_data_structures/rustc_use_parallel_compiler', + 'rustc_interface/rustc_use_parallel_compiler', + 'rustc_middle/rustc_use_parallel_compiler' +] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 446e29199c6..80a9dfd251a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -99,6 +99,7 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, + rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, @@ -255,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_codes/src/error_codes/E0771.md b/compiler/rustc_error_codes/src/error_codes/E0771.md index a2a1a20f230..4f36590025b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0771.md +++ b/compiler/rustc_error_codes/src/error_codes/E0771.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler + A non-`'static` lifetime was used in a const generic. This is currently not allowed. Erroneous code example: -```compile_fail,E0771 +```compile_fail,E0770 #![feature(adt_const_params)] fn function_with_str<'a, const STRING: &'a str>() {} // error! 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/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 46ace8eb2dd..bd3033fcb3e 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -27,12 +27,11 @@ serde = { version = "1.0.125", features = [ "derive" ] } serde_json = "1.0.59" [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = [ "Win32_Foundation", "Win32_Security", "Win32_System_Threading", - "Win32_System_WindowsProgramming", ] [features] diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index ef528d87cb2..db97d96fccd 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -571,6 +571,14 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { Some((diagnostic, handler)) } + /// Retrieves the [`Handler`] if available + pub fn handler(&self) -> Option<&Handler> { + match self.inner.state { + DiagnosticBuilderState::Emittable(handler) => Some(handler), + DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => None, + } + } + /// Buffers the diagnostic for later emission, /// unless handler has disabled such buffering. pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fcbd9a53b48..0f360473619 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. @@ -478,6 +478,7 @@ pub enum StashKey { /// FRU syntax MaybeFruTypo, CallAssocMethod, + TraitMissingMethod, } fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { @@ -605,7 +606,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/lock.rs b/compiler/rustc_errors/src/lock.rs index 7db262abfde..bd5cf49b56b 100644 --- a/compiler/rustc_errors/src/lock.rs +++ b/compiler/rustc_errors/src/lock.rs @@ -19,8 +19,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> { use windows::{ core::PCSTR, Win32::Foundation::{CloseHandle, HANDLE, WAIT_ABANDONED, WAIT_OBJECT_0}, - Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject}, - Win32::System::WindowsProgramming::INFINITE, + Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject, INFINITE}, }; struct Handle(HANDLE); 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 27d30c315af..57e55752027 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -313,12 +313,16 @@ declare_features! ( (active, async_closure, "1.37.0", Some(62290), None), /// Allows async functions to be declared, implemented, and used in traits. (active, async_fn_in_trait, "1.66.0", Some(91611), None), + /// Allows builtin # foo() syntax + (active, builtin_syntax, "CURRENT_RUSTC_VERSION", Some(110680), None), /// Allows `c"foo"` literals. (active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None), /// Treat `extern "C"` function as nounwind. (active, c_unwind, "1.52.0", Some(74990), None), /// Allows using C-variadics. (active, c_variadic, "1.34.0", Some(44930), None), + /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. + (active, cfg_overflow_checks, "CURRENT_RUSTC_VERSION", Some(111466), None), /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used. (active, cfg_sanitize, "1.41.0", Some(39699), None), /// Allows `cfg(target_abi = "...")`. @@ -334,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_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fe05d4590e7..61cfbf5c5e5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -24,6 +24,7 @@ pub type GatedCfg = (Symbol, Symbol, GateFn); /// `cfg(...)`'s that are feature gated. const GATED_CFGS: &[GatedCfg] = &[ // (name in cfg, feature, function to check if the feature is enabled) + (sym::overflow_checks, sym::cfg_overflow_checks, cfg_fn!(cfg_overflow_checks)), (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)), (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), ( diff --git a/compiler/rustc_hir/src/errors.rs b/compiler/rustc_hir/src/errors.rs deleted file mode 100644 index e593ed1044a..00000000000 --- a/compiler/rustc_hir/src/errors.rs +++ /dev/null @@ -1,10 +0,0 @@ -use crate::LangItem; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] -pub struct LangItemError(pub LangItem); - -impl ToString for LangItemError { - fn to_string(&self) -> String { - format!("requires `{}` lang_item", self.0.name()) - } -} diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 38cd5865cc3..932f0396282 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2662,7 +2662,10 @@ pub enum OpaqueTyOrigin { /// `async fn` AsyncFn(LocalDefId), /// type aliases: `type Foo = impl Trait;` - TyAlias, + TyAlias { + /// associated types in impl blocks for traits. + in_assoc_ty: bool, + }, } /// The various kinds of types recognized by the compiler. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 1f08befb180..4b3bc816b95 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -8,7 +8,6 @@ //! * Functions called by the compiler itself. use crate::def_id::DefId; -use crate::errors::LangItemError; use crate::{MethodKind, Target}; use rustc_ast as ast; @@ -42,13 +41,6 @@ impl LanguageItems { self.items[item as usize] = Some(def_id); } - /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`. - /// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`, - /// returns an error encapsulating the `LangItem`. - pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> { - self.get(it).ok_or_else(|| LangItemError(it)) - } - pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ { self.items .iter() diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 98d967cc0b8..616de57dc63 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -30,7 +30,6 @@ pub mod def; pub mod def_path_hash_map; pub mod definitions; pub mod diagnostic_items; -pub mod errors; pub use rustc_span::def_id; mod hir; pub mod hir_id; diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 3b42b0fe246..5e5c984a7ea 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -279,6 +279,9 @@ hir_analysis_specialization_trait = implementing `rustc_specialization_trait` tr hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present .label = `for<...>` is here +hir_analysis_empty_specialization = specialization impl does not specialize any associated items + .note = impl is a specialization of this impl + hir_analysis_const_specialize = cannot specialize on const impl with non-const impl hir_analysis_static_specialize = cannot specialize on `'static` lifetime diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5ee0cf94360..cf082f1ffaa 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -19,7 +19,7 @@ use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError, - MultiSpan, + MultiSpan, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -38,7 +38,6 @@ use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt} use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::edition::Edition; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::spec::abi; @@ -464,7 +463,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 +517,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 +526,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 +1386,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, @@ -2419,6 +2418,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return Ok(None); } + // + // Select applicable inherent associated type candidates modulo regions. + // + // In contexts that have no inference context, just make a new one. // We do need a local variable to store it, though. let infcx_; @@ -2431,7 +2434,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } }; - let param_env = tcx.param_env(block.owner.to_def_id()); + // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors + // when inside of an ADT (#108491) or where clause. + let param_env = tcx.param_env(block.owner); let cause = ObligationCause::misc(span, block.owner.def_id); let mut fulfillment_errors = Vec::new(); @@ -2439,6 +2444,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let universe = infcx.create_next_universe(); // Regions are not considered during selection. + // FIXME(non_lifetime_binders): Here we are "truncating" or "flattening" the universes + // of type and const binders. Is that correct in the selection phase? See also #109505. let self_ty = tcx.replace_escaping_bound_vars_uncached( self_ty, FnMutDelegate { @@ -2454,41 +2461,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { candidates .iter() - .filter_map(|&(impl_, (assoc_item, def_scope))| { + .copied() + .filter(|&(impl_, _)| { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); - let impl_ty = tcx.type_of(impl_); let impl_substs = infcx.fresh_item_substs(impl_); - let impl_ty = impl_ty.subst(tcx, impl_substs); + let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs); let impl_ty = ocx.normalize(&cause, param_env, impl_ty); - // Check that the Self-types can be related. - // FIXME(fmease): Should we use `eq` here? - ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?; + // Check that the self types can be related. + // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses + // `sup` for this situtation, too. What for? To constrain inference variables? + if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() + { + return false; + } // Check whether the impl imposes obligations we have to worry about. - let impl_bounds = tcx.predicates_of(impl_); - let impl_bounds = impl_bounds.instantiate(tcx, impl_substs); - + let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_substs); let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds); - let impl_obligations = traits::predicates_for_generics( |_, _| cause.clone(), param_env, impl_bounds, ); - ocx.register_obligations(impl_obligations); let mut errors = ocx.select_where_possible(); if !errors.is_empty() { fulfillment_errors.append(&mut errors); - return None; + return false; } - // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot. - Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs))) + true }) }) .collect() @@ -2497,24 +2503,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if applicable_candidates.len() > 1 { return Err(self.complain_about_ambiguous_inherent_assoc_type( name, - applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(), + applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(), span, )); } - if let Some((assoc_item, def_scope, impl_substs)) = applicable_candidates.pop() { + if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() { self.check_assoc_ty(assoc_item, name, def_scope, block, span); - // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, we still - // need to relate the Self-type with fresh item substs & register region obligations for - // regionck to prove/disprove. - - let item_substs = - self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs); + // FIXME(fmease): Currently creating throwaway `parent_substs` to please + // `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to + // not require the parent substs logic. + let parent_substs = InternalSubsts::identity_for_item(tcx, impl_); + let substs = + self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs); + let substs = tcx.mk_substs_from_iter( + std::iter::once(ty::GenericArg::from(self_ty)) + .chain(substs.into_iter().skip(parent_substs.len())), + ); - // FIXME(fmease, #106722): Check if the bounds on the parameters of the - // associated type hold, if any. - let ty = tcx.type_of(assoc_item).subst(tcx, item_substs); + let ty = tcx.mk_alias(ty::Inherent, tcx.mk_alias_ty(assoc_item, substs)); return Ok(Some((ty, assoc_item))); } @@ -3709,7 +3717,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { )); } - if self_ty.span.edition() >= Edition::Edition2021 { + if self_ty.span.edition().rust_2021() { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = @@ -3723,7 +3731,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // check if the impl trait that we are considering is a impl of a local trait self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); - diag.emit(); + diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.struct_span_lint_hir( diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c4d4e0d6d78..d3495d3dbd7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -31,6 +31,7 @@ use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCtxt, TraitEngine, TraitEngineExt as _}; use std::ops::ControlFlow; @@ -222,7 +223,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { if check_opaque_for_cycles(tcx, item.owner_id.def_id, substs, span, &origin).is_err() { return; } - check_opaque_meets_bounds(tcx, item.owner_id.def_id, substs, span, &origin); + check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin); } /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result @@ -391,13 +392,12 @@ pub(super) fn check_opaque_for_cycles<'tcx>( fn check_opaque_meets_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, - substs: SubstsRef<'tcx>, span: Span, origin: &hir::OpaqueTyOrigin, ) { let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, - hir::OpaqueTyOrigin::TyAlias => def_id, + hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id), }; let param_env = tcx.param_env(defining_use_anchor); @@ -406,6 +406,8 @@ fn check_opaque_meets_bounds<'tcx>( .with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)) .build(); let ocx = ObligationCtxt::new(&infcx); + + let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs); // `ReErased` regions appear in the "parent_substs" of closures/generators. @@ -448,9 +450,18 @@ fn check_opaque_meets_bounds<'tcx>( match origin { // Checked when type checking the function containing them. hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {} + // Nested opaque types occur only in associated types: + // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; ` + // They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`. + // We don't have to check them here because their well-formedness follows from the WF of + // the projection input types in the defining- and use-sites. + hir::OpaqueTyOrigin::TyAlias { .. } + if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {} // Can have different predicates to their defining use - hir::OpaqueTyOrigin::TyAlias => { - let outlives_env = OutlivesEnvironment::new(param_env); + hir::OpaqueTyOrigin::TyAlias { .. } => { + let wf_tys = ocx.assumed_wf_types(param_env, span, def_id); + let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let _ = ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env); } } @@ -1503,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/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 5ba1ca1c807..e0ba255cc06 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::util::IgnoreRegions; +use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{self, TyCtxt}; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -81,7 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( self_type_did: DefId, adt_to_impl_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, IgnoreRegions::No) else { + let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound) else { return Ok(()) }; 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/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index d05d8508408..a98d8e17153 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -298,9 +298,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); - let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| { - tcx.sess.fatal(format!("`CoerceUnsized` implementation {}", err.to_string())); - }); + let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); let source = tcx.type_of(impl_did).subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); 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/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 5ce8a83aad7..23beacd2a8c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, DelayDm}; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::util::IgnoreRegions; +use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{ self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -210,6 +210,19 @@ fn do_orphan_check_impl<'tcx>( NonlocalImpl::DisallowOther, ), + // ``` + // struct S<T>(T); + // impl<T: ?Sized> S<T> { + // type This = T; + // } + // impl<T: ?Sized> AutoTrait for S<T>::This {} + // ``` + // FIXME(inherent_associated_types): The example code above currently leads to a cycle + ty::Alias(AliasKind::Inherent, _) => ( + LocalImpl::Disallow { problematic_kind: "associated type" }, + NonlocalImpl::DisallowOther, + ), + // type Opaque = impl Trait; // impl AutoTrait for Opaque {} ty::Alias(AliasKind::Opaque, _) => ( @@ -494,7 +507,7 @@ fn lint_auto_trait_impl<'tcx>( // Impls which completely cover a given root type are fine as they // disable auto impls entirely. So only lint if the substs // are not a permutation of the identity substs. - let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else { + let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else { // ok return; }; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b65817ee95e..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}; @@ -1483,7 +1483,7 @@ fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorK fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { match tcx.hir().get_by_def_id(def_id) { Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => { - matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) + matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }) } _ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id), } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 119933697a1..ed60998ec8d 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -51,7 +51,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed. None } else if tcx.lazy_normalization() { - if let Some(param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) { + let parent_node = tcx.hir().get_parent(hir_id); + if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node + && constant.hir_id == hir_id + { + // enum variant discriminants are not allowed to use any kind of generics + None + } else if let Some(param_id) = + tcx.hir().opt_const_param_default_param_def_id(hir_id) + { // If the def_id we are calling generics_of on is an anon ct default i.e: // // struct Foo<const N: usize = { .. }>; @@ -94,15 +102,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { has_self: generics.has_self, has_late_bound_regions: generics.has_late_bound_regions, }; + } else { + // HACK(eddyb) this provides the correct generics when + // `feature(generic_const_expressions)` is enabled, so that const expressions + // used with const generics, e.g. `Foo<{N+1}>`, can work at all. + // + // Note that we do not supply the parent generics when using + // `min_const_generics`. + Some(parent_def_id.to_def_id()) } - - // HACK(eddyb) this provides the correct generics when - // `feature(generic_const_expressions)` is enabled, so that const expressions - // used with const generics, e.g. `Foo<{N+1}>`, can work at all. - // - // Note that we do not supply the parent generics when using - // `min_const_generics`. - Some(parent_def_id.to_def_id()) } else { let parent_node = tcx.hir().get_parent(hir_id); match parent_node { @@ -115,11 +123,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { { Some(parent_def_id.to_def_id()) } - Node::Variant(Variant { disr_expr: Some(constant), .. }) - if constant.hir_id == hir_id => - { - Some(parent_def_id.to_def_id()) - } Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => { Some(tcx.typeck_root_def_id(def_id.to_def_id())) } @@ -156,7 +159,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } Some(fn_def_id.to_def_id()) } - ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { + ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. + }) => { let parent_id = tcx.hir().get_parent_item(hir_id); assert_ne!(parent_id, hir::CRATE_OWNER_ID); debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e04658c8e77..a33990813b8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -721,7 +721,7 @@ pub(super) fn type_param_predicates( | ItemKind::TyAlias(_, generics) | ItemKind::OpaqueTy(OpaqueTy { generics, - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. }) | ItemKind::Enum(_, generics) 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 821567c1d88..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), @@ -526,7 +527,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, .. + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. }) => { // Opaque types are visited when we visit the // `TyKind::OpaqueDef`, so that they have the lifetimes from @@ -707,7 +709,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let opaque_ty = self.tcx.hir().item(item_id); match &opaque_ty.kind { hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. }) => { intravisit::walk_ty(self, ty); @@ -1948,7 +1950,7 @@ fn is_late_bound_map( ty::Param(param_ty) => { self.arg_is_constrained[param_ty.index as usize] = true; } - ty::Alias(ty::Projection, _) => return ControlFlow::Continue(()), + ty::Alias(ty::Projection | ty::Inherent, _) => return ControlFlow::Continue(()), _ => (), } t.super_visit_with(self) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c20fbfd1e40..6c7c2b9eea2 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -127,7 +127,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { // the def_id that this query was called with. We filter to only type and const args here // as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't // but it can't hurt to be safe ^^ - if let ty::Alias(ty::Projection, projection) = ty.kind() { + if let ty::Alias(ty::Projection | ty::Inherent, projection) = ty.kind() { let generics = tcx.generics_of(projection.def_id); let arg_index = segment @@ -426,9 +426,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_adt(def, substs) } - ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { - find_opaque_ty_constraints_for_tait(tcx, def_id) - } + ItemKind::OpaqueTy(OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. + }) => find_opaque_ty_constraints_for_tait(tcx, def_id), // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(OpaqueTy { origin: diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index e18b0f08279..9200c2aecf5 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -59,7 +59,7 @@ struct ParameterCollector { impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { match *t.kind() { - ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => { + ty::Alias(ty::Projection | ty::Inherent, ..) if !self.include_nonconstraining => { // projections are not injective return ControlFlow::Continue(()); } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 379a88538a9..6e7eb4f6cdc 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -815,6 +815,15 @@ pub(crate) struct ClosureImplicitHrtb { } #[derive(Diagnostic)] +#[diag(hir_analysis_empty_specialization)] +pub(crate) struct EmptySpecialization { + #[primary_span] + pub span: Span, + #[note] + pub base_impl_span: Span, +} + +#[derive(Diagnostic)] #[diag(hir_analysis_const_specialize)] pub(crate) struct ConstSpecialize { #[primary_span] 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/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 5cca2dacb5c..e84da2519ae 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -80,7 +80,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; -use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt}; +use rustc_trait_selection::traits::{self, translate_substs_with_cause, wf, ObligationCtxt}; pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { if let Some(node) = parent_specialization_node(tcx, impl_def_id) { @@ -100,12 +100,19 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti // Implementing a normal trait isn't a specialization. return None; } + if trait_def.is_marker { + // Overlapping marker implementations are not really specializations. + return None; + } Some(impl2_node) } /// Check that `impl1` is a sound specialization #[instrument(level = "debug", skip(tcx))] fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) { + let span = tcx.def_span(impl1_def_id); + check_has_items(tcx, impl1_def_id, impl2_node, span); + if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) { let impl2_def_id = impl2_node.def_id(); debug!(?impl2_def_id, ?impl2_substs); @@ -116,7 +123,6 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node unconstrained_parent_impl_substs(tcx, impl2_def_id, impl2_substs) }; - let span = tcx.def_span(impl1_def_id); check_constness(tcx, impl1_def_id, impl2_node, span); check_static_lifetimes(tcx, &parent_substs, span); check_duplicate_params(tcx, impl1_substs, &parent_substs, span); @@ -124,6 +130,13 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node } } +fn check_has_items(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) { + if let Node::Impl(impl2_id) = impl2_node && tcx.associated_item_def_ids(impl1_def_id).is_empty() { + let base_impl_span = tcx.def_span(impl2_id); + tcx.sess.emit_err(errors::EmptySpecialization { span, base_impl_span }); + } +} + /// Check that the specializing impl `impl1` is at least as const as the base /// impl `impl2` fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) { @@ -167,8 +180,21 @@ fn get_impl_substs( ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id); let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id); - let impl2_substs = - translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node); + let impl1_span = tcx.def_span(impl1_def_id); + let impl2_substs = translate_substs_with_cause( + infcx, + param_env, + impl1_def_id.to_def_id(), + impl1_substs, + impl2_node, + |_, span| { + traits::ObligationCause::new( + impl1_span, + impl1_def_id, + traits::ObligationCauseCode::BindingObligation(impl2_node.def_id(), span), + ) + }, + ); let errors = ocx.select_all_or_error(); if !errors.is_empty() { 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/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index d53c429ca15..0cd2fc1aa29 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -210,6 +210,9 @@ fn insert_required_predicates_to_be_wf<'tcx>( ); } + // FIXME(inherent_associated_types): Handle this case properly. + ty::Alias(ty::Inherent, _) => {} + _ => {} } } 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/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index aa664031a87..4a669e3f8b8 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -79,3 +79,14 @@ hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new` + +hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> + [true] {""} + *[other] {" "}in the current scope +} + +hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> + [NONE] {""} + [implement] , perhaps you need to implement it + *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it +} diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 9d59cdcbc60..2defca54aff 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -86,9 +86,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error); self.note_type_is_not_clone(err, expected, expr_ty, expr); self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty); - self.check_for_range_as_method_call(err, expr, expr_ty, expected); - self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected); - self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty); + self.suggest_method_call_on_range_literal(err, expr, expr_ty, expected); + self.suggest_return_binding_for_missing_tail_expr(err, expr, expr_ty, expected); + self.note_wrong_return_ty_due_to_generic_arg(err, expr, expr_ty); } /// Requires that the two types unify, and prints an error message if @@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// ```ignore (illustrative) /// opt.map(|param| { takes_ref(param) }); /// ``` - fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> { + fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Vec<(Span, String)>, &'static str)> { let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else { return None; }; @@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => false, }; - match (is_as_ref_able, self.sess().source_map().span_to_snippet(method_path.ident.span)) { - (true, Ok(src)) => { - let suggestion = format!("as_ref().{}", src); - Some((method_path.ident.span, "consider using `as_ref` instead", suggestion)) - } - _ => None, + if is_as_ref_able { + Some(( + vec![(method_path.ident.span.shrink_to_lo(), "as_ref().".to_string())], + "consider using `as_ref` instead", + )) + } else { + None } } @@ -1217,14 +1218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// In addition of this check, it also checks between references mutability state. If the /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with /// `&mut`!". - pub fn check_ref( + pub fn suggest_deref_or_ref( &self, expr: &hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, ) -> Option<( - Span, - String, + Vec<(Span, String)>, String, Applicability, bool, /* verbose */ @@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "b\"", "\"").is_some() { - let pos = sp.lo() + BytePos(1); - return Some(( - sp.with_hi(pos), - "consider removing the leading `b`".to_string(), - String::new(), - Applicability::MachineApplicable, - true, - false, - )); - } - } + let pos = sp.lo() + BytePos(1); + return Some(( + vec![(sp.with_hi(pos), String::new())], + "consider removing the leading `b`".to_string(), + Applicability::MachineApplicable, + true, + false, + )); + } + } (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "\"", "b\"").is_some() { - return Some(( - sp.shrink_to_lo(), - "consider adding a leading `b`".to_string(), - "b".to_string(), - Applicability::MachineApplicable, - true, - false, - )); + return Some(( + vec![(sp.shrink_to_lo(), "b".to_string())], + "consider adding a leading `b`".to_string(), + Applicability::MachineApplicable, + true, + false, + )); } } _ => {} @@ -1320,66 +1318,73 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind - && let Some(1) = self.deref_steps(expected, checked_ty) { + && let Some(1) = self.deref_steps(expected, checked_ty) + { // We have `*&T`, check if what was expected was `&T`. // If so, we may want to suggest removing a `*`. sugg_sp = sugg_sp.with_hi(inner.span.lo()); return Some(( - sugg_sp, + vec![(sugg_sp, String::new())], "consider removing deref here".to_string(), - "".to_string(), Applicability::MachineApplicable, true, false, )); } - if let Ok(src) = sm.span_to_snippet(sugg_sp) { - let needs_parens = match expr.kind { - // parenthesize if needed (Issue #46756) - hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, - // parenthesize borrows of range literals (Issue #54505) - _ if is_range_literal(expr) => true, - _ => false, - }; - - if let Some(sugg) = self.can_use_as_ref(expr) { - return Some(( - sugg.0, - sugg.1.to_string(), - sugg.2, - Applicability::MachineApplicable, - false, - false, - )); - } - - let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{ident}: "), - None => String::new(), - }; - - if let Some(hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Assign(..), - .. - })) = self.tcx.hir().find_parent(expr.hir_id) - { - if mutability.is_mut() { - // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` - return None; - } - } + let needs_parens = match expr.kind { + // parenthesize if needed (Issue #46756) + hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true, + // parenthesize borrows of range literals (Issue #54505) + _ if is_range_literal(expr) => true, + _ => false, + }; - let sugg_expr = if needs_parens { format!("({src})") } else { src }; + if let Some((sugg, msg)) = self.can_use_as_ref(expr) { return Some(( - sp, - format!("consider {}borrowing here", mutability.mutably_str()), - format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()), + sugg, + msg.to_string(), Applicability::MachineApplicable, - false, + true, false, )); } + + let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { + Some(ident) => format!("{ident}: "), + None => String::new(), + }; + + if let Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Assign(..), + .. + })) = self.tcx.hir().find_parent(expr.hir_id) + { + if mutability.is_mut() { + // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` + return None; + } + } + + let sugg = mutability.ref_prefix_str(); + let (sugg, verbose) = if needs_parens { + ( + vec![ + (sp.shrink_to_lo(), format!("{prefix}{sugg}(")), + (sp.shrink_to_hi(), ")".to_string()), + ], + false, + ) + } else { + (vec![(sp.shrink_to_lo(), format!("{prefix}{sugg}"))], true) + }; + return Some(( + sugg, + format!("consider {}borrowing here", mutability.mutably_str()), + Applicability::MachineApplicable, + verbose, + false, + )); } } ( @@ -1401,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && sm.is_span_accessible(call_span) { return Some(( - sp.with_hi(call_span.lo()), + vec![(sp.with_hi(call_span.lo()), String::new())], "consider removing the borrow".to_string(), - String::new(), Applicability::MachineApplicable, true, - true + true, )); } return None; } - if sp.contains(expr.span) - && sm.is_span_accessible(expr.span) - { + if sp.contains(expr.span) && sm.is_span_accessible(expr.span) { return Some(( - sp.with_hi(expr.span.lo()), + vec![(sp.with_hi(expr.span.lo()), String::new())], "consider removing the borrow".to_string(), - String::new(), Applicability::MachineApplicable, true, true, @@ -1441,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| { // skip `&` or `&mut ` if both mutabilities are mutable - let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _); + let lo = sp.lo() + + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _); // skip `&` or `&mut ` let hi = sp.lo() + BytePos(old_prefix.len() as _); let sp = sp.with_lo(lo).with_hi(hi); ( sp, - format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }), - if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect } + format!( + "{}{derefs}", + if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" } + ), + if mutbl_b <= mutbl_a { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }, ) }); if let Some((span, src, applicability)) = suggestion { return Some(( - span, + vec![(span, src)], "consider dereferencing".to_string(), - src, applicability, true, false, @@ -1486,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we've reached our target type with just removing `&`, then just print now. if steps == 0 && !remove.trim().is_empty() { return Some(( - prefix_span, + vec![(prefix_span, String::new())], format!("consider removing the `{}`", remove.trim()), - String::new(), // Do not remove `&&` to get to bool, because it might be something like // { a } && b, which we have a separate fixup suggestion that is more // likely correct... @@ -1554,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } return Some(( - span, + vec![(span, suggestion)], message, - suggestion, Applicability::MachineApplicable, true, false, @@ -1569,7 +1575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } - pub fn check_for_cast( + pub fn suggest_cast( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, @@ -1936,7 +1942,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Identify when the user has written `foo..bar()` instead of `foo.bar()`. - pub fn check_for_range_as_method_call( + pub fn suggest_method_call_on_range_literal( &self, err: &mut Diagnostic, expr: &hir::Expr<'tcx>, @@ -2005,7 +2011,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Identify when the type error is because `()` is found in a binding that was assigned a /// block without a tail expression. - fn check_for_binding_assigned_block_without_tail_expression( + fn suggest_return_binding_for_missing_tail_expr( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, @@ -2047,7 +2053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_wrong_return_type_due_to_generic_arg( + fn note_wrong_return_ty_due_to_generic_arg( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index ce30bbeca0b..102a313067f 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,4 +1,6 @@ //! Errors emitted by `rustc_hir_typeck`. +use std::borrow::Cow; + use crate::fluent_generated as fluent; use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -295,3 +297,25 @@ pub enum SuggestBoxing { end: Span, }, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_no_associated_item, code = "E0599")] +pub struct NoAssociatedItem { + #[primary_span] + pub span: Span, + pub item_kind: &'static str, + pub item_name: Ident, + pub ty_prefix: Cow<'static, str>, + pub ty_str: String, + pub trait_missing_method: bool, +} + +#[derive(Subdiagnostic)] +#[note(hir_typeck_candidate_trait_note)] +pub struct CandidateTraitNote { + #[primary_span] + pub span: Span, + pub trait_name: String, + pub item_name: Ident, + pub action_or_ty: String, +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bba049c3819..8ea159bba74 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1245,6 +1245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, Some((rcvr, args)), expected, + false, ) { err.emit(); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e78e6acba5..039316c74dd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -4,7 +4,7 @@ use crate::rvalue_scopes; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -853,6 +853,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let item_name = item_segment.ident; let result = self .resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id) + .and_then(|r| { + // lint bare trait if the method is found in the trait + if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + diag.emit(); + } + Ok(r) + }) .or_else(|error| { let guar = self .tcx @@ -863,17 +870,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Err(guar), }; + let trait_missing_method = + matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait(); // If we have a path like `MyTrait::missing_method`, then don't register // a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise, // register a WF obligation so that we can detect any additional // errors in the self type. - if !(matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait()) { + if !trait_missing_method { self.register_wf_obligation( ty.raw.into(), qself.span, traits::WellFormed(None), ); } + + // emit or cancel the diagnostic for bare traits + if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if trait_missing_method { + // cancel the diag for bare traits when meeting `MyTrait::missing_method` + diag.cancel(); + } else { + diag.emit(); + } + } + if item_name.name != kw::Empty { if let Some(mut e) = self.report_method_error( span, @@ -883,10 +903,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, None, Expectation::NoExpectation, + trait_missing_method && span.edition().rust_2021(), // emits missing method for trait only after edition 2021 ) { e.emit(); } } + result }); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 70ce45e21ea..3efdab53438 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -278,9 +278,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, ) -> bool { if let traits::FulfillmentErrorCode::CodeSelectionError( - traits::SelectionError::OutputTypeParameterMismatch(_, expected, _), + traits::SelectionError::OutputTypeParameterMismatch(box traits::SelectionOutputTypeParameterMismatch{ + expected_trait_ref, .. + }), ) = error.code - && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind() + && let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected_trait_ref.skip_binder().self_ty().kind() && span.overlaps(self.tcx.def_span(*def_id)) { true @@ -843,7 +845,7 @@ fn find_param_in_ty<'tcx>( return true; } if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Projection, ..) = ty.kind() + && let ty::Alias(ty::Projection | ty::Inherent, ..) = ty.kind() { // This logic may seem a bit strange, but typically when // we have a projection type in a function signature, the diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 73a7bbebb65..67f45f9aa3f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -300,7 +300,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { match ty.kind() { ty::Adt(adt_def, _) => Some(*adt_def), // FIXME(#104767): Should we handle bound regions here? - ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => { + ty::Alias(ty::Projection | ty::Inherent, _) if !ty.has_escaping_bound_vars() => { self.normalize(span, ty).ty_adt_def() } _ => None, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 2867fcc8ecd..c4add4dbdfb 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -275,13 +275,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, ) -> bool { let expr = expr.peel_blocks(); - if let Some((sp, msg, suggestion, applicability, verbose, annotation)) = - self.check_ref(expr, found, expected) + if let Some((suggestion, msg, applicability, verbose, annotation)) = + self.suggest_deref_or_ref(expr, found, expected) { if verbose { - err.span_suggestion_verbose(sp, msg, suggestion, applicability); + err.multipart_suggestion_verbose(msg, suggestion, applicability); } else { - err.span_suggestion(sp, msg, suggestion, applicability); + err.multipart_suggestion(msg, suggestion, applicability); } if annotation { let suggest_annotation = match expr.peel_drop_temps().kind { @@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(sp, format!("{descr} `{name}` defined here")); } return true; - } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) { + } else if self.suggest_cast(err, expr, found, expected, expected_ty_expr) { return true; } else { let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index a2a4362e2f5..54b222ade03 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -2,6 +2,7 @@ #![feature(let_chains)] #![feature(try_blocks)] #![feature(never_type)] +#![feature(box_patterns)] #![feature(min_specialization)] #![feature(control_flow_enum)] #![feature(drain_filter)] @@ -67,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 30f0978d190..12bc17ca97c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2,6 +2,8 @@ //! found or is otherwise invalid. use crate::errors; +use crate::errors::CandidateTraitNote; +use crate::errors::NoAssociatedItem; use crate::Expectation; use crate::FnCtxt; use rustc_ast::ast::Mutability; @@ -38,6 +40,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _ use rustc_trait_selection::traits::{ FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, }; +use std::borrow::Cow; use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; @@ -112,6 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, expected: Expectation<'tcx>, + trait_missing_method: bool, ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { // Avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { @@ -136,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_span, &mut no_match_data, expected, + trait_missing_method, ); } @@ -278,6 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_span: Span, no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, + trait_missing_method: bool, ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> { let mode = no_match_data.mode; let tcx = self.tcx; @@ -323,7 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). - let mut ty_str_reported = ty_str.clone(); + let mut ty_str_reported = if trait_missing_method { + ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned() + } else { + ty_str.clone() + }; + if let ty::Adt(_, generics) = rcvr_ty.kind() { if generics.len() > 0 { let mut autoderef = self.autoderef(span, rcvr_ty); @@ -355,25 +366,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { self.suggest_missing_writer(rcvr_ty, args) } else { - struct_span_err!( - tcx.sess, + tcx.sess.create_err(NoAssociatedItem { span, - E0599, - "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, - rcvr_ty.prefix_string(self.tcx), - ty_str_reported, - ) + ty_prefix: if trait_missing_method { + // FIXME(mu001999) E0599 maybe not suitable here because it is for types + Cow::from("trait") + } else { + rcvr_ty.prefix_string(self.tcx) + }, + ty_str: ty_str_reported, + trait_missing_method, + }) }; if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } - let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { + let mut ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { short_ty_str } else { ty_str }; + if trait_missing_method { + ty_str = + ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned(); + } + if let Some(file) = ty_file { err.note(format!("the full type name has been written to '{}'", file.display(),)); } @@ -1045,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - self.check_for_inner_self(&mut err, source, rcvr_ty, item_name); + self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name); bound_spans.sort(); bound_spans.dedup(); @@ -1067,6 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &static_candidates, unsatisfied_bounds, expected.only_has_type(self), + trait_missing_method, ); } @@ -1132,7 +1152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - self.check_for_deref_method(&mut err, source, rcvr_ty, item_name, expected); + self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); return Some(err); } @@ -1805,7 +1825,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_for_inner_self( + fn suggest_unwrapping_inner_self( &self, err: &mut Diagnostic, source: SelfSource<'tcx>, @@ -2175,7 +2195,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_for_deref_method( + fn note_derefed_ty_has_method( &self, err: &mut Diagnostic, self_source: SelfSource<'tcx>, @@ -2211,7 +2231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Float(_) | ty::Adt(_, _) | ty::Str - | ty::Alias(ty::Projection, _) + | ty::Alias(ty::Projection | ty::Inherent, _) | ty::Param(_) => format!("{deref_ty}"), // we need to test something like <&[_]>::len or <(&[u32])>::len // and Vec::function(); @@ -2375,6 +2395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { static_candidates: &[CandidateSource], unsatisfied_bounds: bool, return_type: Option<Ty<'tcx>>, + trait_missing_method: bool, ) { let mut alt_rcvr_sugg = false; if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { @@ -2598,11 +2619,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, _ => None, }; - err.help(if param_type.is_some() { - "items from traits can only be used if the type parameter is bounded by the trait" - } else { - "items from traits can only be used if the trait is implemented and in scope" - }); + if !trait_missing_method { + err.help(if param_type.is_some() { + "items from traits can only be used if the type parameter is bounded by the trait" + } else { + "items from traits can only be used if the trait is implemented and in scope" + }); + } + let candidates_len = candidates.len(); let message = |action| { format!( @@ -2633,47 +2657,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 { @@ -2736,27 +2775,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (candidates, Vec::new()) }; - let action = if let Some(param) = param_type { - format!("restrict type parameter `{}` with", param) - } else { - // FIXME: it might only need to be imported into scope, not implemented. - "implement".to_string() - }; match &potential_candidates[..] { [] => {} [trait_info] if trait_info.def_id.is_local() => { - err.span_note( - self.tcx.def_span(trait_info.def_id), - format!( - "`{}` defines an item `{}`, perhaps you need to {} it", - self.tcx.def_path_str(trait_info.def_id), - item_name, - action - ), - ); + err.subdiagnostic(CandidateTraitNote { + span: self.tcx.def_span(trait_info.def_id), + trait_name: self.tcx.def_path_str(trait_info.def_id), + item_name, + action_or_ty: if trait_missing_method { + "NONE".to_string() + } else { + param_type.map_or_else( + || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. + ToString::to_string, + ) + }, + }); } trait_infos => { - let mut msg = message(action); + let mut msg = message(param_type.map_or_else( + || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. + |param| format!("restrict type parameter `{}` with", param), + )); for (i, trait_info) in trait_infos.iter().enumerate() { msg.push_str(&format!( "\ncandidate #{}: `{}`", 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 2a51439b0a9..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, @@ -127,7 +113,8 @@ impl<'tcx> InferCtxt<'tcx> { bug!() } - (_, ty::Alias(AliasKind::Projection, _)) | (ty::Alias(AliasKind::Projection, _), _) + (_, ty::Alias(AliasKind::Projection | AliasKind::Inherent, _)) + | (ty::Alias(AliasKind::Projection | AliasKind::Inherent, _), _) if self.tcx.trait_solver_next() => { relation.register_type_relate_obligation(a, b); @@ -151,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), } } @@ -208,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 }); @@ -236,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() => @@ -251,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. @@ -293,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, @@ -391,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()); @@ -411,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); @@ -430,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()); } @@ -513,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>); @@ -872,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 98da5ba65b7..ad4f5058b5e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2354,7 +2354,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let labeled_user_string = match bound_kind { GenericKind::Param(ref p) => format!("the parameter type `{}`", p), GenericKind::Alias(ref p) => match p.kind(self.tcx) { - ty::AliasKind::Projection => format!("the associated type `{}`", p), + ty::AliasKind::Projection | ty::AliasKind::Inherent => { + format!("the associated type `{}`", p) + } ty::AliasKind::Opaque => format!("the opaque type `{}`", p), }, }; @@ -2721,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/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index a3116351940..421eb807a14 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -2,6 +2,7 @@ use super::TypeErrCtxt; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, Diagnostic, MultiSpan}; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::Printer; @@ -71,9 +72,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #traits-as-parameters", ); } - (ty::Alias(ty::Projection, _), ty::Alias(ty::Projection, _)) => { + (ty::Alias(ty::Projection | ty::Inherent, _), ty::Alias(ty::Projection | ty::Inherent, _)) => { diag.note("an associated type was expected, but a different one was found"); } + // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. (ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p)) if !tcx.is_impl_trait_in_trait(proj.def_id) => { @@ -222,7 +224,7 @@ impl<T> Trait<T> for X { diag.span_label(p_span, "this type parameter"); } } - (ty::Alias(ty::Projection, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { + (ty::Alias(ty::Projection | ty::Inherent, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { self.expected_projection( diag, proj_ty, @@ -231,7 +233,7 @@ impl<T> Trait<T> for X { cause.code(), ); } - (_, ty::Alias(ty::Projection, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { + (_, ty::Alias(ty::Projection | ty::Inherent, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { let msg = format!( "consider constraining the associated type `{}` to `{}`", values.found, values.expected, @@ -255,6 +257,15 @@ impl<T> Trait<T> for X { ); } } + (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => { + if tcx.is_type_alias_impl_trait(alias.def_id) { + if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) { + diag.span_note(tcx.def_span(body_owner_def_id), "\ + this item must have the opaque type in its signature \ + in order to be able to register hidden types"); + } + } + } (ty::FnPtr(_), ty::FnDef(def, _)) if let hir::def::DefKind::Fn = tcx.def_kind(def) => { diag.note( 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 a89b9931599..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; @@ -1530,10 +1531,10 @@ impl<'tcx> InferCtxt<'tcx> { // variables let tcx = self.tcx; if substs.has_non_region_infer() { - if let Some(ct) = tcx.bound_abstract_const(unevaluated.def)? { + 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 88a0a81e276..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(variables); - 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/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 334395945ea..545310ad351 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -149,7 +149,7 @@ impl<'tcx> InferCtxt<'tcx> { // no one encounters it in practice. // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`, // where it is of no concern, so we only check for TAITs. - if let Some(OpaqueTyOrigin::TyAlias) = + if let Some(OpaqueTyOrigin::TyAlias { .. }) = b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id)) { self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { @@ -381,8 +381,12 @@ impl<'tcx> InferCtxt<'tcx> { // Anonymous `impl Trait` hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id, // Named `type Foo = impl Bar;` - hir::OpaqueTyOrigin::TyAlias => { - may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { + if in_assoc_ty { + self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id) + } else { + may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) + } } }; in_definition_scope.then_some(origin) @@ -549,6 +553,7 @@ impl<'tcx> InferCtxt<'tcx> { // We can't normalize associated types from `rustc_infer`, // but we can eagerly register inference variables for them. // FIXME(RPITIT): Don't replace RPITITs with inference vars. + // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. ty::Alias(ty::Projection, projection_ty) if !projection_ty.has_escaping_bound_vars() && !tcx.is_impl_trait_in_trait(projection_ty.def_id) => @@ -569,6 +574,7 @@ impl<'tcx> InferCtxt<'tcx> { hidden_ty } // FIXME(RPITIT): This can go away when we move to associated types + // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. ty::Alias( ty::Projection, ty::AliasTy { def_id: def_id2, substs: substs2, .. }, 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 9d9f4ee13f4..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 |_| { @@ -173,12 +178,21 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg { let expected_values = check_cfg .expecteds .entry(ident.name.to_string()) + .and_modify(|expected_values| match expected_values { + ExpectedValues::Some(_) => {} + ExpectedValues::Any => { + // handle the case where names(...) was done + // before values by changing to a list + *expected_values = + ExpectedValues::Some(FxHashSet::default()); + } + }) .or_insert_with(|| { ExpectedValues::Some(FxHashSet::default()) }); let ExpectedValues::Some(expected_values) = expected_values else { - bug!("shoudn't be possible") + bug!("`expected_values` should be a list a values") }; for val in values { @@ -261,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: @@ -338,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..bbf9d9d515d 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}; @@ -691,6 +691,8 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } + let incremental = dep_graph.is_fully_enabled(); + sess.time("setup_global_ctxt", || { gcx_cell.get_or_init(move || { TyCtxt::create_global_ctxt( @@ -700,9 +702,13 @@ 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, + incremental, + ), ) }) }) 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/messages.ftl b/compiler/rustc_lint/messages.ftl index 71cf644eb50..a5639404faf 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -520,3 +520,19 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass .specifically = this associated type bound is unsatisfied for `{$proj_ty}` lint_opaque_hidden_inferred_bound_sugg = add this bound + +lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing + .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result + +lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing + .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result + +lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing + .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result + +lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing + .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 0b7a704eb57..6601a80920b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -62,6 +62,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef}; use rustc_session::config::ExpectedValues; use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason}; @@ -610,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 /// @@ -646,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 { @@ -726,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 /// @@ -765,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; } @@ -1442,6 +1447,10 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { // Bounds are respected for `type X = impl Trait` return; } + if cx.tcx.type_of(item.owner_id).skip_binder().has_inherent_projections() { + // Bounds are respected for `type X = … Type::Inherent …` + return; + } // There must not be a where clause if type_alias_generics.predicates.is_empty() { return; @@ -1561,7 +1570,6 @@ declare_lint_pass!( impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { - use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::Clause; use rustc_middle::ty::PredicateKind::*; @@ -1878,8 +1886,8 @@ declare_lint_pass!( struct UnderMacro(bool); impl KeywordIdents { - fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) { - for tt in tokens.into_trees() { + fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: &TokenStream) { + for tt in tokens.trees() { match tt { // Only report non-raw idents. TokenTree::Token(token, _) => { @@ -1940,10 +1948,10 @@ impl KeywordIdents { impl EarlyLintPass for KeywordIdents { fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) { - self.check_tokens(cx, mac_def.body.tokens.clone()); + self.check_tokens(cx, &mac_def.body.tokens); } fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) { - self.check_tokens(cx, mac.args.tokens.clone()); + self.check_tokens(cx, &mac.args.tokens); } fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) { self.check_ident_token(cx, UnderMacro(false), ident); @@ -2898,6 +2906,7 @@ impl ClashingExternDeclarations { | (Generator(..), Generator(..)) | (GeneratorWitness(..), GeneratorWitness(..)) | (Alias(ty::Projection, ..), Alias(ty::Projection, ..)) + | (Alias(ty::Inherent, ..), Alias(ty::Inherent, ..)) | (Alias(ty::Opaque, ..), Alias(ty::Opaque, ..)) => false, // These definitely should have been caught above. 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/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs new file mode 100644 index 00000000000..259abc2af11 --- /dev/null +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -0,0 +1,164 @@ +use rustc_hir::{Arm, Expr, ExprKind, Node}; +use rustc_span::sym; + +use crate::{ + lints::{DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag}, + LateContext, LateLintPass, LintContext, +}; + +declare_lint! { + /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference + /// instead of an owned value. + /// + /// ### Example + /// + /// ```rust + /// # fn operation_that_requires_mutex_to_be_unlocked() {} // just to make it compile + /// # let mutex = std::sync::Mutex::new(1); // just to make it compile + /// let mut lock_guard = mutex.lock(); + /// std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex + /// // still locked + /// operation_that_requires_mutex_to_be_unlocked(); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `drop` on a reference will only drop the + /// reference itself, which is a no-op. It will not call the `drop` method (from + /// the `Drop` trait implementation) on the underlying referenced value, which + /// is likely what was intended. + pub DROP_REF, + Warn, + "calls to `std::mem::drop` with a reference instead of an owned value" +} + +declare_lint! { + /// The `forget_ref` lint checks for calls to `std::mem::forget` with a reference + /// instead of an owned value. + /// + /// ### Example + /// + /// ```rust + /// let x = Box::new(1); + /// std::mem::forget(&x); // Should have been forget(x), x will still be dropped + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `forget` on a reference will only forget the + /// reference itself, which is a no-op. It will not forget the underlying + /// referenced value, which is likely what was intended. + pub FORGET_REF, + Warn, + "calls to `std::mem::forget` with a reference instead of an owned value" +} + +declare_lint! { + /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value + /// that derives the Copy trait. + /// + /// ### Example + /// + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::drop(x); // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `std::mem::drop` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the + /// value will be copied and moved into the function on invocation. + pub DROP_COPY, + Warn, + "calls to `std::mem::drop` with a value that implements Copy" +} + +declare_lint! { + /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value + /// that derives the Copy trait. + /// + /// ### Example + /// + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::forget(x); // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `std::mem::forget` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the + /// value will be copied and moved into the function on invocation. + /// + /// An alternative, but also valid, explanation is that Copy types do not + /// implement the Drop trait, which means they have no destructors. Without a + /// destructor, there is nothing for `std::mem::forget` to ignore. + pub FORGET_COPY, + Warn, + "calls to `std::mem::forget` with a value that implements Copy" +} + +declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]); + +impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if let ExprKind::Call(path, [arg]) = expr.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) + { + let arg_ty = cx.typeck_results().expr_ty(arg); + let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env); + let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); + match fn_name { + sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { + cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, label: arg.span }); + }, + sym::mem_forget if arg_ty.is_ref() => { + cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, label: arg.span }); + }, + sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { + cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, label: arg.span }); + } + sym::mem_forget if is_copy => { + cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, label: arg.span }); + } + _ => return, + }; + } + } +} + +// Dropping returned value of a function, as in the following snippet is considered idiomatic, see +// rust-lang/rust-clippy#9482 for examples. +// +// ``` +// match <var> { +// <pat> => drop(fn_with_side_effect_and_returning_some_value()), +// .. +// } +// ``` +fn is_single_call_in_arm<'tcx>( + cx: &LateContext<'tcx>, + arg: &'tcx Expr<'_>, + drop_expr: &'tcx Expr<'_>, +) -> bool { + if matches!(arg.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)) { + let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id); + if let Some(Node::Arm(Arm { body, .. })) = &parent_node { + return body.hir_id == drop_expr.hir_id; + } + } + false +} 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 319eb2ea445..dfddfe09ab3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -52,6 +52,7 @@ mod array_into_iter; pub mod builtin; mod context; mod deref_into_dyn_supertrait; +mod drop_forget_useless; mod early; mod enum_intrinsics_non_enums; mod errors; @@ -85,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, @@ -96,6 +97,7 @@ use rustc_span::Span; use array_into_iter::ArrayIntoIter; use builtin::*; use deref_into_dyn_supertrait::*; +use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use hidden_unicode_codepoints::*; @@ -201,6 +203,7 @@ late_lint_methods!( [ ForLoopsOverFallibles: ForLoopsOverFallibles, DerefIntoDynSupertrait: DerefIntoDynSupertrait, + DropForgetUseless: DropForgetUseless, HardwiredLints: HardwiredLints, ImproperCTypesDeclarations: ImproperCTypesDeclarations, ImproperCTypesDefinitions: ImproperCTypesDefinitions, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index d7bacc6485f..8e48806b504 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -662,6 +662,43 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { pub end_span: Span, } +// drop_ref.rs +#[derive(LintDiagnostic)] +#[diag(lint_drop_ref)] +#[note] +pub struct DropRefDiag<'a> { + pub arg_ty: Ty<'a>, + #[label] + pub label: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_drop_copy)] +#[note] +pub struct DropCopyDiag<'a> { + pub arg_ty: Ty<'a>, + #[label] + pub label: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_forget_ref)] +#[note] +pub struct ForgetRefDiag<'a> { + pub arg_ty: Ty<'a>, + #[label] + pub label: Span, +} + +#[derive(LintDiagnostic)] +#[diag(lint_forget_copy)] +#[note] +pub struct ForgetCopyDiag<'a> { + pub arg_ty: Ty<'a>, + #[label] + pub label: Span, +} + // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a6ba742201a..125b4dc5503 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1119,14 +1119,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, // so they are currently ignored for the purposes of this lint. - ty::Param(..) | ty::Alias(ty::Projection, ..) + ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent, ..) if matches!(self.mode, CItemKind::Definition) => { FfiSafe } ty::Param(..) - | ty::Alias(ty::Projection, ..) + | ty::Alias(ty::Projection | ty::Inherent, ..) | ty::Infer(..) | ty::Bound(..) | ty::Error(_) diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 03e6d2149e9..87906dee4d3 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -8,18 +8,100 @@ using namespace llvm; +// FFI equivalent of enum `llvm::coverage::Counter::CounterKind` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L97-L99 +enum class LLVMRustCounterKind { + Zero = 0, + CounterValueReference = 1, + Expression = 2, +}; + +// FFI equivalent of struct `llvm::coverage::Counter` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L94-L149 +struct LLVMRustCounter { + LLVMRustCounterKind CounterKind; + uint32_t ID; +}; + +static coverage::Counter fromRust(LLVMRustCounter Counter) { + switch (Counter.CounterKind) { + case LLVMRustCounterKind::Zero: + return coverage::Counter::getZero(); + case LLVMRustCounterKind::CounterValueReference: + return coverage::Counter::getCounter(Counter.ID); + case LLVMRustCounterKind::Expression: + return coverage::Counter::getExpression(Counter.ID); + } + report_fatal_error("Bad LLVMRustCounterKind!"); +} + +// FFI equivalent of enum `llvm::coverage::CounterMappingRegion::RegionKind` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L213-L234 +enum class LLVMRustCounterMappingRegionKind { + CodeRegion = 0, + ExpansionRegion = 1, + SkippedRegion = 2, + GapRegion = 3, + BranchRegion = 4, +}; + +static coverage::CounterMappingRegion::RegionKind +fromRust(LLVMRustCounterMappingRegionKind Kind) { + switch (Kind) { + case LLVMRustCounterMappingRegionKind::CodeRegion: + return coverage::CounterMappingRegion::CodeRegion; + case LLVMRustCounterMappingRegionKind::ExpansionRegion: + return coverage::CounterMappingRegion::ExpansionRegion; + case LLVMRustCounterMappingRegionKind::SkippedRegion: + return coverage::CounterMappingRegion::SkippedRegion; + case LLVMRustCounterMappingRegionKind::GapRegion: + return coverage::CounterMappingRegion::GapRegion; + case LLVMRustCounterMappingRegionKind::BranchRegion: + return coverage::CounterMappingRegion::BranchRegion; + } + report_fatal_error("Bad LLVMRustCounterMappingRegionKind!"); +} + +// FFI equivalent of struct `llvm::coverage::CounterMappingRegion` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304 struct LLVMRustCounterMappingRegion { - coverage::Counter Count; - coverage::Counter FalseCount; + LLVMRustCounter Count; + LLVMRustCounter FalseCount; uint32_t FileID; uint32_t ExpandedFileID; uint32_t LineStart; uint32_t ColumnStart; uint32_t LineEnd; uint32_t ColumnEnd; - coverage::CounterMappingRegion::RegionKind Kind; + LLVMRustCounterMappingRegionKind Kind; +}; + +// FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L154 +enum class LLVMRustCounterExprKind { + Subtract = 0, + Add = 1, }; +// FFI equivalent of struct `llvm::coverage::CounterExpression` +// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L160 +struct LLVMRustCounterExpression { + LLVMRustCounterExprKind Kind; + LLVMRustCounter LHS; + LLVMRustCounter RHS; +}; + +static coverage::CounterExpression::ExprKind +fromRust(LLVMRustCounterExprKind Kind) { + switch (Kind) { + case LLVMRustCounterExprKind::Subtract: + return coverage::CounterExpression::Subtract; + case LLVMRustCounterExprKind::Add: + return coverage::CounterExpression::Add; + } + report_fatal_error("Bad LLVMRustCounterExprKind!"); +} + extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( const char* const Filenames[], size_t FilenamesLen, @@ -37,9 +119,9 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( extern "C" void LLVMRustCoverageWriteMappingToBuffer( const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs, - const coverage::CounterExpression *Expressions, + const LLVMRustCounterExpression *RustExpressions, unsigned NumExpressions, - LLVMRustCounterMappingRegion *RustMappingRegions, + const LLVMRustCounterMappingRegion *RustMappingRegions, unsigned NumMappingRegions, RustStringRef BufferOut) { // Convert from FFI representation to LLVM representation. @@ -48,13 +130,24 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer( for (const auto &Region : ArrayRef<LLVMRustCounterMappingRegion>( RustMappingRegions, NumMappingRegions)) { MappingRegions.emplace_back( - Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID, + fromRust(Region.Count), fromRust(Region.FalseCount), + Region.FileID, Region.ExpandedFileID, Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd, - Region.Kind); + fromRust(Region.Kind)); } + + std::vector<coverage::CounterExpression> Expressions; + Expressions.reserve(NumExpressions); + for (const auto &Expression : + ArrayRef<LLVMRustCounterExpression>(RustExpressions, NumExpressions)) { + Expressions.emplace_back(fromRust(Expression.Kind), + fromRust(Expression.LHS), + fromRust(Expression.RHS)); + } + auto CoverageMappingWriter = coverage::CoverageMappingWriter( ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs), - ArrayRef<coverage::CounterExpression>(Expressions, NumExpressions), + Expressions, MappingRegions); RawRustStringOstream OS(BufferOut); CoverageMappingWriter.write(OS); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index fc28f6efa44..c43a0272477 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -745,6 +745,9 @@ LLVMRustOptimize( if (InstrProfileOutput) { Options.InstrProfileOutput = InstrProfileOutput; } + // cargo run tests in multhreading mode by default + // so use atomics for coverage counters + Options.Atomic = true; MPM.addPass(InstrProfiling(Options, false)); } ); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 427c82c410b..cd6e3687460 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -9,7 +9,7 @@ use crate::diagnostics::utils::{ FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind, }; use proc_macro2::{Ident, Span, TokenStream}; -use quote::{format_ident, quote}; +use quote::{format_ident, quote, quote_spanned}; use syn::Token; use syn::{parse_quote, spanned::Spanned, Attribute, Meta, Path, Type}; use synstructure::{BindingInfo, Structure, VariantInfo}; @@ -251,7 +251,8 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { let diag = &self.parent.diag; let field = binding_info.ast(); - let field_binding = &binding_info.binding; + let mut field_binding = binding_info.binding.clone(); + field_binding.set_span(field.ty.span()); let ident = field.ident.as_ref().unwrap(); let ident = format_ident!("{}", ident); // strip `r#` prefix, if present @@ -284,9 +285,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_)); let (binding, needs_destructure) = if needs_clone { // `primary_span` can accept a `Vec<Span>` so don't destructure that. - (quote! { #field_binding.clone() }, false) + (quote_spanned! {inner_ty.span()=> #field_binding.clone() }, false) } else { - (quote! { #field_binding }, true) + (quote_spanned! {inner_ty.span()=> #field_binding }, true) }; let generated_code = self diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index bd84681cbb4..a536eb3b04e 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -140,7 +140,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// ```fluent /// parser_expected_identifier = expected identifier /// -/// parser_expected_identifier-found = expected identifier, found {$found} +/// parser_expected_identifier_found = expected identifier, found {$found} /// /// parser_raw_identifier = escape `{$ident}` to use it as an identifier /// ``` diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 62d49c1c64e..374ba1a45c0 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -4,17 +4,16 @@ use crate::diagnostics::error::{ invalid_attr, span_err, throw_invalid_attr, throw_span_err, DiagnosticDeriveError, }; use crate::diagnostics::utils::{ - build_field_mapping, is_doc_comment, new_code_ident, - report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo, - FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind, + build_field_mapping, build_suggestion_code, is_doc_comment, new_code_ident, + report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, + should_generate_set_arg, AllowMultipleAlternatives, FieldInfo, FieldInnerTy, FieldMap, + HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind, }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; use syn::{spanned::Spanned, Attribute, Meta, MetaList, Path}; use synstructure::{BindingInfo, Structure, VariantInfo}; -use super::utils::{build_suggestion_code, AllowMultipleAlternatives}; - /// The central struct for constructing the `add_to_diagnostic` method from an annotated struct. pub(crate) struct SubdiagnosticDeriveBuilder { diag: syn::Ident, @@ -210,19 +209,20 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } /// Generates the code for a field with no attributes. - fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream { - let ast = binding.ast(); - assert_eq!(ast.attrs.len(), 0, "field with attribute used as diagnostic arg"); - + fn generate_field_set_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream { let diag = &self.parent.diag; - let ident = ast.ident.as_ref().unwrap(); - // strip `r#` prefix, if present - let ident = format_ident!("{}", ident); + + let field = binding_info.ast(); + let mut field_binding = binding_info.binding.clone(); + field_binding.set_span(field.ty.span()); + + let ident = field.ident.as_ref().unwrap(); + let ident = format_ident!("{}", ident); // strip `r#` prefix, if present quote! { #diag.set_arg( stringify!(#ident), - #binding + #field_binding ); } } @@ -399,7 +399,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { clone_suggestion_code: bool, ) -> Result<TokenStream, DiagnosticDeriveError> { let span = attr.span().unwrap(); - let ident = &list.path.segments.last().unwrap().ident; + let mut ident = list.path.segments.last().unwrap().ident.clone(); + ident.set_span(info.ty.span()); let name = ident.to_string(); let name = name.as_str(); @@ -498,7 +499,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .variant .bindings() .iter() - .filter(|binding| !binding.ast().attrs.is_empty()) + .filter(|binding| !should_generate_set_arg(binding.ast())) .map(|binding| self.generate_field_attr_code(binding, kind_stats)) .collect(); @@ -580,7 +581,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .variant .bindings() .iter() - .filter(|binding| binding.ast().attrs.is_empty()) + .filter(|binding| should_generate_set_arg(binding.ast())) .map(|binding| self.generate_field_set_arg(binding)) .collect(); diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index b9b09c66230..e2434981f8d 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -207,6 +207,12 @@ impl<'ty> FieldInnerTy<'ty> { FieldInnerTy::Plain(..) => quote! { #inner }, } } + + pub fn span(&self) -> proc_macro2::Span { + match self { + FieldInnerTy::Option(ty) | FieldInnerTy::Vec(ty) | FieldInnerTy::Plain(ty) => ty.span(), + } + } } /// Field information passed to the builder. Deliberately omits attrs to discourage the @@ -851,7 +857,8 @@ impl quote::IdentFragment for SubdiagnosticKind { /// Returns `true` if `field` should generate a `set_arg` call rather than any other diagnostic /// call (like `span_label`). pub(super) fn should_generate_set_arg(field: &Field) -> bool { - field.attrs.is_empty() + // Perhaps this should be an exhaustive list... + field.attrs.iter().all(|attr| is_doc_comment(attr)) } pub(super) fn is_doc_comment(attr: &Attribute) -> bool { 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/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 39ef4276faf..72b208a7132 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -89,11 +89,25 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { // to try to eagerly statically link all dependencies. This is normally // done for end-product dylibs, not intermediate products. // - // Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may - // be code-size conscious, but without it, it makes sense to statically - // link a cdylib. - CrateType::Dylib | CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => Linkage::Static, - CrateType::Dylib | CrateType::Cdylib => Linkage::Dynamic, + // Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set, + // the caller may be code-size conscious, but without it, it makes sense + // to statically link a cdylib or staticlib. For staticlibs we use + // `-Z staticlib-prefer-dynamic` for now. This may be merged into + // `-C prefer-dynamic` in the future. + CrateType::Dylib | CrateType::Cdylib => { + if sess.opts.cg.prefer_dynamic { + Linkage::Dynamic + } else { + Linkage::Static + } + } + CrateType::Staticlib => { + if sess.opts.unstable_opts.staticlib_prefer_dynamic { + Linkage::Dynamic + } else { + Linkage::Static + } + } // If the global prefer_dynamic switch is turned off, or the final // executable will be statically linked, prefer static crate linkage. @@ -108,9 +122,6 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { // No linkage happens with rlibs, we just needed the metadata (which we // got long ago), so don't bother with anything. CrateType::Rlib => Linkage::NotLinked, - - // staticlibs must have all static dependencies. - CrateType::Staticlib => Linkage::Static, }; match preferred_linkage { @@ -123,9 +134,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { return v; } - // Staticlibs and static executables must have all static dependencies. + // Static executables must have all static dependencies. // If any are not found, generate some nice pretty errors. - if ty == CrateType::Staticlib + if (ty == CrateType::Staticlib && !sess.opts.unstable_opts.staticlib_allow_rdylib_deps) || (ty == CrateType::Executable && sess.crt_static(Some(ty)) && !sess.target.crt_static_allows_dylibs) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index c6af8d63289..6c4d121fd01 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -220,7 +220,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owned_slice::slice_owned; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::MetadataRef; use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg}; use rustc_fs_util::try_canonicalize; use rustc_session::config::{self, CrateType}; @@ -782,7 +781,7 @@ fn get_metadata_section<'p>( if !filename.exists() { return Err(MetadataError::NotPresent(filename)); } - let raw_bytes: MetadataRef = match flavor { + let raw_bytes = match flavor { CrateFlavor::Rlib => { loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)? } @@ -843,7 +842,7 @@ fn get_metadata_section<'p>( slice_owned(mmap, Deref::deref) } }; - let blob = MetadataBlob::new(raw_bytes); + let blob = MetadataBlob(raw_bytes); if blob.is_compatible() { Ok(blob) } else { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index a310cbb8029..699e1f49ed6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -7,6 +7,7 @@ use crate::rmeta::*; use rustc_ast as ast; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; @@ -50,7 +51,7 @@ mod cstore_impl; /// A `MetadataBlob` internally is just a reference counted pointer to /// the actual data, so cloning it is cheap. #[derive(Clone)] -pub(crate) struct MetadataBlob(Lrc<MetadataRef>); +pub(crate) struct MetadataBlob(pub(crate) OwnedSlice); impl std::ops::Deref for MetadataBlob { type Target = [u8]; @@ -660,10 +661,6 @@ impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T> implement_ty_decoder!(DecodeContext<'a, 'tcx>); impl MetadataBlob { - pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob { - MetadataBlob(Lrc::new(metadata_ref)) - } - pub(crate) fn is_compatible(&self) -> bool { self.blob().starts_with(METADATA_HEADER) } @@ -856,7 +853,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::EarlyBinder(&*output) } - fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef { + fn get_variant( + self, + kind: DefKind, + index: DefIndex, + parent_did: DefId, + ) -> (VariantIdx, ty::VariantDef) { let adt_kind = match kind { DefKind::Variant => ty::AdtKind::Enum, DefKind::Struct => ty::AdtKind::Struct, @@ -870,22 +872,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index))); - ty::VariantDef::new( - self.item_name(index), - variant_did, - ctor, - data.discr, - self.get_associated_item_or_field_def_ids(index) - .map(|did| ty::FieldDef { - did, - name: self.item_name(did.index), - vis: self.get_visibility(did.index), - }) - .collect(), - adt_kind, - parent_did, - false, - data.is_non_exhaustive, + ( + data.idx, + ty::VariantDef::new( + self.item_name(index), + variant_did, + ctor, + data.discr, + self.get_associated_item_or_field_def_ids(index) + .map(|did| ty::FieldDef { + did, + name: self.item_name(did.index), + vis: self.get_visibility(did.index), + }) + .collect(), + adt_kind, + parent_did, + false, + data.is_non_exhaustive, + ), ) } @@ -901,7 +906,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); - let variants = if let ty::AdtKind::Enum = adt_kind { + let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind { self.root .tables .module_children_non_reexports @@ -912,15 +917,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let kind = self.def_kind(index); match kind { DefKind::Ctor(..) => None, - _ => Some(self.get_variant(&kind, index, did)), + _ => Some(self.get_variant(kind, index, did)), } }) .collect() } else { - std::iter::once(self.get_variant(&kind, item_id, did)).collect() + std::iter::once(self.get_variant(kind, item_id, did)).collect() }; - tcx.mk_adt_def(did, adt_kind, variants, repr) + variants.sort_by_key(|(idx, _)| *idx); + + tcx.mk_adt_def( + did, + adt_kind, + variants.into_iter().map(|(_, variant)| variant).collect(), + repr, + ) } fn get_visibility(self, id: DefIndex) -> Visibility<DefId> { @@ -1457,28 +1469,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/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 05402a58701..4f280bb9d80 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -1,6 +1,5 @@ use crate::rmeta::DecodeContext; use crate::rmeta::EncodeContext; -use rustc_data_structures::owned_slice::slice_owned; use rustc_data_structures::owned_slice::OwnedSlice; use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap}; use rustc_middle::parameterized_over_tcx; @@ -47,7 +46,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> { let len = d.read_usize(); let pos = d.position(); - let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]); + let o = d.blob().clone().0.slice(|blob| &blob[pos..pos + len]); // Although we already have the data we need via the `OwnedSlice`, we still need // to advance the `DecodeContext`'s position so it's in a valid state after diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 82c66b9dfb9..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}; @@ -862,6 +862,11 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::Macro(_) | DefKind::Field | DefKind::Impl { .. } => true, + // Tools may want to be able to detect their tool lints on + // closures from upstream crates, too. This is used by + // https://github.com/model-checking/kani and is not a performance + // or maintenance issue for us. + DefKind::Closure => true, DefKind::TyParam | DefKind::ConstParam | DefKind::Ctor(..) @@ -874,7 +879,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::ImplTraitPlaceholder | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Closure | DefKind::Generator => false, } } @@ -1371,9 +1375,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Therefore, the loop over variants will encode its fields as the adt's children. } - for variant in adt_def.variants().iter() { + for (idx, variant) in adt_def.variants().iter_enumerated() { let data = VariantData { discr: variant.discr, + idx, ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; @@ -1511,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 { @@ -1637,9 +1645,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(ref opaque) => { self.encode_explicit_item_bounds(def_id); - self.tables - .is_type_alias_impl_trait - .set(def_id.index, matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias)); + self.tables.is_type_alias_impl_trait.set( + def_id.index, + matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }), + ); } hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { self.tables.impl_defaultness.set_some(def_id.index, *defaultness); @@ -2125,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 84f6b7f934d..987a484049f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -7,7 +7,6 @@ use table::TableBuilder; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::MetadataRef; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}; @@ -20,8 +19,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; @@ -31,6 +30,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnIndex, MacroKind}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span}; +use rustc_target::abi::VariantIdx; use rustc_target::spec::{PanicStrategy, TargetTriple}; use std::marker::PhantomData; @@ -394,7 +394,7 @@ define_tables! { mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>, mir_generator_witnesses: Table<DefIndex, LazyValue<mir::GeneratorLayout<'static>>>, promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>, - thir_abstract_const: Table<DefIndex, LazyValue<ty::Const<'static>>>, + thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>, impl_parent: Table<DefIndex, RawDefId>, impl_polarity: Table<DefIndex, ty::ImplPolarity>, constness: Table<DefIndex, hir::Constness>, @@ -430,6 +430,7 @@ define_tables! { #[derive(TyEncodable, TyDecodable)] struct VariantData { + idx: VariantIdx, discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. ctor: Option<(CtorKind, DefIndex)>, 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/messages.ftl b/compiler/rustc_middle/messages.ftl index c6bbf2ef0cd..64d511c261a 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -39,5 +39,7 @@ middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute +middle_requires_lang_item = requires `{$name}` lang_item + middle_const_not_used_in_type_alias = const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index dc4aa18640f..046186d274c 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,5 +1,5 @@ use rustc_macros::Diagnostic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::ty::Ty; @@ -74,6 +74,14 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { } #[derive(Diagnostic)] +#[diag(middle_requires_lang_item)] +pub(crate) struct RequiresLangItem { + #[primary_span] + pub span: Option<Span>, + pub name: Symbol, +} + +#[derive(Diagnostic)] #[diag(middle_const_not_used_in_type_alias)] pub(super) struct ConstNotUsedTraitAlias { pub ct: String, 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..22ee2a8c5e5 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; @@ -104,6 +99,11 @@ 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/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 343ea1f00f5..9a633e04ce7 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -18,12 +18,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the `DefId` for a given `LangItem`. /// If not found, fatally aborts compilation. pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId { - self.lang_items().require(lang_item).unwrap_or_else(|err| { - if let Some(span) = span { - self.sess.span_fatal(span, err.to_string()) - } else { - self.sess.fatal(err.to_string()) - } + self.lang_items().get(lang_item).unwrap_or_else(|| { + self.sess.emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() }); }) } 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/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e45284ca506..055d8e9a352 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,7 +1,8 @@ use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar}; use crate::mir::interpret::ConstValue; -use crate::ty::{layout, query::TyCtxtAt, tls, Ty, ValTree}; +use crate::query::TyCtxtAt; +use crate::ty::{layout, tls, Ty, ValTree}; use rustc_data_structures::sync::Lock; use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; @@ -15,15 +16,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 +124,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 +160,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 +179,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..f53dc8cb0ec 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,9 +1,10 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}; use crate::mir; +use crate::query::{TyCtxtAt, TyCtxtEnsure}; use crate::ty::subst::InternalSubsts; use crate::ty::visit::TypeVisitableExt; -use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt}; +use crate::ty::{self, TyCtxt}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_session::lint; @@ -61,7 +62,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 +111,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 858a3d266ea..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, } /////////////////////////////////////////////////////////////////////////// @@ -1524,6 +1528,19 @@ impl<V, T> ProjectionElem<V, T> { } } + /// Returns `true` if the target of this projection always refers to the same memory region + /// whatever the state of the program. + pub fn is_stable_offset(&self) -> bool { + match self { + Self::Deref | Self::Index(_) => false, + Self::Field(_, _) + | Self::OpaqueCast(_) + | Self::ConstantIndex { .. } + | Self::Subslice { .. } + | Self::Downcast(_, _) => true, + } + } + /// Returns `true` if this is a `Downcast` projection with the given `VariantIdx`. pub fn is_downcast_to(&self, v: VariantIdx) -> bool { matches!(*self, Self::Downcast(_, x) if x == v) @@ -1537,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, @@ -1626,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) } } @@ -1708,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<'_> { @@ -2300,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 @@ -2312,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())), } } } @@ -2728,8 +2756,6 @@ pub struct UserTypeProjection { pub projs: Vec<ProjectionKind>, } -impl Copy for ProjectionKind {} - impl UserTypeProjection { pub(crate) fn index(mut self) -> Self { self.projs.push(ProjectionElem::Index(())); 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 6718605ed0b..596dd80bf48 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -64,7 +64,7 @@ use crate::mir::*; use crate::ty::subst::SubstsRef; -use crate::ty::{CanonicalUserTypeAnnotation, Ty}; +use crate::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc_span::Span; macro_rules! make_mir_visitor { @@ -782,12 +782,12 @@ macro_rules! make_mir_visitor { fn super_ascribe_user_ty(&mut self, place: & $($mutability)? Place<'tcx>, - _variance: $(& $mutability)? ty::Variance, + variance: $(& $mutability)? ty::Variance, user_ty: & $($mutability)? UserTypeProjection, location: Location) { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::AscribeUserTy), + PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)), location ); self.visit_user_type_projection(user_ty); @@ -842,6 +842,7 @@ macro_rules! make_mir_visitor { source_info, value, argument_index: _, + references: _, } = var_debug_info; self.visit_source_info(source_info); @@ -880,12 +881,11 @@ macro_rules! make_mir_visitor { ) { let Constant { span, - user_ty, + user_ty: _, // no visit method for this literal, } = constant; self.visit_span($(& $mutability)? *span); - drop(user_ty); // no visit method for this match literal { ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location), ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), @@ -1320,7 +1320,7 @@ pub enum NonUseContext { /// Ending a storage live range. StorageDead, /// User type annotation assertions for NLL. - AscribeUserTy, + AscribeUserTy(ty::Variance), /// The data of a user variable, for debug info. VarDebugInfo, } diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 7d9aea02289..b45f7caaabe 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -82,9 +82,10 @@ impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuarantee [u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()]; } -impl EraseType for Result<Option<ty::Const<'_>>, rustc_errors::ErrorGuaranteed> { - type Result = - [u8; size_of::<Result<Option<ty::Const<'static>>, rustc_errors::ErrorGuaranteed>>()]; +impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> { + type Result = [u8; size_of::< + Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>, + >()]; } impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> { @@ -171,6 +172,10 @@ impl EraseType for ty::Binder<'_, ty::FnSig<'_>> { type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()]; } +impl EraseType for ty::Binder<'_, &'_ ty::List<Ty<'_>>> { + type Result = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()]; +} + impl<T0, T1> EraseType for (&'_ T0, &'_ T1) { type Result = [u8; size_of::<(&'static (), &'static ())>()]; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b425c7600ac..21c69662b9e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -4,13 +4,94 @@ //! ["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::query::plumbing::{query_ensure, query_get_at, DynamicQuery}; +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::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; -pub mod on_disk_cache; pub use keys::{AsLocalKey, Key, LocalCrate}; +pub mod on_disk_cache; +#[macro_use] +pub mod plumbing; +pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue}; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method @@ -236,6 +317,15 @@ rustc_queries! { cache_on_disk_if { key.is_local() } } + query opaque_types_defined_by( + key: LocalDefId + ) -> &'tcx [LocalDefId] { + desc { + |tcx| "computing the opaque types defined by `{}`", + tcx.def_path_str(key.to_def_id()) + } + } + /// Returns the list of bounds that can be used for /// `SelectionCandidate::ProjectionCandidate(_)` and /// `ProjectionTyCandidate::TraitDef`. @@ -402,7 +492,7 @@ rustc_queries! { /// Try to build an abstract representation of the given constant. query thir_abstract_const( key: DefId - ) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> { + ) -> Result<Option<ty::EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed> { desc { |tcx| "building an abstract representation for `{}`", tcx.def_path_str(key), } @@ -437,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() } @@ -1016,7 +1106,7 @@ rustc_queries! { desc { "converting literal to mir constant" } } - query check_match(key: LocalDefId) { + query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> { desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -1821,6 +1911,16 @@ rustc_queries! { desc { "normalizing `{}`", goal.value.value } } + /// Do not call this query directly: invoke `normalize` instead. + query normalize_inherent_projection_ty( + goal: CanonicalProjectionGoal<'tcx> + ) -> Result< + &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>, + NoSolution, + > { + desc { "normalizing `{}`", goal.value.value } + } + /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. query try_normalize_generic_arg_after_erasing_regions( goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> @@ -2083,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/query.rs b/compiler/rustc_middle/src/query/plumbing.rs index 07d47cae5ee..647f4826876 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/query/plumbing.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/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 8366567c2c3..2f0b07d4c71 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -281,9 +281,6 @@ pub enum ObligationCauseCode<'tcx> { /// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`. ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>), - /// Obligation incurred due to an object cast. - ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>), - /// Obligation incurred due to a coercion. Coercion { source: Ty<'tcx>, @@ -580,11 +577,7 @@ pub enum SelectionError<'tcx> { /// After a closure impl has selected, its "outputs" were evaluated /// (which for closures includes the "input" type params) and they /// didn't resolve. See `confirm_poly_trait_refs` for more. - OutputTypeParameterMismatch( - ty::PolyTraitRef<'tcx>, - ty::PolyTraitRef<'tcx>, - ty::error::TypeError<'tcx>, - ), + OutputTypeParameterMismatch(Box<SelectionOutputTypeParameterMismatch<'tcx>>), /// The trait pointed by `DefId` is not object safe. TraitNotObjectSafe(DefId), /// A given constant couldn't be evaluated. @@ -596,6 +589,13 @@ pub enum SelectionError<'tcx> { ErrorReporting, } +#[derive(Clone, Debug, TypeVisitable, Lift)] +pub struct SelectionOutputTypeParameterMismatch<'tcx> { + pub found_trait_ref: ty::PolyTraitRef<'tcx>, + pub expected_trait_ref: ty::PolyTraitRef<'tcx>, + pub terr: ty::error::TypeError<'tcx>, +} + /// When performing resolution, it is typically the case that there /// can be one of three outcomes: /// 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 bfb740ab356..a39631da936 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -4,7 +4,6 @@ use crate::ty::{ TypeVisitableExt, }; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::DefId; #[derive(Hash, Debug, Clone, Copy, Ord, PartialOrd, PartialEq, Eq)] #[derive(TyDecodable, TyEncodable, HashStable, TypeVisitable, TypeFoldable)] @@ -35,12 +34,6 @@ TrivialTypeTraversalAndLiftImpls! { pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>; impl<'tcx> TyCtxt<'tcx> { - /// Returns a const without substs applied - pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> { - let ac = self.thir_abstract_const(uv); - Ok(ac?.map(|ac| EarlyBinder(ac))) - } - pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T { struct Expander<'tcx> { tcx: TyCtxt<'tcx>, @@ -59,8 +52,8 @@ 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.bound_abstract_const(uv.def) { - Err(e) => self.tcx.const_error_with_guaranteed(c.ty(), e), + ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) { + 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..1a4bd14815f 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -6,7 +6,6 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_macros::HashStable; -use std::fmt; mod int; mod kind; @@ -21,15 +20,6 @@ pub use valtree::*; #[rustc_pass_by_value] pub struct Const<'tcx>(pub(super) Interned<'tcx, ConstData<'tcx>>); -impl<'tcx> fmt::Debug for Const<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // This reflects what `Const` looked liked before `Interned` was - // introduced. We print it like this to avoid having to update expected - // output in a lot of tests. - write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind()) - } -} - /// Typed constant value. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)] pub struct ConstData<'tcx> { @@ -142,9 +132,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 +216,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..1dd4f8a2437 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -42,7 +42,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { } /// Represents a constant in Rust. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] #[derive(derive_more::From)] pub enum ConstKind<'tcx> { @@ -128,7 +128,7 @@ impl<'tcx> ConstKind<'tcx> { } /// An inference variable for a const, for use in const generics. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] pub enum InferConst<'tcx> { /// Infer the value of the const. Var(ty::ConstVid<'tcx>), @@ -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 c2550572879..e84d0100a5c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,15 +14,14 @@ 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::plumbing::QuerySystem; use crate::query::LocalCrate; +use crate::query::Providers; +use crate::query::{IntoQueryParam, TyCtxtAt}; 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, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, @@ -81,8 +80,6 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; -use super::query::IntoQueryParam; - const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); #[allow(rustc::usage_of_ty_tykind)] @@ -496,7 +493,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, @@ -513,7 +510,7 @@ pub struct GlobalCtxt<'tcx> { untracked: Untracked, - pub query_system: query::QuerySystem<'tcx>, + pub query_system: QuerySystem<'tcx>, pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. @@ -648,14 +645,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 +673,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 +731,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, @@ -1848,7 +1840,17 @@ impl<'tcx> TyCtxt<'tcx> { let substs = substs.into_iter().map(Into::into); #[cfg(debug_assertions)] { - let n = self.generics_of(_def_id).count(); + let generics = self.generics_of(_def_id); + + let n = if let DefKind::AssocTy = self.def_kind(_def_id) + && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(_def_id)) + { + // If this is an inherent projection. + + generics.params.len() + 1 + } else { + generics.count() + }; assert_eq!( (n, Some(n)), substs.size_hint(), @@ -2009,7 +2011,7 @@ impl<'tcx> TyCtxt<'tcx> { debug_assert_matches!( (kind, self.def_kind(alias_ty.def_id)), (ty::Opaque, DefKind::OpaqueTy) - | (ty::Projection, DefKind::AssocTy) + | (ty::Projection | ty::Inherent, DefKind::AssocTy) | (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder) ); self.mk_ty_from_kind(Alias(kind, alias_ty)) @@ -2451,7 +2453,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..5c1c419811e 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -1,7 +1,7 @@ use super::{GlobalCtxt, TyCtxt}; use crate::dep_graph::TaskDepsRef; -use crate::ty::query; +use crate::query::plumbing::QueryJobId; use rustc_data_structures::sync::{self, Lock}; use rustc_errors::Diagnostic; #[cfg(not(parallel_compiler))] @@ -22,7 +22,7 @@ pub struct ImplicitCtxt<'a, 'tcx> { /// The current query job, if any. This is updated by `JobOwner::start` in /// `ty::query::plumbing` when executing a query. - pub query: Option<query::QueryJobId>, + pub query: Option<QueryJobId>, /// Where to store diagnostics for the current query job, if any. /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query. @@ -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/error.rs b/compiler/rustc_middle/src/ty/error.rs index 1be61e16dbe..49ab9b79e96 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -265,7 +265,7 @@ impl<'tcx> Ty<'tcx> { ty::Infer(ty::FreshTy(_)) => "fresh type".into(), ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), - ty::Alias(ty::Projection, _) => "associated type".into(), + ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(), ty::Param(p) => format!("type parameter `{p}`").into(), ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() }, ty::Error(_) => "type error".into(), @@ -312,7 +312,7 @@ impl<'tcx> Ty<'tcx> { ty::Tuple(..) => "tuple".into(), ty::Placeholder(..) => "higher-ranked type".into(), ty::Bound(..) => "bound type variable".into(), - ty::Alias(ty::Projection, _) => "associated type".into(), + ty::Alias(ty::Projection | ty::Inherent, _) => "associated type".into(), ty::Param(_) => "type parameter".into(), ty::Alias(ty::Opaque, ..) => "opaque type".into(), } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 68002bfcfbd..d64875a9f00 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -176,14 +176,14 @@ impl FlagComputation { self.add_substs(substs); } - &ty::Alias(ty::Projection, data) => { - self.add_flags(TypeFlags::HAS_TY_PROJECTION); - self.add_alias_ty(data); - } + &ty::Alias(kind, data) => { + self.add_flags(match kind { + ty::Projection => TypeFlags::HAS_TY_PROJECTION, + ty::Inherent => TypeFlags::HAS_TY_INHERENT, + ty::Opaque => TypeFlags::HAS_TY_OPAQUE, + }); - &ty::Alias(ty::Opaque, ty::AliasTy { substs, .. }) => { - self.add_flags(TypeFlags::HAS_TY_OPAQUE); - self.add_substs(substs); + self.add_alias_ty(data); } &ty::Dynamic(obj, r, _) => { 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 92a040068dd..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 @@ -113,6 +113,12 @@ impl<'tcx> Ty<'tcx> { } Never => InhabitedPredicate::False, Param(_) | Alias(ty::Projection, _) => InhabitedPredicate::GenericType(self), + // FIXME(inherent_associated_types): Most likely we can just map to `GenericType` like above. + // However it's unclear if the substs passed to `InhabitedPredicate::subst` are of the correct + // format, i.e. don't contain parent substs. If you hit this case, please verify this beforehand. + Alias(ty::Inherent, _) => { + bug!("unimplemented: inhabitedness checking for inherent projections") + } Tuple(tys) if tys.is_empty() => InhabitedPredicate::True, // use a query for more complex cases Adt(..) | Array(..) | Tuple(_) => tcx.inhabited_predicate_type(self), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f2a2e67cf82..ba91e5aea5a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,5 +1,6 @@ use crate::fluent_generated as fluent; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; @@ -324,7 +325,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let non_zero = !ty.is_unsafe_ptr(); let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.kind() { - ty::Param(_) | ty::Alias(ty::Projection, _) => { + ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => { debug_assert!(tail.has_non_region_param()); Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) } @@ -543,20 +544,20 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> { } } -impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasDataLayout for TyCtxtAt<'tcx> { #[inline] fn data_layout(&self) -> &TargetDataLayout { &self.data_layout } } -impl<'tcx> HasTargetSpec for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTargetSpec for TyCtxtAt<'tcx> { fn target_spec(&self) -> &Target { &self.sess.target } } -impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { **self @@ -683,7 +684,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { } } -impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { +impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> { type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>; #[inline] 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 88b084bbccb..be0d1e61a46 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,7 +122,6 @@ pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; pub mod print; -pub mod query; pub mod relate; pub mod subst; pub mod trait_def; @@ -1004,7 +1004,7 @@ impl<'tcx> Term<'tcx> { match self.unpack() { TermKind::Ty(ty) => match ty.kind() { ty::Alias(kind, alias_ty) => match kind { - AliasKind::Projection => Some(*alias_ty), + AliasKind::Projection | AliasKind::Inherent => Some(*alias_ty), AliasKind::Opaque => None, }, _ => None, @@ -1070,6 +1070,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: /// @@ -2476,6 +2494,18 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Returns the `DefId` of the item within which the `impl Trait` is declared. + /// For type-alias-impl-trait this is the `type` alias. + /// For impl-trait-in-assoc-type this is the assoc type. + /// For return-position-impl-trait this is the function. + pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId { + // Find the surrounding item (type alias or assoc type) + while let DefKind::OpaqueTy = self.def_kind(def_id) { + def_id = self.local_parent(def_id); + } + def_id + } + pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { if self.def_kind(def_id) != DefKind::AssocFn { return false; @@ -2520,7 +2550,7 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId> hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => { Some(parent) } - hir::OpaqueTyOrigin::TyAlias => None, + hir::OpaqueTyOrigin::TyAlias { .. } => None, }; } } @@ -2578,7 +2608,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); @@ -2587,7 +2617,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/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 9332b0430ff..a0c8d299f48 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -32,7 +32,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// This should only be used outside of type inference. For example, /// it assumes that normalization will succeed. - #[tracing::instrument(level = "debug", skip(self, param_env))] + #[tracing::instrument(level = "debug", skip(self, param_env), ret)] pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T where T: TypeFoldable<TyCtxt<'tcx>>, 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 b7e780b94ef..4491d78648f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,5 +1,6 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; -use crate::ty::query::IntoQueryParam; +use crate::query::IntoQueryParam; +use crate::query::Providers; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -702,7 +703,7 @@ pub trait PrettyPrinter<'tcx>: ty::Error(_) => p!("[type error]"), ty::Param(ref param_ty) => p!(print(param_ty)), ty::Bound(debruijn, bound_ty) => match bound_ty.kind { - ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?, + ty::BoundTyKind::Anon => debug_bound_var(&mut self, debruijn, bound_ty.var)?, ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() { true if debruijn == ty::INNERMOST => p!(write("^{}", s)), true => p!(write("^{}_{}", debruijn.index(), s)), @@ -729,7 +730,7 @@ pub trait PrettyPrinter<'tcx>: ty::Foreign(def_id) => { p!(print_def_path(def_id, &[])); } - ty::Alias(ty::Projection, ref data) => { + ty::Alias(ty::Projection | ty::Inherent, ref data) => { if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get())) && self.tcx().is_impl_trait_in_trait(data.def_id) { @@ -740,7 +741,7 @@ pub trait PrettyPrinter<'tcx>: } ty::Placeholder(placeholder) => match placeholder.bound.kind { ty::BoundTyKind::Anon => { - self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound.var)?; } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, @@ -1163,30 +1164,6 @@ pub trait PrettyPrinter<'tcx>: traits.entry(trait_ref).or_default().extend(proj_ty); } - fn pretty_print_bound_var( - &mut self, - debruijn: ty::DebruijnIndex, - var: ty::BoundVar, - ) -> Result<(), Self::Error> { - if debruijn == ty::INNERMOST { - write!(self, "^{}", var.index()) - } else { - write!(self, "^{}_{}", debruijn.index(), var.index()) - } - } - - fn pretty_print_placeholder_var( - &mut self, - ui: ty::UniverseIndex, - var: ty::BoundVar, - ) -> Result<(), Self::Error> { - if ui == ty::UniverseIndex::ROOT { - write!(self, "!{}", var.index()) - } else { - write!(self, "!{}_{}", ui.index(), var.index()) - } - } - fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> { None } @@ -1320,7 +1297,7 @@ pub trait PrettyPrinter<'tcx>: define_scoped_cx!(self); if self.should_print_verbose() { - p!(write("Const({:?}: {:?})", ct.kind(), ct.ty())); + p!(write("{:?}", ct)); return Ok(self); } @@ -1379,9 +1356,11 @@ pub trait PrettyPrinter<'tcx>: } ty::ConstKind::Bound(debruijn, bound_var) => { - self.pretty_print_bound_var(debruijn, bound_var)? + debug_bound_var(&mut self, debruijn, bound_var)? } - ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), + ty::ConstKind::Placeholder(placeholder) => { + debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound)?; + }, // FIXME(generic_const_exprs): // write out some legible representation of an abstract const? ty::ConstKind::Expr(_) => p!("[const expr]"), @@ -3054,8 +3033,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)] @@ -3066,3 +3045,27 @@ pub struct OpaqueFnEntry<'tcx> { fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>, return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>, } + +pub fn debug_bound_var<T: std::fmt::Write>( + fmt: &mut T, + debruijn: ty::DebruijnIndex, + var: ty::BoundVar, +) -> Result<(), std::fmt::Error> { + if debruijn == ty::INNERMOST { + write!(fmt, "^{}", var.index()) + } else { + write!(fmt, "^{}_{}", debruijn.index(), var.index()) + } +} + +pub fn debug_placeholder_var<T: std::fmt::Write>( + fmt: &mut T, + universe: ty::UniverseIndex, + bound: ty::BoundVar, +) -> Result<(), std::fmt::Error> { + if universe == ty::UniverseIndex::ROOT { + write!(fmt, "!{}", bound.index()) + } else { + write!(fmt, "!{}_{}", universe.index(), bound.index()) + } +} diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 7f28ed6c263..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)), @@ -550,6 +550,11 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( Ok(tcx.mk_projection(projection_ty.def_id, projection_ty.substs)) } + (&ty::Alias(ty::Inherent, a_data), &ty::Alias(ty::Inherent, b_data)) => { + let alias_ty = relation.relate(a_data, b_data)?; + Ok(tcx.mk_alias(ty::Inherent, tcx.mk_alias_ty(alias_ty.def_id, alias_ty.substs))) + } + ( &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: a_substs, .. }), &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: b_substs, .. }), @@ -570,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 @@ -597,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 @@ -605,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..16cb6c91046 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -192,6 +192,44 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { } } +impl<'tcx> fmt::Debug for ty::InferConst<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + InferConst::Var(var) => write!(f, "{var:?}"), + InferConst::Fresh(var) => write!(f, "Fresh({var:?})"), + } + } +} + +impl<'tcx> fmt::Debug for ty::Const<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // This reflects what `Const` looked liked before `Interned` was + // introduced. We print it like this to avoid having to update expected + // output in a lot of tests. + write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind()) + } +} + +impl<'tcx> fmt::Debug for ty::ConstKind<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use ty::ConstKind::*; + match self { + Param(param) => write!(f, "{param:?}"), + Infer(var) => write!(f, "{var:?}"), + Bound(debruijn, var) => ty::print::debug_bound_var(f, *debruijn, *var), + Placeholder(placeholder) => { + ty::print::debug_placeholder_var(f, placeholder.universe, placeholder.bound) + } + Unevaluated(uv) => { + f.debug_tuple("Unevaluated").field(&uv.substs).field(&uv.def).finish() + } + Value(valtree) => write!(f, "{valtree:?}"), + Error(_) => write!(f, "[const error]"), + Expr(expr) => write!(f, "{expr:?}"), + } + } +} + /////////////////////////////////////////////////////////////////////////// // Atomic structs // @@ -204,6 +242,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 646384eebc8..e6d51c4ec97 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1190,9 +1190,9 @@ where /// Represents the projection of an associated type. /// -/// For a projection, this would be `<Ty as Trait<...>>::N`. -/// -/// For an opaque type, there is no explicit syntax. +/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. +/// * For an inherent projection, this would be `Ty::N<...>`. +/// * For an opaque type, there is no explicit syntax. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct AliasTy<'tcx> { @@ -1201,12 +1201,16 @@ pub struct AliasTy<'tcx> { /// For a projection, these are the substitutions for the trait and the /// GAT substitutions, if there are any. /// + /// For an inherent projection, they consist of the self type and the GAT substitutions, + /// if there are any. + /// /// For RPIT the substitutions are for the generics of the function, /// while for TAIT it is used for the generic parameters of the alias. pub substs: SubstsRef<'tcx>, - /// The `DefId` of the `TraitItem` for the associated type `N` if this is a projection, - /// or the `OpaqueType` item if this is an opaque. + /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether + /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if + /// this is an opaque. /// /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the /// underlying type if the type is an opaque. @@ -1224,6 +1228,7 @@ pub struct AliasTy<'tcx> { impl<'tcx> AliasTy<'tcx> { pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { match tcx.def_kind(self.def_id) { + DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent, DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection, DefKind::OpaqueTy => ty::Opaque, kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), @@ -1237,6 +1242,17 @@ impl<'tcx> AliasTy<'tcx> { /// The following methods work only with associated type projections. impl<'tcx> AliasTy<'tcx> { + pub fn self_ty(self) -> Ty<'tcx> { + self.substs.type_at(0) + } + + pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1))) + } +} + +/// The following methods work only with trait associated type projections. +impl<'tcx> AliasTy<'tcx> { pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { match tcx.def_kind(self.def_id) { DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), @@ -1249,7 +1265,7 @@ impl<'tcx> AliasTy<'tcx> { /// Extracts the underlying trait reference and own substs from this projection. /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, - /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs + /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs pub fn trait_ref_and_own_substs( self, tcx: TyCtxt<'tcx>, @@ -1274,13 +1290,28 @@ impl<'tcx> AliasTy<'tcx> { let def_id = self.trait_def_id(tcx); ty::TraitRef::new(tcx, def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id))) } +} - pub fn self_ty(self) -> Ty<'tcx> { - self.substs.type_at(0) - } +/// The following methods work only with inherent associated type projections. +impl<'tcx> AliasTy<'tcx> { + /// Transform the substitutions to have the given `impl` substs as the base and the GAT substs on top of that. + /// + /// Does the following transformation: + /// + /// ```text + /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] + /// + /// I_i impl subst + /// P_j GAT subst + /// ``` + pub fn rebase_substs_onto_impl( + self, + impl_substs: ty::SubstsRef<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> ty::SubstsRef<'tcx> { + debug_assert_eq!(self.kind(tcx), ty::Inherent); - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1))) + tcx.mk_substs_from_iter(impl_substs.into_iter().chain(self.substs.into_iter().skip(1))) } } @@ -1677,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); @@ -2335,13 +2368,11 @@ impl<'tcx> Ty<'tcx> { ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(), - ty::Alias(..) | ty::Param(_) => false, + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false, ty::Infer(ty::TyVar(_)) => false, - ty::Bound(..) - | ty::Placeholder(..) - | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + ty::Bound(..) | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e5b2d342452..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, @@ -34,9 +35,14 @@ pub struct Discr<'tcx> { /// Used as an input to [`TyCtxt::uses_unique_generic_params`]. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum IgnoreRegions { - Yes, +pub enum CheckRegions { No, + /// Only permit early bound regions. This is useful for Adts which + /// can never have late bound regions. + OnlyEarlyBound, + /// Permit both late bound and early bound regions. Use this for functions, + /// which frequently have late bound regions. + Bound, } #[derive(Copy, Clone, Debug)] @@ -468,21 +474,28 @@ impl<'tcx> TyCtxt<'tcx> { pub fn uses_unique_generic_params( self, substs: SubstsRef<'tcx>, - ignore_regions: IgnoreRegions, + ignore_regions: CheckRegions, ) -> Result<(), NotUniqueParam<'tcx>> { let mut seen = GrowableBitSet::default(); + let mut seen_late = FxHashSet::default(); for arg in substs { match arg.unpack() { - GenericArgKind::Lifetime(lt) => { - if ignore_regions == IgnoreRegions::No { - let ty::ReEarlyBound(p) = lt.kind() else { - return Err(NotUniqueParam::NotParam(lt.into())) - }; + GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { + (CheckRegions::Bound, ty::ReLateBound(di, reg)) => { + if !seen_late.insert((di, reg)) { + return Err(NotUniqueParam::DuplicateParam(lt.into())); + } + } + (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => { if !seen.insert(p.index) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - } + (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => { + return Err(NotUniqueParam::NotParam(lt.into())); + } + (CheckRegions::No, _) => {} + }, GenericArgKind::Type(t) => match t.kind() { ty::Param(p) => { if !seen.insert(p.index) { @@ -655,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)) } @@ -1253,7 +1266,7 @@ pub enum ExplicitSelf<'tcx> { impl<'tcx> ExplicitSelf<'tcx> { /// Categorizes an explicit self declaration like `self: SomeType` - /// into either `self`, `&self`, `&mut self`, `Box<self>`, or + /// into either `self`, `&self`, `&mut self`, `Box<Self>`, or /// `Other`. /// This is mainly used to require the arbitrary_self_types feature /// in the case of `Other`, to improve error messages in the common cases, @@ -1472,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/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 5eaa58d69ed..520bb55e031 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -49,6 +49,9 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> { fn has_projections(&self) -> bool { self.has_type_flags(TypeFlags::HAS_PROJECTION) } + fn has_inherent_projections(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INHERENT) + } fn has_opaque_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) } 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/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index c385b00692f..0105a265ffb 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -481,9 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { })))) } - ExprKind::OffsetOf { container, fields } => { - block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container)) - } + ExprKind::OffsetOf { container, fields } => block.and(Rvalue::NullaryOp( + NullOp::OffsetOf(fields), + this.tcx.erase_regions(container), + )), ExprKind::Literal { .. } | ExprKind::NamedConst { .. } 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 3f006765a71..4e3e98b56e7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -42,7 +42,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // Ensure unsafeck and abstract const building is ran before we steal the THIR. tcx.ensure_with_value().thir_check_unsafety(def); tcx.ensure_with_value().thir_abstract_const(def); - tcx.ensure_with_value().check_match(def); + if let Err(e) = tcx.check_match(def) { + return construct_error(tcx, def, e); + } let body = match tcx.thir_body(def) { Err(error_reported) => construct_error(tcx, def, error_reported), @@ -796,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, @@ -826,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/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 8cb3b00c9ad..ca25f83e643 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -26,8 +26,8 @@ use rustc_session::Session; use rustc_span::hygiene::DesugaringKind; use rustc_span::Span; -pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let Ok((thir, expr)) = tcx.thir_body(def_id) else { return }; +pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { + let (thir, expr) = tcx.thir_body(def_id)?; let thir = thir.borrow(); let pattern_arena = TypedArena::default(); let mut visitor = MatchVisitor { @@ -37,13 +37,16 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) { lint_level: tcx.hir().local_def_id_to_hir_id(def_id), let_source: LetSource::None, pattern_arena: &pattern_arena, + error: Ok(()), }; visitor.visit_expr(&thir[expr]); + for param in thir.params.iter() { if let Some(box ref pattern) = param.pat { visitor.check_irrefutable(pattern, "function argument", None); } } + visitor.error } fn create_e0004( @@ -77,6 +80,7 @@ struct MatchVisitor<'a, 'p, 'tcx> { lint_level: HirId, let_source: LetSource, pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>, + error: Result<(), ErrorGuaranteed>, } impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> { @@ -276,9 +280,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let [pat_field] = &subpatterns[..] else { bug!() }; self.check_irrefutable(&pat_field.pattern, "`for` loop binding", None); } else { - non_exhaustive_match( + self.error = Err(non_exhaustive_match( &cx, self.thir, scrut_ty, scrut.span, witnesses, arms, expr_span, - ); + )); } } } @@ -406,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { } #[instrument(level = "trace", skip(self))] - fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) { + fn check_irrefutable(&mut self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) { let mut cx = self.new_cx(self.lint_level, false); let pattern = self.lower_pattern(&mut cx, pat); @@ -475,7 +479,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { AdtDefinedHere { adt_def_span, ty, variants } }; - self.tcx.sess.emit_err(PatternNotCovered { + self.error = Err(self.tcx.sess.emit_err(PatternNotCovered { span: pat.span, origin, uncovered: Uncovered::new(pat.span, &cx, witnesses), @@ -486,7 +490,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let_suggestion, misc_suggestion, adt_defined_here, - }); + })); } } @@ -628,7 +632,7 @@ fn non_exhaustive_match<'p, 'tcx>( witnesses: Vec<DeconstructedPat<'p, 'tcx>>, arms: &[ArmId], expr_span: Span, -) { +) -> ErrorGuaranteed { let is_empty_match = arms.is_empty(); let non_empty_enum = match scrut_ty.kind() { ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(), @@ -640,13 +644,12 @@ fn non_exhaustive_match<'p, 'tcx>( let pattern; let patterns_len; if is_empty_match && !non_empty_enum { - cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty { + return cx.tcx.sess.emit_err(NonExhaustivePatternsTypeNotEmpty { cx, expr_span, span: sp, ty: scrut_ty, }); - return; } else { // FIXME: migration of this diagnostic will require list support let joined_patterns = joined_uncovered_patterns(cx, &witnesses); @@ -797,7 +800,7 @@ fn non_exhaustive_match<'p, 'tcx>( } else { err.help(msg); } - err.emit(); + err.emit() } pub(crate) fn joined_uncovered_patterns<'p, 'tcx>( 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_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 2e68c794356..18895072c3b 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -276,6 +276,7 @@ where assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); let field_ty = tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); + (tcx.mk_place_field(base_place, field, field_ty), subpath) }) .collect() diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index af44a4329bf..3952f44ad48 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -75,12 +75,12 @@ pub trait MeetSemiLattice: Eq { /// A set that has a "bottom" element, which is less than or equal to any other element. pub trait HasBottom { - fn bottom() -> Self; + const BOTTOM: Self; } /// A set that has a "top" element, which is greater than or equal to any other element. pub trait HasTop { - fn top() -> Self; + const TOP: Self; } /// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom: @@ -113,15 +113,11 @@ impl MeetSemiLattice for bool { } impl HasBottom for bool { - fn bottom() -> Self { - false - } + const BOTTOM: Self = false; } impl HasTop for bool { - fn top() -> Self { - true - } + const TOP: Self = true; } /// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation @@ -274,13 +270,9 @@ impl<T: Clone + Eq> MeetSemiLattice for FlatSet<T> { } impl<T> HasBottom for FlatSet<T> { - fn bottom() -> Self { - Self::Bottom - } + const BOTTOM: Self = Self::Bottom; } impl<T> HasTop for FlatSet<T> { - fn top() -> Self { - Self::Top - } + const TOP: Self = Self::Top; } diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index 2a0aff55083..171db6965ac 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -26,7 +26,7 @@ pub use self::borrowed_locals::borrowed_locals; pub use self::borrowed_locals::MaybeBorrowedLocals; pub use self::liveness::MaybeLiveLocals; pub use self::liveness::MaybeTransitiveLiveLocals; -pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive}; +pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive}; /// `MaybeInitializedPlaces` tracks all places that might be /// initialized upon reaching a particular point in the control flow diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 4a5d9d52010..463ce083a64 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -74,6 +74,73 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { } } +#[derive(Clone)] +pub struct MaybeStorageDead { + always_live_locals: BitSet<Local>, +} + +impl MaybeStorageDead { + pub fn new(always_live_locals: BitSet<Local>) -> Self { + MaybeStorageDead { always_live_locals } + } +} + +impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead { + type Domain = BitSet<Local>; + + const NAME: &'static str = "maybe_storage_dead"; + + fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain { + // bottom = live + BitSet::new_empty(body.local_decls.len()) + } + + fn initialize_start_block(&self, body: &mir::Body<'tcx>, on_entry: &mut Self::Domain) { + assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size()); + // Do not iterate on return place and args, as they are trivially always live. + for local in body.vars_and_temps_iter() { + if !self.always_live_locals.contains(local) { + on_entry.insert(local); + } + } + } +} + +impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead { + type Idx = Local; + + fn statement_effect( + &self, + trans: &mut impl GenKill<Self::Idx>, + stmt: &mir::Statement<'tcx>, + _: Location, + ) { + match stmt.kind { + StatementKind::StorageLive(l) => trans.kill(l), + StatementKind::StorageDead(l) => trans.gen(l), + _ => (), + } + } + + fn terminator_effect( + &self, + _trans: &mut impl GenKill<Self::Idx>, + _: &mir::Terminator<'tcx>, + _: Location, + ) { + // Terminators have no effect + } + + fn call_return_effect( + &self, + _trans: &mut impl GenKill<Self::Idx>, + _block: BasicBlock, + _return_places: CallReturnPlaces<'_, 'tcx>, + ) { + // Nothing to do when a call returns successfully + } +} + type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>; /// Dataflow analysis that determines whether each local requires storage at a diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index fdff1ec788d..b74d06e5ae8 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -32,9 +32,12 @@ //! Because of that, we can assume that the only way to change the value behind a tracked place is //! by direct assignment. +use std::collections::VecDeque; use std::fmt::{Debug, Formatter}; +use std::ops::Range; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; @@ -65,8 +68,8 @@ pub trait ValueAnalysis<'tcx> { StatementKind::Assign(box (place, rvalue)) => { self.handle_assign(*place, rvalue, state); } - StatementKind::SetDiscriminant { box ref place, .. } => { - state.flood_discr(place.as_ref(), self.map()); + StatementKind::SetDiscriminant { box place, variant_index } => { + self.handle_set_discriminant(*place, *variant_index, state); } StatementKind::Intrinsic(box intrinsic) => { self.handle_intrinsic(intrinsic, state); @@ -74,11 +77,11 @@ pub trait ValueAnalysis<'tcx> { StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { // StorageLive leaves the local in an uninitialized state. // StorageDead makes it UB to access the local afterwards. - state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::bottom()); + state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::BOTTOM); } StatementKind::Deinit(box place) => { // Deinit makes the place uninitialized. - state.flood_with(place.as_ref(), self.map(), Self::Value::bottom()); + state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM); } StatementKind::Retag(..) => { // We don't track references. @@ -92,6 +95,24 @@ pub trait ValueAnalysis<'tcx> { } } + fn handle_set_discriminant( + &self, + place: Place<'tcx>, + variant_index: VariantIdx, + state: &mut State<Self::Value>, + ) { + self.super_set_discriminant(place, variant_index, state) + } + + fn super_set_discriminant( + &self, + place: Place<'tcx>, + _variant_index: VariantIdx, + state: &mut State<Self::Value>, + ) { + state.flood_discr(place.as_ref(), self.map()); + } + fn handle_intrinsic( &self, intrinsic: &NonDivergingIntrinsic<'tcx>, @@ -103,16 +124,18 @@ pub trait ValueAnalysis<'tcx> { fn super_intrinsic( &self, intrinsic: &NonDivergingIntrinsic<'tcx>, - state: &mut State<Self::Value>, + _state: &mut State<Self::Value>, ) { match intrinsic { NonDivergingIntrinsic::Assume(..) => { // Could use this, but ignoring it is sound. } - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { dst, .. }) => { - if let Some(place) = dst.place() { - state.flood(place.as_ref(), self.map()); - } + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + dst: _, + src: _, + count: _, + }) => { + // This statement represents `*dst = *src`, `count` times. } } } @@ -154,7 +177,7 @@ pub trait ValueAnalysis<'tcx> { Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state), Rvalue::Ref(..) | Rvalue::AddressOf(..) => { // We don't track such places. - ValueOrPlace::top() + ValueOrPlace::TOP } Rvalue::Repeat(..) | Rvalue::ThreadLocalRef(..) @@ -168,7 +191,7 @@ pub trait ValueAnalysis<'tcx> { | Rvalue::Aggregate(..) | Rvalue::ShallowInitBox(..) => { // No modification is possible through these r-values. - ValueOrPlace::top() + ValueOrPlace::TOP } } } @@ -196,7 +219,7 @@ pub trait ValueAnalysis<'tcx> { self.map() .find(place.as_ref()) .map(ValueOrPlace::Place) - .unwrap_or(ValueOrPlace::top()) + .unwrap_or(ValueOrPlace::TOP) } } } @@ -214,7 +237,7 @@ pub trait ValueAnalysis<'tcx> { _constant: &Constant<'tcx>, _state: &mut State<Self::Value>, ) -> Self::Value { - Self::Value::top() + Self::Value::TOP } /// The effect of a successful function call return should not be @@ -229,7 +252,7 @@ pub trait ValueAnalysis<'tcx> { // Effect is applied by `handle_call_return`. } TerminatorKind::Drop { place, .. } => { - state.flood_with(place.as_ref(), self.map(), Self::Value::bottom()); + state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM); } TerminatorKind::Yield { .. } => { // They would have an effect, but are not allowed in this phase. @@ -307,7 +330,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) { // The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥. assert!(matches!(state.0, StateData::Unreachable)); - let values = IndexVec::from_elem_n(T::Value::bottom(), self.0.map().value_count); + let values = IndexVec::from_elem_n(T::Value::BOTTOM, self.0.map().value_count); *state = State(StateData::Reachable(values)); for arg in body.args_iter() { state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map()); @@ -437,7 +460,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> { } pub fn flood_all(&mut self) { - self.flood_all_with(V::top()) + self.flood_all_with(V::TOP) } pub fn flood_all_with(&mut self, value: V) { @@ -447,28 +470,24 @@ impl<V: Clone + HasTop + HasBottom> State<V> { pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) { let StateData::Reachable(values) = &mut self.0 else { return }; - map.for_each_aliasing_place(place, None, &mut |place| { - if let Some(vi) = map.places[place].value_index { - values[vi] = value.clone(); - } + map.for_each_aliasing_place(place, None, &mut |vi| { + values[vi] = value.clone(); }); } pub fn flood(&mut self, place: PlaceRef<'_>, map: &Map) { - self.flood_with(place, map, V::top()) + self.flood_with(place, map, V::TOP) } pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) { let StateData::Reachable(values) = &mut self.0 else { return }; - map.for_each_aliasing_place(place, Some(TrackElem::Discriminant), &mut |place| { - if let Some(vi) = map.places[place].value_index { - values[vi] = value.clone(); - } + map.for_each_aliasing_place(place, Some(TrackElem::Discriminant), &mut |vi| { + values[vi] = value.clone(); }); } pub fn flood_discr(&mut self, place: PlaceRef<'_>, map: &Map) { - self.flood_discr_with(place, map, V::top()) + self.flood_discr_with(place, map, V::TOP) } /// Low-level method that assigns to a place. @@ -538,14 +557,14 @@ impl<V: Clone + HasTop + HasBottom> State<V> { /// Retrieve the value stored for a place, or ⊤ if it is not tracked. pub fn get(&self, place: PlaceRef<'_>, map: &Map) -> V { - map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::top()) + map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::TOP) } /// Retrieve the value stored for a place, or ⊤ if it is not tracked. pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map) -> V { match map.find_discr(place) { Some(place) => self.get_idx(place, map), - None => V::top(), + None => V::TOP, } } @@ -553,11 +572,11 @@ impl<V: Clone + HasTop + HasBottom> State<V> { pub fn get_idx(&self, place: PlaceIndex, map: &Map) -> V { match &self.0 { StateData::Reachable(values) => { - map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::top()) + map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::TOP) } StateData::Unreachable => { // Because this is unreachable, we can return any value we want. - V::bottom() + V::BOTTOM } } } @@ -588,6 +607,9 @@ pub struct Map { projections: FxHashMap<(PlaceIndex, TrackElem), PlaceIndex>, places: IndexVec<PlaceIndex, PlaceInfo>, value_count: usize, + // The Range corresponds to a slice into `inner_values_buffer`. + inner_values: IndexVec<PlaceIndex, Range<usize>>, + inner_values_buffer: Vec<ValueIndex>, } impl Map { @@ -597,6 +619,8 @@ impl Map { projections: FxHashMap::default(), places: IndexVec::new(), value_count: 0, + inner_values: IndexVec::new(), + inner_values_buffer: Vec::new(), } } @@ -608,12 +632,12 @@ impl Map { pub fn from_filter<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - filter: impl FnMut(Ty<'tcx>) -> bool, - place_limit: Option<usize>, + filter: impl Fn(Ty<'tcx>) -> bool, + value_limit: Option<usize>, ) -> Self { let mut map = Self::new(); let exclude = excluded_locals(body); - map.register_with_filter(tcx, body, filter, exclude, place_limit); + map.register_with_filter(tcx, body, filter, exclude, value_limit); debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len()); map } @@ -623,51 +647,90 @@ impl Map { &mut self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - mut filter: impl FnMut(Ty<'tcx>) -> bool, + filter: impl Fn(Ty<'tcx>) -> bool, exclude: BitSet<Local>, - place_limit: Option<usize>, + value_limit: Option<usize>, ) { - // We use this vector as stack, pushing and popping projections. - let mut projection = Vec::new(); + let mut worklist = VecDeque::with_capacity(value_limit.unwrap_or(body.local_decls.len())); + + // Start by constructing the places for each bare local. + self.locals = IndexVec::from_elem(None, &body.local_decls); for (local, decl) in body.local_decls.iter_enumerated() { - if !exclude.contains(local) { - self.register_with_filter_rec( - tcx, - local, - &mut projection, - decl.ty, - &mut filter, - place_limit, - ); + if exclude.contains(local) { + continue; } + + // Create a place for the local. + debug_assert!(self.locals[local].is_none()); + let place = self.places.push(PlaceInfo::new(None)); + self.locals[local] = Some(place); + + // And push the eventual children places to the worklist. + self.register_children(tcx, place, decl.ty, &filter, &mut worklist); } + + // `place.elem1.elem2` with type `ty`. + // `elem1` is either `Some(Variant(i))` or `None`. + while let Some((mut place, elem1, elem2, ty)) = worklist.pop_front() { + // The user requires a bound on the number of created values. + if let Some(value_limit) = value_limit && self.value_count >= value_limit { + break + } + + // Create a place for this projection. + for elem in [elem1, Some(elem2)].into_iter().flatten() { + place = *self.projections.entry((place, elem)).or_insert_with(|| { + // Prepend new child to the linked list. + let next = self.places.push(PlaceInfo::new(Some(elem))); + self.places[next].next_sibling = self.places[place].first_child; + self.places[place].first_child = Some(next); + next + }); + } + + // And push the eventual children places to the worklist. + self.register_children(tcx, place, ty, &filter, &mut worklist); + } + + // Pre-compute the tree of ValueIndex nested in each PlaceIndex. + // `inner_values_buffer[inner_values[place]]` is the set of all the values + // reachable by projecting `place`. + self.inner_values_buffer = Vec::with_capacity(self.value_count); + self.inner_values = IndexVec::from_elem(0..0, &self.places); + for local in body.local_decls.indices() { + if let Some(place) = self.locals[local] { + self.cache_preorder_invoke(place); + } + } + + // Trim useless places. + for opt_place in self.locals.iter_mut() { + if let Some(place) = *opt_place && self.inner_values[place].is_empty() { + *opt_place = None; + } + } + #[allow(rustc::potential_query_instability)] + self.projections.retain(|_, child| !self.inner_values[*child].is_empty()); } /// Potentially register the (local, projection) place and its fields, recursively. /// /// Invariant: The projection must only contain trackable elements. - fn register_with_filter_rec<'tcx>( + fn register_children<'tcx>( &mut self, tcx: TyCtxt<'tcx>, - local: Local, - projection: &mut Vec<PlaceElem<'tcx>>, + place: PlaceIndex, ty: Ty<'tcx>, - filter: &mut impl FnMut(Ty<'tcx>) -> bool, - place_limit: Option<usize>, + filter: &impl Fn(Ty<'tcx>) -> bool, + worklist: &mut VecDeque<(PlaceIndex, Option<TrackElem>, TrackElem, Ty<'tcx>)>, ) { - if let Some(place_limit) = place_limit && self.value_count >= place_limit { - return - } - - // We know that the projection only contains trackable elements. - let place = self.make_place(local, projection).unwrap(); - // Allocate a value slot if it doesn't have one, and the user requested one. if self.places[place].value_index.is_none() && filter(ty) { self.places[place].value_index = Some(self.value_count.into()); self.value_count += 1; } + // For enums, directly create the `Discriminant`, as that's their main use. if ty.is_enum() { let discr_ty = ty.discriminant_ty(tcx); if filter(discr_ty) { @@ -692,46 +755,32 @@ impl Map { // Recurse with all fields of this place. iter_fields(ty, tcx, ty::ParamEnv::reveal_all(), |variant, field, ty| { - if let Some(variant) = variant { - projection.push(PlaceElem::Downcast(None, variant)); - let _ = self.make_place(local, projection); - projection.push(PlaceElem::Field(field, ty)); - self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit); - projection.pop(); - projection.pop(); - return; - } - projection.push(PlaceElem::Field(field, ty)); - self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit); - projection.pop(); + worklist.push_back(( + place, + variant.map(TrackElem::Variant), + TrackElem::Field(field), + ty, + )) }); } - /// Tries to add the place to the map, without allocating a value slot. - /// - /// Can fail if the projection contains non-trackable elements. - fn make_place<'tcx>( - &mut self, - local: Local, - projection: &[PlaceElem<'tcx>], - ) -> Result<PlaceIndex, ()> { - // Get the base index of the local. - let mut index = - *self.locals.get_or_insert_with(local, || self.places.push(PlaceInfo::new(None))); - - // Apply the projection. - for &elem in projection { - let elem = elem.try_into()?; - index = *self.projections.entry((index, elem)).or_insert_with(|| { - // Prepend new child to the linked list. - let next = self.places.push(PlaceInfo::new(Some(elem))); - self.places[next].next_sibling = self.places[index].first_child; - self.places[index].first_child = Some(next); - next - }); + /// Precompute the list of values inside `root` and store it inside + /// as a slice within `inner_values_buffer`. + fn cache_preorder_invoke(&mut self, root: PlaceIndex) { + let start = self.inner_values_buffer.len(); + if let Some(vi) = self.places[root].value_index { + self.inner_values_buffer.push(vi); + } + + // We manually iterate instead of using `children` as we need to mutate `self`. + let mut next_child = self.places[root].first_child; + while let Some(child) = next_child { + ensure_sufficient_stack(|| self.cache_preorder_invoke(child)); + next_child = self.places[child].next_sibling; } - Ok(index) + let end = self.inner_values_buffer.len(); + self.inner_values[root] = start..end; } /// Returns the number of tracked places, i.e., those for which a value can be stored. @@ -750,7 +799,7 @@ impl Map { place: PlaceRef<'_>, extra: impl IntoIterator<Item = TrackElem>, ) -> Option<PlaceIndex> { - let mut index = *self.locals.get(place.local)?.as_ref()?; + let mut index = *self.locals[place.local].as_ref()?; for &elem in place.projection { index = self.apply(index, elem.try_into().ok()?)?; @@ -784,17 +833,17 @@ impl Map { /// /// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track /// as such. - pub fn for_each_aliasing_place( + fn for_each_aliasing_place( &self, place: PlaceRef<'_>, tail_elem: Option<TrackElem>, - f: &mut impl FnMut(PlaceIndex), + f: &mut impl FnMut(ValueIndex), ) { - if place.is_indirect() { + if place.has_deref() { // We do not track indirect places. return; } - let Some(&Some(mut index)) = self.locals.get(place.local) else { + let Some(mut index) = self.locals[place.local] else { // The local is not tracked at all, so it does not alias anything. return; }; @@ -805,7 +854,9 @@ impl Map { .chain(tail_elem.map(Ok).into_iter()); for elem in elems { // A field aliases the parent place. - f(index); + if let Some(vi) = self.places[index].value_index { + f(vi); + } let Ok(elem) = elem else { return }; let sub = self.apply(index, elem); @@ -819,7 +870,7 @@ impl Map { return; } } - self.preorder_invoke(index, f); + self.for_each_value_inside(index, f); } /// Invoke the given function on all the descendants of the given place, except one branch. @@ -827,7 +878,7 @@ impl Map { &self, parent: PlaceIndex, preserved_child: Option<PlaceIndex>, - f: &mut impl FnMut(PlaceIndex), + f: &mut impl FnMut(ValueIndex), ) { for sibling in self.children(parent) { let elem = self.places[sibling].proj_elem; @@ -837,16 +888,17 @@ impl Map { // Only invalidate the other variants, the current one is fine. && Some(sibling) != preserved_child { - self.preorder_invoke(sibling, f); + self.for_each_value_inside(sibling, f); } } } - /// Invoke a function on the given place and all descendants. - fn preorder_invoke(&self, root: PlaceIndex, f: &mut impl FnMut(PlaceIndex)) { - f(root); - for child in self.children(root) { - self.preorder_invoke(child, f); + /// Invoke a function on each value in the given place and all descendants. + fn for_each_value_inside(&self, root: PlaceIndex, f: &mut impl FnMut(ValueIndex)) { + let range = self.inner_values[root].clone(); + let values = &self.inner_values_buffer[range]; + for &v in values { + f(v) } } } @@ -909,9 +961,7 @@ pub enum ValueOrPlace<V> { } impl<V: HasTop> ValueOrPlace<V> { - pub fn top() -> Self { - ValueOrPlace::Value(V::top()) - } + pub const TOP: Self = ValueOrPlace::Value(V::TOP); } /// The set of projection elements that can be used by a tracked place. diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 962536669e0..eca5f98a2c0 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -24,6 +24,8 @@ rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_span = { path = "../rustc_span" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_macros = { path = "../rustc_macros" } [dev-dependencies] coverage_test_macros = { path = "src/coverage/test_macros" } diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl new file mode 100644 index 00000000000..8c85cb5f76d --- /dev/null +++ b/compiler/rustc_mir_transform/messages.ftl @@ -0,0 +1,66 @@ +mir_transform_const_modify = attempting to modify a `const` item + .note = each usage of a `const` item creates a new temporary; the original `const` item will not be modified + +mir_transform_const_mut_borrow = taking a mutable reference to a `const` item + .note = each usage of a `const` item creates a new temporary + .note2 = the mutable reference will refer to this temporary, not the original `const` item + .note3 = mutable reference created due to call to this method + +mir_transform_const_defined_here = `const` item defined here + +mir_transform_unaligned_packed_ref = reference to packed field is unaligned + .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +mir_transform_unused_unsafe = unnecessary `unsafe` block + .label = because it's nested under this `unsafe` block + +mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in_unsafe_fn_allowed -> + [true] function or block + *[false] block + } + .not_inherited = items do not inherit unsafety from separate enclosing items + +mir_transform_call_to_unsafe_label = call to unsafe function +mir_transform_call_to_unsafe_note = consult the function's documentation for information on how to avoid undefined behavior +mir_transform_use_of_asm_label = use of inline assembly +mir_transform_use_of_asm_note = inline assembly is entirely unchecked and can cause undefined behavior +mir_transform_initializing_valid_range_label = initializing type with `rustc_layout_scalar_valid_range` attr +mir_transform_initializing_valid_range_note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior +mir_transform_const_ptr2int_label = cast of pointer to int +mir_transform_const_ptr2int_note = casting pointers to integers in constants +mir_transform_use_of_static_mut_label = use of mutable static +mir_transform_use_of_static_mut_note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior +mir_transform_use_of_extern_static_label = use of extern static +mir_transform_use_of_extern_static_note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior +mir_transform_deref_ptr_label = dereference of raw pointer +mir_transform_deref_ptr_note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior +mir_transform_union_access_label = access to union field +mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior +mir_transform_mutation_layout_constrained_label = mutation of layout constrained field +mir_transform_mutation_layout_constrained_note = mutating layout constrained fields cannot statically be checked for valid values +mir_transform_mutation_layout_constrained_borrow_label = borrow of layout constrained field with interior mutability +mir_transform_mutation_layout_constrained_borrow_note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values +mir_transform_target_feature_call_label = call to function with `#[target_feature]` +mir_transform_target_feature_call_note = can only be called if the required target features are available + +mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133) + +mir_transform_arithmetic_overflow = this arithmetic operation will overflow +mir_transform_operation_will_panic = this operation will panic at runtime + +mir_transform_ffi_unwind_call = call to {$foreign -> + [true] foreign function + *[false] function pointer + } with FFI-unwind ABI + +mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer + .suggestion = cast `{$ident}` to obtain a function pointer + +mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be + .label = the value is held across this suspend point + .note = {$reason} + .help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point + +mir_transform_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 57b24c9c552..b79150737d6 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -1,11 +1,12 @@ -use rustc_errors::{DiagnosticBuilder, DiagnosticMessage}; +use rustc_hir::HirId; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::CONST_ITEM_MUTATION; use rustc_span::def_id::DefId; +use rustc_span::Span; -use crate::MirLint; +use crate::{errors, MirLint}; pub struct CheckConstItemMutation; @@ -58,16 +59,14 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { } } - fn lint_const_item_usage( + /// If we should lint on this usage, return the [`HirId`], source [`Span`] + /// and [`Span`] of the const item to use in the lint. + fn should_lint_const_item_usage( &self, place: &Place<'tcx>, const_item: DefId, location: Location, - msg: impl Into<DiagnosticMessage>, - decorate: impl for<'a, 'b> FnOnce( - &'a mut DiagnosticBuilder<'b, ()>, - ) -> &'a mut DiagnosticBuilder<'b, ()>, - ) { + ) -> Option<(HirId, Span, Span)> { // Don't lint on borrowing/assigning when a dereference is involved. // If we 'leave' the temporary via a dereference, we must // be modifying something else @@ -83,16 +82,9 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { .assert_crate_local() .lint_root; - self.tcx.struct_span_lint_hir( - CONST_ITEM_MUTATION, - lint_root, - source_info.span, - msg, - |lint| { - decorate(lint) - .span_note(self.tcx.def_span(const_item), "`const` item defined here") - }, - ); + Some((lint_root, source_info.span, self.tcx.def_span(const_item))) + } else { + None } } } @@ -104,10 +96,14 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { // Assigning directly to a constant (e.g. `FOO = true;`) is a hard error, // so emitting a lint would be redundant. if !lhs.projection.is_empty() { - if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) { - self.lint_const_item_usage(&lhs, def_id, loc, "attempting to modify a `const` item",|lint| { - lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified") - }) + if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) + && let Some((lint_root, span, item)) = self.should_lint_const_item_usage(&lhs, def_id, loc) { + self.tcx.emit_spanned_lint( + CONST_ITEM_MUTATION, + lint_root, + span, + errors::ConstMutate::Modify { konst: item } + ); } } // We are looking for MIR of the form: @@ -143,17 +139,22 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; - self.lint_const_item_usage(place, def_id, lint_loc, "taking a mutable reference to a `const` item", |lint| { - lint - .note("each usage of a `const` item creates a new temporary") - .note("the mutable reference will refer to this temporary, not the original `const` item"); - - if let Some((method_did, _substs)) = method_did { - lint.span_note(self.tcx.def_span(method_did), "mutable reference created due to call to this method"); - } - lint - }); + let method_call = if let Some((method_did, _)) = method_did { + Some(self.tcx.def_span(method_did)) + } else { + None + }; + if let Some((lint_root, span, item)) = + self.should_lint_const_item_usage(place, def_id, lint_loc) + { + self.tcx.emit_spanned_lint( + CONST_ITEM_MUTATION, + lint_root, + span, + errors::ConstMutate::MutBorrow { method_call, konst: item }, + ); + } } } self.super_rvalue(rvalue, loc); diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index b9bc89fcf8f..2e6cf603d59 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -1,10 +1,9 @@ -use rustc_errors::struct_span_err; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; -use crate::util; use crate::MirLint; +use crate::{errors, util}; pub struct CheckPackedRef; @@ -49,25 +48,7 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { // shouldn't do. span_bug!(self.source_info.span, "builtin derive created an unaligned reference"); } else { - struct_span_err!( - self.tcx.sess, - self.source_info.span, - E0793, - "reference to packed field is unaligned" - ) - .note( - "packed structs are only aligned by one byte, and many modern architectures \ - penalize unaligned field accesses" - ) - .note( - "creating a misaligned reference is undefined behavior (even if that \ - reference is never dereferenced)", - ).help( - "copy the field contents to a local variable, or replace the \ - reference with a raw pointer and use `read_unaligned`/`write_unaligned` \ - (loads and stores via `*p` must be properly aligned even when using raw pointers)" - ) - .emit(); + self.tcx.sess.emit_err(errors::UnalignedPackedRef { span: self.source_info.span }); } } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index ce6d865a7dc..069514d8a3b 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,5 +1,4 @@ use rustc_data_structures::unord::{UnordItems, UnordSet}; -use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -8,13 +7,15 @@ 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; use std::ops::Bound; +use crate::errors; + pub struct UnsafetyChecker<'a, 'tcx> { body: &'a Body<'tcx>, body_did: LocalDefId, @@ -509,21 +510,12 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResu fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id)); - let msg = "unnecessary `unsafe` block"; - tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, msg, |lint| { - lint.span_label(span, msg); - match kind { - UnusedUnsafe::Unused => {} - UnusedUnsafe::InUnsafeBlock(id) => { - lint.span_label( - tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), - "because it's nested under this `unsafe` block", - ); - } - } - - lint - }); + let nested_parent = if let UnusedUnsafe::InUnsafeBlock(id) = kind { + Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id))) + } else { + None + }; + tcx.emit_spanned_lint(UNUSED_UNSAFE, id, span, errors::UnusedUnsafe { span, nested_parent }); } pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { @@ -537,26 +529,11 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { let UnsafetyCheckResult { violations, unused_unsafes, .. } = tcx.unsafety_check_result(def_id); for &UnsafetyViolation { source_info, lint_root, kind, details } in violations.iter() { - let (description, note) = details.description_and_note(); + let details = errors::RequiresUnsafeDetail { violation: details, span: source_info.span }; match kind { UnsafetyViolationKind::General => { - // once - let unsafe_fn_msg = if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { - " function or" - } else { - "" - }; - - let mut err = struct_span_err!( - tcx.sess, - source_info.span, - E0133, - "{} is unsafe and requires unsafe{} block", - description, - unsafe_fn_msg, - ); - err.span_label(source_info.span, description).note(note); + let op_in_unsafe_fn_allowed = unsafe_op_in_unsafe_fn_allowed(tcx, lint_root); let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| { if let Node::Expr(block) = node && let ExprKind::Block(block, _) = block.kind @@ -572,22 +549,23 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { false } }); - if let Some((id, _)) = note_non_inherited { - let span = tcx.hir().span(id); - err.span_label( - tcx.sess.source_map().guess_head_span(span), - "items do not inherit unsafety from separate enclosing items", - ); - } - - err.emit(); + let enclosing = if let Some((id, _)) = note_non_inherited { + Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id))) + } else { + None + }; + tcx.sess.emit_err(errors::RequiresUnsafe { + span: source_info.span, + enclosing, + details, + op_in_unsafe_fn_allowed, + }); } - UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir( + UnsafetyViolationKind::UnsafeFn => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, lint_root, source_info.span, - format!("{} is unsafe and requires unsafe block (error E0133)", description,), - |lint| lint.span_label(source_info.span, description).note(note), + errors::UnsafeOpInUnsafeFn { details }, ), } } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 7f995c69a48..a5d18fff89b 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -806,6 +806,24 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { } } + fn process_projection_elem( + &mut self, + elem: PlaceElem<'tcx>, + _: Location, + ) -> Option<PlaceElem<'tcx>> { + if let PlaceElem::Index(local) = elem + && let Some(value) = self.get_const(local.into()) + && self.should_const_prop(&value) + && let interpret::Operand::Immediate(interpret::Immediate::Scalar(scalar)) = *value + && let Ok(offset) = scalar.to_target_usize(&self.tcx) + && let Some(min_length) = offset.checked_add(1) + { + Some(PlaceElem::ConstantIndex { offset, min_length, from_end: false }) + } else { + None + } + } + fn visit_assign( &mut self, place: &mut Place<'tcx>, diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index a4049d08d7b..adb09c509d2 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -1,6 +1,8 @@ //! Propagates constants for early reporting of statically known //! assertion failures +use std::fmt::Debug; + use either::Left; use rustc_const_eval::interpret::Immediate; @@ -17,7 +19,6 @@ use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{ self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, }; -use rustc_session::lint; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; use rustc_trait_selection::traits; @@ -25,6 +26,7 @@ use rustc_trait_selection::traits; use crate::const_prop::CanConstProp; use crate::const_prop::ConstPropMachine; use crate::const_prop::ConstPropMode; +use crate::errors::AssertLint; use crate::MirLint; /// The maximum number of bytes that we'll allocate space for a local or the return value. @@ -311,18 +313,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn report_assert_as_lint( - &self, - lint: &'static lint::Lint, - location: Location, - message: &'static str, - panic: AssertKind<impl std::fmt::Debug>, - ) { - let source_info = self.body().source_info(location); + fn report_assert_as_lint(&self, source_info: &SourceInfo, lint: AssertLint<impl Debug>) { if let Some(lint_root) = self.lint_root(*source_info) { - self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, message, |lint| { - lint.span_label(source_info.span, format!("{:?}", panic)) - }); + self.tcx.emit_spanned_lint(lint.lint(), lint_root, source_info.span, lint); } } @@ -335,11 +328,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // `AssertKind` only has an `OverflowNeg` variant, so make sure that is // appropriate to use. assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow"); + let source_info = self.body().source_info(location); self.report_assert_as_lint( - lint::builtin::ARITHMETIC_OVERFLOW, - location, - "this arithmetic operation will overflow", - AssertKind::OverflowNeg(val.to_const_int()), + source_info, + AssertLint::ArithmeticOverflow( + source_info.span, + AssertKind::OverflowNeg(val.to_const_int()), + ), ); return None; } @@ -370,23 +365,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let r_bits = r.to_scalar().to_bits(right_size).ok(); if r_bits.map_or(false, |b| b >= left_size.bits() as u128) { debug!("check_binary_op: reporting assert for {:?}", location); + let source_info = self.body().source_info(location); + let panic = AssertKind::Overflow( + op, + match l { + Some(l) => l.to_const_int(), + // Invent a dummy value, the diagnostic ignores it anyway + None => ConstInt::new( + ScalarInt::try_from_uint(1_u8, left_size).unwrap(), + left_ty.is_signed(), + left_ty.is_ptr_sized_integral(), + ), + }, + r.to_const_int(), + ); self.report_assert_as_lint( - lint::builtin::ARITHMETIC_OVERFLOW, - location, - "this arithmetic operation will overflow", - AssertKind::Overflow( - op, - match l { - Some(l) => l.to_const_int(), - // Invent a dummy value, the diagnostic ignores it anyway - None => ConstInt::new( - ScalarInt::try_from_uint(1_u8, left_size).unwrap(), - left_ty.is_signed(), - left_ty.is_ptr_sized_integral(), - ), - }, - r.to_const_int(), - ), + source_info, + AssertLint::ArithmeticOverflow(source_info.span, panic), ); return None; } @@ -398,11 +393,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, &l, &r)?; Ok(overflow) })? { + let source_info = self.body().source_info(location); self.report_assert_as_lint( - lint::builtin::ARITHMETIC_OVERFLOW, - location, - "this arithmetic operation will overflow", - AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()), + source_info, + AssertLint::ArithmeticOverflow( + source_info.span, + AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()), + ), ); return None; } @@ -543,11 +540,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need proper const propagator for these. _ => return None, }; + let source_info = self.body().source_info(location); self.report_assert_as_lint( - lint::builtin::UNCONDITIONAL_PANIC, - location, - "this operation will panic at runtime", - msg, + source_info, + AssertLint::UnconditionalPanic(source_info.span, msg), ); } diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 3922ed2fbf7..319f3a79705 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -33,9 +33,8 @@ impl<'tcx> MirPass<'tcx> for CopyProp { } fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); let borrowed_locals = borrowed_locals(body); - let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals); + let ssa = SsaLocals::new(body); let fully_moved = fully_moved_locals(&ssa, body); debug!(?fully_moved); @@ -76,7 +75,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> { let mut fully_moved = BitSet::new_filled(body.local_decls.len()); - for (_, rvalue) in ssa.assignments(body) { + for (_, rvalue, _) in ssa.assignments(body) { let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place)) = rvalue else { continue }; @@ -163,20 +162,22 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { } fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) { - match stmt.kind { - // When removing storage statements, we need to remove both (#107511). - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) - if self.storage_to_remove.contains(l) => - { - stmt.make_nop() - } - StatementKind::Assign(box (ref place, ref mut rvalue)) - if place.as_local().is_some() => - { - // Do not replace assignments. - self.visit_rvalue(rvalue, loc) - } - _ => self.super_statement(stmt, loc), + // When removing storage statements, we need to remove both (#107511). + if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind + && self.storage_to_remove.contains(l) + { + stmt.make_nop(); + return + } + + self.super_statement(stmt, loc); + + // Do not leave tautological assignments around. + if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind + && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs + && lhs == rhs + { + stmt.make_nop(); } } } 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/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 254b704f9fc..7adfc9dff2a 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -79,22 +79,22 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { &self.map } - fn handle_statement(&self, statement: &Statement<'tcx>, state: &mut State<Self::Value>) { - match statement.kind { - StatementKind::SetDiscriminant { box ref place, variant_index } => { - state.flood_discr(place.as_ref(), &self.map); - if self.map.find_discr(place.as_ref()).is_some() { - let enum_ty = place.ty(self.local_decls, self.tcx).ty; - if let Some(discr) = self.eval_discriminant(enum_ty, variant_index) { - state.assign_discr( - place.as_ref(), - ValueOrPlace::Value(FlatSet::Elem(discr)), - &self.map, - ); - } - } + fn handle_set_discriminant( + &self, + place: Place<'tcx>, + variant_index: VariantIdx, + state: &mut State<Self::Value>, + ) { + state.flood_discr(place.as_ref(), &self.map); + if self.map.find_discr(place.as_ref()).is_some() { + let enum_ty = place.ty(self.local_decls, self.tcx).ty; + if let Some(discr) = self.eval_discriminant(enum_ty, variant_index) { + state.assign_discr( + place.as_ref(), + ValueOrPlace::Value(FlatSet::Elem(discr)), + &self.map, + ); } - _ => self.super_statement(statement, state), } } @@ -208,8 +208,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { _ => unreachable!(), } .map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty))) - .unwrap_or(ValueOrPlace::top()), - _ => ValueOrPlace::top(), + .unwrap_or(ValueOrPlace::TOP), + _ => ValueOrPlace::TOP, }, Rvalue::BinaryOp(op, box (left, right)) => { // Overflows must be ignored here. 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/errors.rs b/compiler/rustc_mir_transform/src/errors.rs new file mode 100644 index 00000000000..602e40d5131 --- /dev/null +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -0,0 +1,245 @@ +use rustc_errors::{ + DecorateLint, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, IntoDiagnostic, +}; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails}; +use rustc_session::lint::{self, Lint}; +use rustc_span::Span; + +#[derive(LintDiagnostic)] +pub(crate) enum ConstMutate { + #[diag(mir_transform_const_modify)] + #[note] + Modify { + #[note(mir_transform_const_defined_here)] + konst: Span, + }, + #[diag(mir_transform_const_mut_borrow)] + #[note] + #[note(mir_transform_note2)] + MutBorrow { + #[note(mir_transform_note3)] + method_call: Option<Span>, + #[note(mir_transform_const_defined_here)] + konst: Span, + }, +} + +#[derive(Diagnostic)] +#[diag(mir_transform_unaligned_packed_ref, code = "E0793")] +#[note] +#[note(mir_transform_note_ub)] +#[help] +pub(crate) struct UnalignedPackedRef { + #[primary_span] + pub span: Span, +} + +#[derive(LintDiagnostic)] +#[diag(mir_transform_unused_unsafe)] +pub(crate) struct UnusedUnsafe { + #[label(mir_transform_unused_unsafe)] + pub span: Span, + #[label] + pub nested_parent: Option<Span>, +} + +pub(crate) struct RequiresUnsafe { + pub span: Span, + pub details: RequiresUnsafeDetail, + pub enclosing: Option<Span>, + pub op_in_unsafe_fn_allowed: bool, +} + +// The primary message for this diagnostic should be '{$label} is unsafe and...', +// so we need to eagerly translate the label here, which isn't supported by the derive API +// We could also exhaustively list out the primary messages for all unsafe violations, +// but this would result in a lot of duplication. +impl<'sess, G: EmissionGuarantee> IntoDiagnostic<'sess, G> for RequiresUnsafe { + #[track_caller] + fn into_diagnostic(self, handler: &'sess Handler) -> DiagnosticBuilder<'sess, G> { + let mut diag = + handler.struct_diagnostic(crate::fluent_generated::mir_transform_requires_unsafe); + diag.code(rustc_errors::DiagnosticId::Error("E0133".to_string())); + diag.set_span(self.span); + diag.span_label(self.span, self.details.label()); + diag.note(self.details.note()); + let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter()); + diag.set_arg("details", desc); + diag.set_arg("op_in_unsafe_fn_allowed", self.op_in_unsafe_fn_allowed); + if let Some(sp) = self.enclosing { + diag.span_label(sp, crate::fluent_generated::mir_transform_not_inherited); + } + diag + } +} + +#[derive(Copy, Clone)] +pub(crate) struct RequiresUnsafeDetail { + pub span: Span, + pub violation: UnsafetyViolationDetails, +} + +impl RequiresUnsafeDetail { + fn note(self) -> DiagnosticMessage { + use UnsafetyViolationDetails::*; + match self.violation { + CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_note, + UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_note, + InitializingTypeWith => { + crate::fluent_generated::mir_transform_initializing_valid_range_note + } + CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_note, + UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_note, + UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_note, + DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_note, + AccessToUnionField => crate::fluent_generated::mir_transform_union_access_note, + MutationOfLayoutConstrainedField => { + crate::fluent_generated::mir_transform_mutation_layout_constrained_note + } + BorrowOfLayoutConstrainedField => { + crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_note + } + CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_note, + } + } + + fn label(self) -> DiagnosticMessage { + use UnsafetyViolationDetails::*; + match self.violation { + CallToUnsafeFunction => crate::fluent_generated::mir_transform_call_to_unsafe_label, + UseOfInlineAssembly => crate::fluent_generated::mir_transform_use_of_asm_label, + InitializingTypeWith => { + crate::fluent_generated::mir_transform_initializing_valid_range_label + } + CastOfPointerToInt => crate::fluent_generated::mir_transform_const_ptr2int_label, + UseOfMutableStatic => crate::fluent_generated::mir_transform_use_of_static_mut_label, + UseOfExternStatic => crate::fluent_generated::mir_transform_use_of_extern_static_label, + DerefOfRawPointer => crate::fluent_generated::mir_transform_deref_ptr_label, + AccessToUnionField => crate::fluent_generated::mir_transform_union_access_label, + MutationOfLayoutConstrainedField => { + crate::fluent_generated::mir_transform_mutation_layout_constrained_label + } + BorrowOfLayoutConstrainedField => { + crate::fluent_generated::mir_transform_mutation_layout_constrained_borrow_label + } + CallToFunctionWith => crate::fluent_generated::mir_transform_target_feature_call_label, + } + } +} + +pub(crate) struct UnsafeOpInUnsafeFn { + pub details: RequiresUnsafeDetail, +} + +impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn { + #[track_caller] + fn decorate_lint<'b>( + self, + diag: &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()> { + let desc = diag + .handler() + .expect("lint should not yet be emitted") + .eagerly_translate_to_string(self.details.label(), [].into_iter()); + diag.set_arg("details", desc); + diag.span_label(self.details.span, self.details.label()); + diag.note(self.details.note()); + diag + } + + fn msg(&self) -> DiagnosticMessage { + crate::fluent_generated::mir_transform_unsafe_op_in_unsafe_fn + } +} + +pub(crate) enum AssertLint<P> { + ArithmeticOverflow(Span, AssertKind<P>), + UnconditionalPanic(Span, AssertKind<P>), +} + +impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> { + fn decorate_lint<'b>( + self, + diag: &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()> { + diag.span_label(self.span(), format!("{:?}", self.panic())); + diag + } + + fn msg(&self) -> DiagnosticMessage { + match self { + AssertLint::ArithmeticOverflow(..) => { + crate::fluent_generated::mir_transform_arithmetic_overflow + } + AssertLint::UnconditionalPanic(..) => { + crate::fluent_generated::mir_transform_operation_will_panic + } + } + } +} + +impl<P> AssertLint<P> { + pub fn lint(&self) -> &'static Lint { + match self { + AssertLint::ArithmeticOverflow(..) => lint::builtin::ARITHMETIC_OVERFLOW, + AssertLint::UnconditionalPanic(..) => lint::builtin::UNCONDITIONAL_PANIC, + } + } + pub fn span(&self) -> Span { + match self { + AssertLint::ArithmeticOverflow(sp, _) | AssertLint::UnconditionalPanic(sp, _) => *sp, + } + } + pub fn panic(&self) -> &AssertKind<P> { + match self { + AssertLint::ArithmeticOverflow(_, p) | AssertLint::UnconditionalPanic(_, p) => p, + } + } +} + +#[derive(LintDiagnostic)] +#[diag(mir_transform_ffi_unwind_call)] +pub(crate) struct FfiUnwindCall { + #[label(mir_transform_ffi_unwind_call)] + pub span: Span, + pub foreign: bool, +} + +#[derive(LintDiagnostic)] +#[diag(mir_transform_fn_item_ref)] +pub(crate) struct FnItemRef { + #[suggestion(code = "{sugg}", applicability = "unspecified")] + pub span: Span, + pub sugg: String, + pub ident: String, +} + +#[derive(LintDiagnostic)] +#[diag(mir_transform_must_not_suspend)] +pub(crate) struct MustNotSupend<'a> { + #[label] + pub yield_sp: Span, + #[subdiagnostic] + pub reason: Option<MustNotSuspendReason>, + #[help] + pub src_sp: Span, + pub pre: &'a str, + pub def_path: String, + pub post: &'a str, +} + +#[derive(Subdiagnostic)] +#[note(mir_transform_note)] +pub(crate) struct MustNotSuspendReason { + #[primary_span] + pub span: Span, + pub reason: String, +} + +#[derive(Diagnostic)] +#[diag(mir_transform_simd_shuffle_last_const)] +pub(crate) struct SimdShuffleLastConst { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index db68adc8bc9..58cc161ddcc 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -1,13 +1,15 @@ 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; use rustc_target::spec::PanicStrategy; +use crate::errors; + fn abi_can_unwind(abi: Abi) -> bool { use Abi::*; match abi { @@ -107,13 +109,13 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { .lint_root; let span = terminator.source_info.span; - let msg = match fn_def_id { - Some(_) => "call to foreign function with FFI-unwind ABI", - None => "call to function pointer with FFI-unwind ABI", - }; - tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, msg, |lint| { - lint.span_label(span, msg) - }); + let foreign = fn_def_id.is_some(); + tcx.emit_spanned_lint( + FFI_UNWIND_CALLS, + lint_root, + span, + errors::FfiUnwindCall { span, foreign }, + ); tainted = true; } diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index f26c6de9648..5989dbebf2d 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -1,5 +1,4 @@ use itertools::Itertools; -use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; @@ -8,7 +7,7 @@ use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES; use rustc_span::{symbol::sym, Span}; use rustc_target::spec::abi::Abi; -use crate::MirLint; +use crate::{errors, MirLint}; pub struct FunctionItemReferences; @@ -174,27 +173,21 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder(); let variadic = if fn_sig.c_variadic() { ", ..." } else { "" }; let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; - self.tcx.struct_span_lint_hir( + let sugg = format!( + "{} as {}{}fn({}{}){}", + if params.is_empty() { ident.clone() } else { format!("{}::<{}>", ident, params) }, + unsafety, + abi, + vec!["_"; num_args].join(", "), + variadic, + ret, + ); + + self.tcx.emit_spanned_lint( FUNCTION_ITEM_REFERENCES, lint_root, span, - "taking a reference to a function item does not give a function pointer", - |lint| { - lint.span_suggestion( - span, - format!("cast `{}` to obtain a function pointer", ident), - format!( - "{} as {}{}fn({}{}){}", - if params.is_empty() { ident } else { format!("{}::<{}>", ident, params) }, - unsafety, - abi, - vec!["_"; num_args].join(", "), - variadic, - ret, - ), - Applicability::Unspecified, - ) - }, + errors::FnItemRef { span, sugg, ident }, ); } } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 9e16c400f14..891e446942e 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -51,6 +51,7 @@ //! Otherwise it drops all the values in scope at the last suspension point. use crate::deref_separator::deref_finder; +use crate::errors; use crate::simplify; use crate::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -1396,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); @@ -1409,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), }; @@ -1424,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 { @@ -1891,36 +1893,21 @@ fn check_must_not_suspend_def( data: SuspendCheckData<'_>, ) -> bool { if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) { - let msg = rustc_errors::DelayDm(|| { - format!( - "{}`{}`{} held across a suspend point, but should not be", - data.descr_pre, - tcx.def_path_str(def_id), - data.descr_post, - ) + let reason = attr.value_str().map(|s| errors::MustNotSuspendReason { + span: data.source_span, + reason: s.as_str().to_string(), }); - tcx.struct_span_lint_hir( + tcx.emit_spanned_lint( rustc_session::lint::builtin::MUST_NOT_SUSPEND, hir_id, data.source_span, - msg, - |lint| { - // add span pointing to the offending yield/await - lint.span_label(data.yield_span, "the value is held across this suspend point"); - - // Add optional reason note - if let Some(note) = attr.value_str() { - // FIXME(guswynn): consider formatting this better - lint.span_note(data.source_span, note.as_str()); - } - - // Add some quick suggestions on what to do - // FIXME: can `drop` work as a suggestion here as well? - lint.span_help( - data.source_span, - "consider using a block (`{ ... }`) \ - to shrink the value's scope, ending before the suspend point", - ) + errors::MustNotSupend { + yield_sp: data.yield_span, + reason, + src_sp: data.source_span, + pre: data.descr_pre, + def_path: tcx.def_path_str(def_id), + post: data.descr_post, }, ); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index ece20d8d3e6..12f955d46bd 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -7,6 +7,7 @@ use rustc_index::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; @@ -168,7 +169,7 @@ impl<'tcx> Inliner<'tcx> { let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); self.check_codegen_attributes(callsite, callee_attrs)?; self.check_mir_is_available(caller_body, &callsite.callee)?; - let callee_body = self.tcx.instance_mir(callsite.callee.def); + let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?; self.check_mir_body(callsite, callee_body, callee_attrs)?; if !self.tcx.consider_optimizing(|| { @@ -1128,3 +1129,27 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { } } } + +#[instrument(skip(tcx), level = "debug")] +fn try_instance_mir<'tcx>( + tcx: TyCtxt<'tcx>, + instance: InstanceDef<'tcx>, +) -> Result<&'tcx Body<'tcx>, &'static str> { + match instance { + ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() { + ty::Adt(def, substs) => { + let fields = def.all_fields(); + for field in fields { + let field_ty = field.ty(tcx, substs); + if field_ty.has_param() && field_ty.has_projections() { + return Err("cannot build drop shim for polymorphic type"); + } + } + + Ok(tcx.instance_mir(instance)) + } + _ => Ok(tcx.instance_mir(instance)), + }, + _ => Ok(tcx.instance_mir(instance)), + } +} diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 6bff535586a..e4dc617620e 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -5,7 +5,6 @@ use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::*; use rustc_middle::ty::layout::ValidityRequirement; -use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::abi::FieldIdx; @@ -163,18 +162,6 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { return; } - // Transmuting a fieldless enum to its repr is a discriminant read - if let ty::Adt(adt_def, ..) = operand_ty.kind() - && adt_def.is_enum() - && adt_def.is_payloadfree() - && let Some(place) = operand.place() - && let Some(repr_int) = adt_def.repr().int - && repr_int.to_ty(self.tcx) == *cast_ty - { - *rvalue = Rvalue::Discriminant(place); - return; - } - // Transmuting a transparent struct/union to a field's type is a projection if let ty::Adt(adt_def, substs) = operand_ty.kind() && adt_def.repr().transparent() diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index f25a9f042c4..65864dc016f 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,4 +1,6 @@ #![allow(rustc::potential_query_instability)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #![feature(box_patterns)] #![feature(drain_filter)] #![feature(let_chains)] @@ -32,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; @@ -69,6 +71,7 @@ pub mod dump_mir; mod early_otherwise_branch; mod elaborate_box_derefs; mod elaborate_drops; +mod errors; mod ffi_unwind_calls; mod function_item_references; mod generator; @@ -81,6 +84,7 @@ mod match_branches; mod multiple_return_terminators; mod normalize_array_len; mod nrvo; +mod ref_prop; mod remove_noop_landing_pads; mod remove_storage_markers; mod remove_uninit_drops; @@ -105,6 +109,11 @@ use rustc_const_eval::transform::promote_consts; use rustc_const_eval::transform::validate; use rustc_mir_dataflow::rustc_peek; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; + +fluent_messages! { "../messages.ftl" } + pub fn provide(providers: &mut Providers) { check_unsafety::provide(providers); coverage::query::provide(providers); @@ -551,6 +560,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &separate_const_switch::SeparateConstSwitch, &simplify::SimplifyLocals::BeforeConstProp, ©_prop::CopyProp, + &ref_prop::ReferencePropagation, &const_prop::ConstProp, &dataflow_const_prop::DataflowConstProp, // diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 69ba4840146..dae01e41e5f 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -1,6 +1,6 @@ //! Lowers intrinsic calls -use crate::MirPass; +use crate::{errors, MirPass}; use rustc_middle::mir::*; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -310,11 +310,7 @@ fn resolve_rust_intrinsic<'tcx>( } fn validate_simd_shuffle<'tcx>(tcx: TyCtxt<'tcx>, args: &[Operand<'tcx>], span: Span) { - match &args[2] { - Operand::Constant(_) => {} // all good - _ => { - let msg = "last argument of `simd_shuffle` is required to be a `const` item"; - tcx.sess.span_err(span, msg); - } + if !matches!(args[2], Operand::Constant(_)) { + tcx.sess.emit_err(errors::SimdShuffleLastConst { span }); } } diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index b3b831bb4ab..3d61d33ce35 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -7,7 +7,6 @@ use rustc_index::IndexVec; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; -use rustc_mir_dataflow::impls::borrowed_locals; pub struct NormalizeArrayLen; @@ -24,9 +23,7 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen { } fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); - let borrowed_locals = borrowed_locals(body); - let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals); + let ssa = SsaLocals::new(body); let slice_lengths = compute_slice_length(tcx, &ssa, body); debug!(?slice_lengths); @@ -41,7 +38,7 @@ fn compute_slice_length<'tcx>( ) -> IndexVec<Local, Option<ty::Const<'tcx>>> { let mut slice_lengths = IndexVec::from_elem(None, &body.local_decls); - for (local, rvalue) in ssa.assignments(body) { + for (local, rvalue, _) in ssa.assignments(body) { match rvalue { Rvalue::Cast( CastKind::Pointer(ty::adjustment::PointerCast::Unsize), diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index b6e73eaad50..85b26220b1e 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -34,7 +34,8 @@ pub struct RenameReturnPlace; impl<'tcx> MirPass<'tcx> for RenameReturnPlace { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() > 0 + // #111005 + sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs new file mode 100644 index 00000000000..bbd9f76ba5c --- /dev/null +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -0,0 +1,408 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_index::bit_set::BitSet; +use rustc_index::IndexVec; +use rustc_middle::mir::visit::*; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; +use rustc_mir_dataflow::impls::MaybeStorageDead; +use rustc_mir_dataflow::storage::always_storage_live_locals; +use rustc_mir_dataflow::Analysis; + +use crate::ssa::{SsaLocals, StorageLiveLocals}; +use crate::MirPass; + +/// Propagate references using SSA analysis. +/// +/// MIR building may produce a lot of borrow-dereference patterns. +/// +/// This pass aims to transform the following pattern: +/// _1 = &raw? mut? PLACE; +/// _3 = *_1; +/// _4 = &raw? mut? *_1; +/// +/// Into +/// _1 = &raw? mut? PLACE; +/// _3 = PLACE; +/// _4 = &raw? mut? PLACE; +/// +/// where `PLACE` is a direct or an indirect place expression. +/// +/// There are 3 properties that need to be upheld for this transformation to be legal: +/// - place stability: `PLACE` must refer to the same memory wherever it appears; +/// - pointer liveness: we must not introduce dereferences of dangling pointers; +/// - `&mut` borrow uniqueness. +/// +/// # Stability +/// +/// If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where: +/// - `LOCAL` is SSA; +/// - all projections in `PROJECTIONS` have a stable offset (no dereference and no indexing). +/// +/// If `PLACE` is a direct projection of a local, we consider it as constant if: +/// - the local is always live, or it has a single `StorageLive`; +/// - all projections have a stable offset. +/// +/// # Liveness +/// +/// When performing a substitution, we must take care not to introduce uses of dangling locals. +/// To ensure this, we walk the body with the `MaybeStorageDead` dataflow analysis: +/// - if we want to replace `*x` by reborrow `*y` and `y` may be dead, we allow replacement and +/// mark storage statements on `y` for removal; +/// - if we want to replace `*x` by non-reborrow `y` and `y` must be live, we allow replacement; +/// - if we want to replace `*x` by non-reborrow `y` and `y` may be dead, we do not replace. +/// +/// # Uniqueness +/// +/// For `&mut` borrows, we also need to preserve the uniqueness property: +/// we must avoid creating a state where we interleave uses of `*_1` and `_2`. +/// To do it, we only perform full substitution of mutable borrows: +/// we replace either all or none of the occurrences of `*_1`. +/// +/// Some care has to be taken when `_1` is copied in other locals. +/// _1 = &raw? mut? _2; +/// _3 = *_1; +/// _4 = _1 +/// _5 = *_4 +/// In such cases, fully substituting `_1` means fully substituting all of the copies. +/// +/// For immutable borrows, we do not need to preserve such uniqueness property, +/// so we perform all the possible substitutions without removing the `_1 = &_2` statement. +pub struct ReferencePropagation; + +impl<'tcx> MirPass<'tcx> for ReferencePropagation { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + sess.mir_opt_level() >= 4 + } + + #[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()); + while propagate_ssa(tcx, body) {} + } +} + +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); + debug!(?replacer.targets); + debug!(?replacer.allowed_replacements); + debug!(?replacer.storage_to_remove); + + replacer.visit_body_preserves_cfg(body); + + if replacer.any_replacement { + crate::simplify::remove_unused_definitions(body); + } + + replacer.any_replacement +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum Value<'tcx> { + /// Not a pointer, or we can't know. + Unknown, + /// We know the value to be a pointer to this place. + /// The boolean indicates whether the reference is mutable, subject the uniqueness rule. + Pointer(Place<'tcx>, bool), +} + +/// For each local, save the place corresponding to `*local`. +#[instrument(level = "trace", skip(tcx, body))] +fn compute_replacement<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, + ssa: &SsaLocals, +) -> Replacer<'tcx> { + let always_live_locals = always_storage_live_locals(body); + + // Compute which locals have a single `StorageLive` statement ever. + let storage_live = StorageLiveLocals::new(body, &always_live_locals); + + // Compute `MaybeStorageDead` dataflow to check that we only replace when the pointee is + // definitely live. + let mut maybe_dead = MaybeStorageDead::new(always_live_locals) + .into_engine(tcx, body) + .iterate_to_fixpoint() + .into_results_cursor(body); + + // Map for each local to the pointee. + let mut targets = IndexVec::from_elem(Value::Unknown, &body.local_decls); + // Set of locals for which we will remove their storage statement. This is useful for + // reborrowed references. + let mut storage_to_remove = BitSet::new_empty(body.local_decls.len()); + + let fully_replacable_locals = fully_replacable_locals(ssa); + + // Returns true iff we can use `place` as a pointee. + // + // Note that we only need to verify that there is a single `StorageLive` statement, and we do + // not need to verify that it dominates all uses of that local. + // + // Consider the three statements: + // SL : StorageLive(a) + // DEF: b = &raw? mut? a + // USE: stuff that uses *b + // + // First, we recall that DEF is checked to dominate USE. Now imagine for the sake of + // contradiction there is a DEF -> SL -> USE path. Consider two cases: + // + // - DEF dominates SL. We always have UB the first time control flow reaches DEF, + // because the storage of `a` is dead. Since DEF dominates USE, that means we cannot + // reach USE and so our optimization is ok. + // + // - DEF does not dominate SL. Then there is a `START_BLOCK -> SL` path not including DEF. + // But we can extend this path to USE, meaning there is also a `START_BLOCK -> USE` path not + // including DEF. This violates the DEF dominates USE condition, and so is impossible. + let is_constant_place = |place: Place<'_>| { + // We only allow `Deref` as the first projection, to avoid surprises. + if place.projection.first() == Some(&PlaceElem::Deref) { + // `place == (*some_local).xxx`, it is constant only if `some_local` is constant. + // We approximate constness using SSAness. + ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset) + } else { + storage_live.has_single_storage(place.local) + && place.projection[..].iter().all(PlaceElem::is_stable_offset) + } + }; + + let mut can_perform_opt = |target: Place<'tcx>, loc: Location| { + if target.projection.first() == Some(&PlaceElem::Deref) { + // We are creating a reborrow. As `place.local` is a reference, removing the storage + // statements should not make it much harder for LLVM to optimize. + storage_to_remove.insert(target.local); + true + } else { + // This is a proper dereference. We can only allow it if `target` is live. + maybe_dead.seek_after_primary_effect(loc); + let maybe_dead = maybe_dead.contains(target.local); + !maybe_dead + } + }; + + for (local, rvalue, location) in ssa.assignments(body) { + debug!(?local); + + // Only visit if we have something to do. + let Value::Unknown = targets[local] else { bug!() }; + + let ty = body.local_decls[local].ty; + + // If this is not a reference or pointer, do nothing. + if !ty.is_any_ptr() { + debug!("not a reference or pointer"); + continue; + } + + // Whether the current local is subject to the uniqueness rule. + let needs_unique = ty.is_mutable_ptr(); + + // If this a mutable reference that we cannot fully replace, mark it as unknown. + if needs_unique && !fully_replacable_locals.contains(local) { + debug!("not fully replaceable"); + continue; + } + + debug!(?rvalue); + match rvalue { + // This is a copy, just use the value we have in store for the previous one. + // As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should + // have been visited before. + Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) + | Rvalue::CopyForDeref(place) => { + if let Some(rhs) = place.as_local() && ssa.is_ssa(rhs) { + let target = targets[rhs]; + // Only see through immutable reference and pointers, as we do not know yet if + // mutable references are fully replaced. + if !needs_unique && matches!(target, Value::Pointer(..)) { + targets[local] = target; + } else { + targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), needs_unique); + } + } + } + Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { + let mut place = *place; + // Try to see through `place` in order to collapse reborrow chains. + if place.projection.first() == Some(&PlaceElem::Deref) + && let Value::Pointer(target, inner_needs_unique) = targets[place.local] + // Only see through immutable reference and pointers, as we do not know yet if + // mutable references are fully replaced. + && !inner_needs_unique + // Only collapse chain if the pointee is definitely live. + && can_perform_opt(target, location) + { + place = target.project_deeper(&place.projection[1..], tcx); + } + assert_ne!(place.local, local); + if is_constant_place(place) { + targets[local] = Value::Pointer(place, needs_unique); + } + } + // We do not know what to do, so keep as not-a-pointer. + _ => {} + } + } + + debug!(?targets); + + let mut finder = ReplacementFinder { + targets: &mut targets, + can_perform_opt, + allowed_replacements: FxHashSet::default(), + }; + let reachable_blocks = traversal::reachable_as_bitset(body); + for (bb, bbdata) in body.basic_blocks.iter_enumerated() { + // Only visit reachable blocks as we rely on dataflow. + if reachable_blocks.contains(bb) { + finder.visit_basic_block_data(bb, bbdata); + } + } + + let allowed_replacements = finder.allowed_replacements; + return Replacer { + tcx, + targets, + storage_to_remove, + allowed_replacements, + fully_replacable_locals, + any_replacement: false, + }; + + struct ReplacementFinder<'a, 'tcx, F> { + targets: &'a mut IndexVec<Local, Value<'tcx>>, + can_perform_opt: F, + allowed_replacements: FxHashSet<(Local, Location)>, + } + + impl<'tcx, F> Visitor<'tcx> for ReplacementFinder<'_, 'tcx, F> + where + F: FnMut(Place<'tcx>, Location) -> bool, + { + fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) { + if matches!(ctxt, PlaceContext::NonUse(_)) { + // There is no need to check liveness for non-uses. + return; + } + + if place.projection.first() != Some(&PlaceElem::Deref) { + // This is not a dereference, nothing to do. + return; + } + + let mut place = place.as_ref(); + loop { + if let Value::Pointer(target, needs_unique) = self.targets[place.local] { + let perform_opt = (self.can_perform_opt)(target, loc); + debug!(?place, ?target, ?needs_unique, ?perform_opt); + + // This a reborrow chain, recursively allow the replacement. + // + // This also allows to detect cases where `target.local` is not replacable, + // and mark it as such. + if let &[PlaceElem::Deref] = &target.projection[..] { + assert!(perform_opt); + self.allowed_replacements.insert((target.local, loc)); + place.local = target.local; + continue; + } else if perform_opt { + self.allowed_replacements.insert((target.local, loc)); + } else if needs_unique { + // This mutable reference is not fully replacable, so drop it. + self.targets[place.local] = Value::Unknown; + } + } + + break; + } + } + } +} + +/// Compute the set of locals that can be fully replaced. +/// +/// We consider a local to be replacable iff it's only used in a `Deref` projection `*_local` or +/// non-use position (like storage statements and debuginfo). +fn fully_replacable_locals(ssa: &SsaLocals) -> BitSet<Local> { + let mut replacable = BitSet::new_empty(ssa.num_locals()); + + // First pass: for each local, whether its uses can be fully replaced. + for local in ssa.locals() { + if ssa.num_direct_uses(local) == 0 { + replacable.insert(local); + } + } + + // Second pass: a local can only be fully replaced if all its copies can. + ssa.meet_copy_equivalence(&mut replacable); + + replacable +} + +/// Utility to help performing subtitution of `*pattern` by `target`. +struct Replacer<'tcx> { + tcx: TyCtxt<'tcx>, + targets: IndexVec<Local, Value<'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> { + fn tcx(&self) -> TyCtxt<'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; + } + + loop { + if let Value::Pointer(target, _) = self.targets[place.local] { + let perform_opt = matches!(ctxt, PlaceContext::NonUse(_)) + || self.allowed_replacements.contains(&(target.local, loc)); + + if perform_opt { + *place = target.project_deeper(&place.projection[1..], self.tcx); + self.any_replacement = true; + continue; + } + } + + break; + } + } + + fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) { + match stmt.kind { + StatementKind::StorageLive(l) | StatementKind::StorageDead(l) + if self.storage_to_remove.contains(l) => + { + stmt.make_nop(); + } + // Do not remove assignments as they may still be useful for debuginfo. + _ => self.super_statement(stmt, loc), + } + } +} 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_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index ec8d42c1652..2b404efccc7 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -1,3 +1,10 @@ +//! We denote as "SSA" the set of locals that verify the following properties: +//! 1/ They are only assigned-to once, either as a function parameter, or in an assign statement; +//! 2/ This single assignment dominates all uses; +//! +//! As a consequence of rule 2, we consider that borrowed locals are not SSA, even if they are +//! `Freeze`, as we do not track that the assignment dominates all uses of the borrow. + use either::Either; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; @@ -5,7 +12,6 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::{ParamEnv, TyCtxt}; #[derive(Debug)] pub struct SsaLocals { @@ -17,6 +23,9 @@ pub struct SsaLocals { assignment_order: Vec<Local>, /// Copy equivalence classes between locals. See `copy_classes` for documentation. copy_classes: IndexVec<Local, Local>, + /// Number of "direct" uses of each local, ie. uses that are not dereferences. + /// We ignore non-uses (Storage statements, debuginfo). + direct_uses: IndexVec<Local, u32>, } /// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to @@ -26,48 +35,48 @@ struct SmallDominators { inner: Option<Dominators<BasicBlock>>, } -trait DomExt { - fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool; -} - -impl DomExt for Location { - fn dominates(self, other: Location, dominators: &SmallDominators) -> bool { - if self.block == other.block { - self.statement_index <= other.statement_index +impl SmallDominators { + fn dominates(&self, first: Location, second: Location) -> bool { + if first.block == second.block { + first.statement_index <= second.statement_index + } else if let Some(inner) = &self.inner { + inner.dominates(first.block, second.block) } else { - dominators.dominates(self.block, other.block) + first.block < second.block } } -} -impl SmallDominators { - fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool { - if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node } + fn check_dominates(&mut self, set: &mut Set1<LocationExtended>, loc: Location) { + let assign_dominates = match *set { + Set1::Empty | Set1::Many => false, + Set1::One(LocationExtended::Arg) => true, + Set1::One(LocationExtended::Plain(assign)) => { + self.dominates(assign.successor_within_block(), loc) + } + }; + // We are visiting a use that is not dominated by an assignment. + // Either there is a cycle involved, or we are reading for uninitialized local. + // Bail out. + if !assign_dominates { + *set = Set1::Many; + } } } impl SsaLocals { - pub fn new<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - body: &Body<'tcx>, - borrowed_locals: &BitSet<Local>, - ) -> SsaLocals { + pub fn new<'tcx>(body: &Body<'tcx>) -> SsaLocals { let assignment_order = Vec::with_capacity(body.local_decls.len()); let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls); let dominators = if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None }; let dominators = SmallDominators { inner: dominators }; - let mut visitor = SsaVisitor { assignments, assignment_order, dominators }; - for (local, decl) in body.local_decls.iter_enumerated() { - if matches!(body.local_kind(local), LocalKind::Arg) { - visitor.assignments[local] = Set1::One(LocationExtended::Arg); - } - if borrowed_locals.contains(local) && !decl.ty.is_freeze(tcx, param_env) { - visitor.assignments[local] = Set1::Many; - } + let direct_uses = IndexVec::from_elem(0, &body.local_decls); + let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses }; + + for local in body.args_iter() { + visitor.assignments[local] = Set1::One(LocationExtended::Arg); } if body.basic_blocks.len() > 2 { @@ -85,36 +94,52 @@ impl SsaLocals { } debug!(?visitor.assignments); + debug!(?visitor.direct_uses); visitor .assignment_order .retain(|&local| matches!(visitor.assignments[local], Set1::One(_))); debug!(?visitor.assignment_order); - let copy_classes = compute_copy_classes(&visitor, body); - - SsaLocals { + let mut ssa = SsaLocals { assignments: visitor.assignments, assignment_order: visitor.assignment_order, - copy_classes, - } + direct_uses: visitor.direct_uses, + // This is filled by `compute_copy_classes`. + copy_classes: IndexVec::default(), + }; + compute_copy_classes(&mut ssa, body); + ssa + } + + pub fn num_locals(&self) -> usize { + self.assignments.len() + } + + pub fn locals(&self) -> impl Iterator<Item = Local> { + self.assignments.indices() } pub fn is_ssa(&self, local: Local) -> bool { matches!(self.assignments[local], Set1::One(_)) } + /// Return the number of uses if a local that are not "Deref". + pub fn num_direct_uses(&self, local: Local) -> u32 { + self.direct_uses[local] + } + pub fn assignments<'a, 'tcx>( &'a self, body: &'a Body<'tcx>, - ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>)> + 'a { + ) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a { self.assignment_order.iter().filter_map(|&local| { if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] { // `loc` must point to a direct assignment to `local`. let Either::Left(stmt) = body.stmt_at(loc) else { bug!() }; let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() }; assert_eq!(target.as_local(), Some(local)); - Some((local, rvalue)) + Some((local, rvalue, loc)) } else { None } @@ -177,44 +202,29 @@ struct SsaVisitor { dominators: SmallDominators, assignments: IndexVec<Local, Set1<LocationExtended>>, assignment_order: Vec<Local>, -} - -impl SsaVisitor { - fn check_assignment_dominates(&mut self, local: Local, loc: Location) { - let set = &mut self.assignments[local]; - let assign_dominates = match *set { - Set1::Empty | Set1::Many => false, - Set1::One(LocationExtended::Arg) => true, - Set1::One(LocationExtended::Plain(assign)) => { - assign.successor_within_block().dominates(loc, &self.dominators) - } - }; - // We are visiting a use that is not dominated by an assignment. - // Either there is a cycle involved, or we are reading for uninitialized local. - // Bail out. - if !assign_dominates { - *set = Set1::Many; - } - } + direct_uses: IndexVec<Local, u32>, } impl<'tcx> Visitor<'tcx> for SsaVisitor { fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) { match ctxt { - PlaceContext::MutatingUse(MutatingUseContext::Store) => { - self.assignments[local].insert(LocationExtended::Plain(loc)); - if let Set1::One(_) = self.assignments[local] { - // Only record if SSA-like, to avoid growing the vector needlessly. - self.assignment_order.push(local); - } - } + PlaceContext::MutatingUse(MutatingUseContext::Projection) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(), // Anything can happen with raw pointers, so remove them. - PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) - | PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many, - // Immutable borrows are taken into account in `SsaLocals::new` by - // removing non-freeze locals. + // We do not verify that all uses of the borrow dominate the assignment to `local`, + // so we have to remove them too. + PlaceContext::NonMutatingUse( + NonMutatingUseContext::SharedBorrow + | NonMutatingUseContext::ShallowBorrow + | NonMutatingUseContext::UniqueBorrow + | NonMutatingUseContext::AddressOf, + ) + | PlaceContext::MutatingUse(_) => { + self.assignments[local] = Set1::Many; + } PlaceContext::NonMutatingUse(_) => { - self.check_assignment_dominates(local, loc); + self.dominators.check_dominates(&mut self.assignments[local], loc); + self.direct_uses[local] += 1; } PlaceContext::NonUse(_) => {} } @@ -224,58 +234,113 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor { if place.projection.first() == Some(&PlaceElem::Deref) { // Do not do anything for storage statements and debuginfo. if ctxt.is_use() { - // A use through a `deref` only reads from the local, and cannot write to it. - let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection); + // Only change the context if it is a real use, not a "use" in debuginfo. + let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy); self.visit_projection(place.as_ref(), new_ctxt, loc); - self.check_assignment_dominates(place.local, loc); + self.dominators.check_dominates(&mut self.assignments[place.local], loc); } return; + } else { + self.visit_projection(place.as_ref(), ctxt, loc); + self.visit_local(place.local, ctxt, loc); } - self.super_place(place, ctxt, loc); + } + + fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, loc: Location) { + if let Some(local) = place.as_local() { + self.assignments[local].insert(LocationExtended::Plain(loc)); + if let Set1::One(_) = self.assignments[local] { + // Only record if SSA-like, to avoid growing the vector needlessly. + self.assignment_order.push(local); + } + } else { + self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc); + } + self.visit_rvalue(rvalue, loc); } } #[instrument(level = "trace", skip(ssa, body))] -fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Local> { +fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { + let mut direct_uses = std::mem::take(&mut ssa.direct_uses); let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len()); - for &local in &ssa.assignment_order { - debug!(?local); - - if local == RETURN_PLACE { - // `_0` is special, we cannot rename it. - continue; - } - - // This is not SSA: mark that we don't know the value. - debug!(assignments = ?ssa.assignments[local]); - let Set1::One(LocationExtended::Plain(loc)) = ssa.assignments[local] else { continue }; - - // `loc` must point to a direct assignment to `local`. - let Either::Left(stmt) = body.stmt_at(loc) else { bug!() }; - let Some((_target, rvalue)) = stmt.kind.as_assign() else { bug!() }; - assert_eq!(_target.as_local(), Some(local)); - + for (local, rvalue, _) in ssa.assignments(body) { let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place)) = rvalue else { continue }; let Some(rhs) = place.as_local() else { continue }; - let Set1::One(_) = ssa.assignments[rhs] else { continue }; + if !ssa.is_ssa(rhs) { + continue; + } // We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been // visited before `local`, and we just have to copy the representing local. - copies[local] = copies[rhs]; + let head = copies[rhs]; + + if local == RETURN_PLACE { + // `_0` is special, we cannot rename it. Instead, rename the class of `rhs` to + // `RETURN_PLACE`. This is only possible if the class head is a temporary, not an + // argument. + if body.local_kind(head) != LocalKind::Temp { + continue; + } + for h in copies.iter_mut() { + if *h == head { + *h = RETURN_PLACE; + } + } + } else { + copies[local] = head; + } + direct_uses[rhs] -= 1; } debug!(?copies); + debug!(?direct_uses); // Invariant: `copies` must point to the head of an equivalence class. #[cfg(debug_assertions)] for &head in copies.iter() { assert_eq!(copies[head], head); } + debug_assert_eq!(copies[RETURN_PLACE], RETURN_PLACE); + + ssa.direct_uses = direct_uses; + ssa.copy_classes = copies; +} + +#[derive(Debug)] +pub(crate) struct StorageLiveLocals { + /// Set of "StorageLive" statements for each local. + storage_live: IndexVec<Local, Set1<LocationExtended>>, +} + +impl StorageLiveLocals { + pub(crate) fn new( + body: &Body<'_>, + always_storage_live_locals: &BitSet<Local>, + ) -> StorageLiveLocals { + let mut storage_live = IndexVec::from_elem(Set1::Empty, &body.local_decls); + for local in always_storage_live_locals.iter() { + storage_live[local] = Set1::One(LocationExtended::Arg); + } + for (block, bbdata) in body.basic_blocks.iter_enumerated() { + for (statement_index, statement) in bbdata.statements.iter().enumerate() { + if let StatementKind::StorageLive(local) = statement.kind { + storage_live[local] + .insert(LocationExtended::Plain(Location { block, statement_index })); + } + } + } + debug!(?storage_live); + StorageLiveLocals { storage_live } + } - copies + #[inline] + pub(crate) fn has_single_storage(&self, local: Local) -> bool { + matches!(self.storage_live[local], Set1::One(_)) + } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 55c937b305a..35b154b7b34 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -185,9 +185,9 @@ use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; +use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 7253acf61e6..ecc50c3f664 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -12,9 +12,9 @@ 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, TyCtxtAt}; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::query::{Providers, 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 cd296dca133..2d0f466e236 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -257,6 +257,10 @@ parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are inva .tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access .tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information +parse_expected_builtin_ident = expected identifier after `builtin #` + +parse_unknown_builtin_construct = unknown `builtin #` construct `{$name}` + parse_non_string_abi_literal = non-string ABI literal .suggestion = specify the ABI with a string literal @@ -339,6 +343,7 @@ parse_expected_identifier = expected identifier parse_sugg_escape_identifier = escape `{$ident_name}` to use it as an identifier parse_sugg_remove_comma = remove this comma +parse_sugg_add_let_for_stmt = you might have meant to introduce a new binding parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}` parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}` @@ -473,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 010a13aefa4..84494eab855 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -907,6 +907,18 @@ pub(crate) struct SuggRemoveComma { } #[derive(Subdiagnostic)] +#[suggestion( + parse_sugg_add_let_for_stmt, + style = "verbose", + applicability = "maybe-incorrect", + code = "let " +)] +pub(crate) struct SuggAddMissingLetStmt { + #[primary_span] + pub span: Span, +} + +#[derive(Subdiagnostic)] pub(crate) enum ExpectedIdentifierFound { #[label(parse_expected_identifier_found_reserved_identifier)] ReservedIdentifier(#[primary_span] Span), @@ -1508,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] @@ -2644,3 +2666,18 @@ pub(crate) struct MalformedCfgAttr { pub span: Span, pub sugg: &'static str, } + +#[derive(Diagnostic)] +#[diag(parse_unknown_builtin_construct)] +pub(crate) struct UnknownBuiltinConstruct { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(parse_expected_builtin_ident)] +pub(crate) struct ExpectedBuiltinIdent { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 36883bd2172..3002f23da75 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -13,7 +13,7 @@ use crate::errors::{ IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, - StructLiteralNeedingParensSugg, SuggEscapeIdentifier, SuggRemoveComma, + StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, }; @@ -32,8 +32,8 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, - FatalError, Handler, IntoDiagnostic, MultiSpan, PResult, + pluralize, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, + ErrorGuaranteed, FatalError, Handler, IntoDiagnostic, MultiSpan, PResult, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -1006,6 +1006,31 @@ impl<'a> Parser<'a> { Err(e) } + /// Suggest add the missing `let` before the identifier in stmt + /// `a: Ty = 1` -> `let a: Ty = 1` + pub(super) fn suggest_add_missing_let_for_stmt( + &mut self, + err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>, + ) { + if self.token == token::Colon { + let prev_span = self.prev_token.span.shrink_to_lo(); + let snapshot = self.create_snapshot_for_diagnostic(); + self.bump(); + match self.parse_ty() { + Ok(_) => { + if self.token == token::Eq { + let sugg = SuggAddMissingLetStmt { span: prev_span }; + sugg.add_to_diagnostic(err); + } + } + Err(e) => { + e.cancel(); + } + } + self.restore_snapshot(snapshot); + } + } + /// Check to see if a pair of chained operators looks like an attempt at chained comparison, /// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or /// parenthesising the leftmost comparison. diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 018eddea4b0..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 @@ -1300,6 +1304,8 @@ impl<'a> Parser<'a> { }) } else if self.check(&token::OpenDelim(Delimiter::Bracket)) { self.parse_expr_array_or_repeat(Delimiter::Bracket) + } else if self.is_builtin() { + self.parse_expr_builtin() } else if self.check_path() { self.parse_expr_path_start() } else if self.check_keyword(kw::Move) @@ -1766,6 +1772,61 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr) } + /// Parse `builtin # ident(args,*)`. + fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> { + self.parse_builtin(|this, lo, ident| { + if ident.name == sym::offset_of { + return Ok(Some(this.parse_expr_offset_of(lo)?)); + } + + Ok(None) + }) + } + + pub(crate) fn parse_builtin<T>( + &mut self, + parse: impl FnOnce(&mut Parser<'a>, Span, Ident) -> PResult<'a, Option<T>>, + ) -> PResult<'a, T> { + let lo = self.token.span; + + self.bump(); // `builtin` + self.bump(); // `#` + + let Some((ident, false)) = self.token.ident() else { + let err = errors::ExpectedBuiltinIdent { span: self.token.span } + .into_diagnostic(&self.sess.span_diagnostic); + return Err(err); + }; + self.sess.gated_spans.gate(sym::builtin_syntax, ident.span); + self.bump(); + + self.expect(&TokenKind::OpenDelim(Delimiter::Parenthesis))?; + let ret = if let Some(res) = parse(self, lo, ident)? { + Ok(res) + } else { + let err = errors::UnknownBuiltinConstruct { span: lo.to(ident.span), name: ident.name } + .into_diagnostic(&self.sess.span_diagnostic); + return Err(err); + }; + self.expect(&TokenKind::CloseDelim(Delimiter::Parenthesis))?; + + ret + } + + pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> { + let container = self.parse_ty()?; + self.expect(&TokenKind::Comma)?; + + let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false }; + let (fields, _trailing, _recovered) = self.parse_seq_to_before_end( + &TokenKind::CloseDelim(Delimiter::Parenthesis), + seq_sep, + Parser::parse_field_name, + )?; + let span = lo.to(self.token.span); + Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into()))) + } + /// Returns a string literal if the next token is a string literal. /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind, /// and returns `None` if the next token is not literal at all. @@ -2835,6 +2896,10 @@ impl<'a> Parser<'a> { }) } + pub(crate) fn is_builtin(&self) -> bool { + self.token.is_keyword(kw::Builtin) && self.look_ahead(1, |t| *t == token::Pound) + } + /// Parses a `try {...}` expression (`try` token already eaten). fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> { let (attrs, body) = self.parse_inner_attrs_and_block()?; 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 6ca88200dc5..dc18d400f1e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -265,6 +265,9 @@ impl<'a> Parser<'a> { // UNION ITEM self.bump(); // `union` self.parse_item_union()? + } else if self.is_builtin() { + // BUILTIN# ITEM + return self.parse_item_builtin(); } else if self.eat_keyword(kw::Macro) { // MACROS 2.0 ITEM self.parse_item_decl_macro(lo)? @@ -434,6 +437,11 @@ impl<'a> Parser<'a> { } } + fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> { + // To be expanded + return Ok(None); + } + /// Parses an item macro, e.g., `item!();`. fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> { let path = self.parse_path(PathStyle::Mod)?; // `foo::bar` @@ -595,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) } }; @@ -1262,6 +1284,7 @@ impl<'a> Parser<'a> { } } + let prev_span = self.prev_token.span; let id = self.parse_ident()?; let mut generics = self.parse_generics()?; generics.where_clause = self.parse_where_clause()?; @@ -1273,10 +1296,28 @@ impl<'a> Parser<'a> { (thin_vec![], false) } else { self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err( - |mut e| { - e.span_label(id.span, "while parsing this enum"); + |mut err| { + err.span_label(id.span, "while parsing this enum"); + if self.token == token::Colon { + let snapshot = self.create_snapshot_for_diagnostic(); + self.bump(); + match self.parse_ty() { + Ok(_) => { + err.span_suggestion_verbose( + prev_span, + "perhaps you meant to use `struct` here", + "struct".to_string(), + Applicability::MaybeIncorrect, + ); + } + Err(e) => { + e.cancel(); + } + } + self.restore_snapshot(snapshot); + } self.recover_stmt(); - e + err }, )? }; diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 1c17de337e8..03279124177 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -90,7 +90,11 @@ impl<'a> Parser<'a> { attrs, errors::InvalidVariableDeclarationSub::UseLetNotVar, )? - } else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() { + } else if self.check_path() + && !self.token.is_qpath_start() + && !self.is_path_start_item() + && !self.is_builtin() + { // We have avoided contextual keywords like `union`, items with `crate` visibility, // or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something // that starts like a path (1 token), but it fact not a path. @@ -99,7 +103,13 @@ impl<'a> Parser<'a> { ForceCollect::Yes => { self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))? } - ForceCollect::No => self.parse_stmt_path_start(lo, attrs)?, + ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) { + Ok(stmt) => stmt, + Err(mut err) => { + self.suggest_add_missing_let_for_stmt(&mut err); + return Err(err); + } + }, } } else if let Some(item) = self.parse_item_common( attrs.clone(), @@ -555,7 +565,6 @@ impl<'a> Parser<'a> { if self.token == token::Colon { // if next token is following a colon, it's likely a path // and we can suggest a path separator - let ident_span = self.prev_token.span; self.bump(); if self.token.span.lo() == self.prev_token.span.hi() { err.span_suggestion_verbose( @@ -565,14 +574,6 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ); } - if self.look_ahead(1, |token| token == &token::Eq) { - err.span_suggestion_verbose( - ident_span.shrink_to_lo(), - "you might have meant to introduce a new binding", - "let ", - Applicability::MaybeIncorrect, - ); - } if self.sess.unstable_features.is_nightly_build() { // FIXME(Nilstrieb): Remove this again after a few months. err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>"); 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 b738ce35ada..7b39cb0a068 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -26,8 +26,8 @@ use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; 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}; @@ -243,6 +243,39 @@ where // This will also visit substs if necessary, so we don't need to recurse. return self.visit_projection_ty(proj); } + ty::Alias(ty::Inherent, data) => { + if self.def_id_visitor.skip_assoc_tys() { + // Visitors searching for minimal visibility/reachability want to + // conservatively approximate associated types like `Type::Alias` + // as visible/reachable even if `Type` is private. + // Ideally, associated types should be substituted in the same way as + // free type aliases, but this isn't done yet. + return ControlFlow::Continue(()); + } + + self.def_id_visitor.visit_def_id( + data.def_id, + "associated type", + &LazyDefPathStr { def_id: data.def_id, tcx }, + )?; + + struct LazyDefPathStr<'tcx> { + def_id: DefId, + tcx: TyCtxt<'tcx>, + } + impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.tcx.def_path_str(self.def_id)) + } + } + + // This will also visit substs if necessary, so we don't need to recurse. + return if self.def_id_visitor.shallow() { + ControlFlow::Continue(()) + } else { + data.substs.iter().try_for_each(|subst| subst.visit_with(self)) + }; + } ty::Dynamic(predicates, ..) => { // All traits in the list are considered the "primary" part of the type // and are visited by shallow visitors. @@ -706,7 +739,10 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } hir::ItemKind::Impl(ref impl_) => { for impl_item_ref in impl_.items { - self.update(impl_item_ref.id.owner_id.def_id, item_ev, Level::Direct); + 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) => { 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..b76734dd072 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,28 @@ 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::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns}; 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::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; +use rustc_query_system::ich::StableHashingContext; +use rustc_query_system::query::{ + get_query_incr, get_query_non_incr, HashResult, QueryCache, QueryConfig, QueryInfo, QueryMap, + QueryMode, QueryState, +}; +use rustc_query_system::HandleCycleError; use rustc_query_system::Value; use rustc_span::Span; @@ -32,31 +45,183 @@ 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>>, + incremental: bool, +) -> QuerySystem<'tcx> { + QuerySystem { + states: Default::default(), + arenas: Default::default(), + caches: Default::default(), + dynamic_queries: dynamic_queries(), + on_disk_cache, + fns: QuerySystemFns { + engine: engine(incremental), + 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..79d8abc4b69 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) }), } } @@ -478,7 +494,7 @@ macro_rules! define_queries { ( $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - mod get_query { + mod get_query_incr { use super::*; $( @@ -490,8 +506,8 @@ macro_rules! define_queries { key: query_keys::$name<'tcx>, mode: QueryMode, ) -> Option<Erase<query_values::$name<'tcx>>> { - get_query( - queries::$name::default(), + get_query_incr( + queries::$name::config(tcx), QueryCtxt::new(tcx), span, key, @@ -501,9 +517,37 @@ macro_rules! define_queries { )* } - pub(crate) fn engine() -> QueryEngine { - QueryEngine { - $($name: get_query::$name,)* + mod get_query_non_incr { + use super::*; + + $( + #[inline(always)] + #[tracing::instrument(level = "trace", skip(tcx))] + pub(super) fn $name<'tcx>( + tcx: TyCtxt<'tcx>, + span: Span, + key: query_keys::$name<'tcx>, + __mode: QueryMode, + ) -> Option<Erase<query_values::$name<'tcx>>> { + Some(get_query_non_incr( + queries::$name::config(tcx), + QueryCtxt::new(tcx), + span, + key, + )) + } + )* + } + + pub(crate) fn engine(incremental: bool) -> QueryEngine { + if incremental { + QueryEngine { + $($name: get_query_incr::$name,)* + } + } else { + QueryEngine { + $($name: get_query_non_incr::$name,)* + } } } @@ -519,146 +563,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 { @@ -727,9 +716,9 @@ macro_rules! define_queries { mod query_structs { use super::*; - use rustc_middle::ty::query::QueryStruct; - use rustc_middle::ty::query::QueryKeyStringCache; + use rustc_middle::query::plumbing::{QueryKeyStringCache, QueryStruct}; 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 +763,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_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 7d9306f8087..e042ee62dfe 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -2,7 +2,7 @@ use measureme::{StringComponent, StringId}; use rustc_data_structures::profiling::SelfProfiler; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; -use rustc_middle::ty::query::QueryKeyStringCache; +use rustc_middle::query::plumbing::QueryKeyStringCache; use rustc_middle::ty::TyCtxt; use rustc_query_system::query::QueryCache; use std::fmt::Debug; 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..dbfe62ae6e9 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -312,7 +312,7 @@ where } #[inline(never)] -fn try_execute_query<Q, Qcx>( +fn try_execute_query<Q, Qcx, const INCR: bool>( query: Q, qcx: Qcx, span: Span, @@ -355,7 +355,7 @@ where // Drop the lock before we start executing the query drop(state_lock); - execute_job(query, qcx, state, key, id, dep_node) + execute_job::<_, _, INCR>(query, qcx, state, key, id, dep_node) } Entry::Occupied(mut entry) => { match entry.get_mut() { @@ -383,7 +383,7 @@ where } #[inline(always)] -fn execute_job<Q, Qcx>( +fn execute_job<Q, Qcx, const INCR: bool>( query: Q, qcx: Qcx, state: &QueryState<Q::Key, Qcx::DepKind>, @@ -398,9 +398,19 @@ where // Use `JobOwner` so the query will be poisoned if executing it panics. let job_owner = JobOwner { state, key }; - let (result, dep_node_index) = match qcx.dep_context().dep_graph().data() { - None => execute_job_non_incr(query, qcx, key, id), - Some(data) => execute_job_incr(query, qcx, data, key, dep_node, id), + debug_assert_eq!(qcx.dep_context().dep_graph().is_fully_enabled(), INCR); + + let (result, dep_node_index) = if INCR { + execute_job_incr( + query, + qcx, + qcx.dep_context().dep_graph().data().unwrap(), + key, + dep_node, + id, + ) + } else { + execute_job_non_incr(query, qcx, key, id) }; let cache = query.query_cache(qcx); @@ -564,59 +574,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!( @@ -799,7 +794,18 @@ pub enum QueryMode { } #[inline(always)] -pub fn get_query<Q, Qcx>( +pub fn get_query_non_incr<Q, Qcx>(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value +where + Q: QueryConfig<Qcx>, + Qcx: QueryContext, +{ + debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); + + ensure_sufficient_stack(|| try_execute_query::<Q, Qcx, false>(query, qcx, span, key, None).0) +} + +#[inline(always)] +pub fn get_query_incr<Q, Qcx>( query: Q, qcx: Qcx, span: Span, @@ -810,6 +816,8 @@ where Q: QueryConfig<Qcx>, Qcx: QueryContext, { + debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled()); + let dep_node = if let QueryMode::Ensure { check_cache } = mode { let (must_run, dep_node) = ensure_must_run(query, qcx, &key, check_cache); if !must_run { @@ -820,8 +828,9 @@ where None }; - let (result, dep_node_index) = - ensure_sufficient_stack(|| try_execute_query(query, qcx, span, key, dep_node)); + let (result, dep_node_index) = ensure_sufficient_stack(|| { + try_execute_query::<_, _, true>(query, qcx, span, key, dep_node) + }); if let Some(dep_node_index) = dep_node_index { qcx.dep_context().dep_graph().read_index(dep_node_index) } @@ -846,5 +855,7 @@ pub fn force_query<Q, Qcx>( debug_assert!(!query.anon()); - ensure_sufficient_stack(|| try_execute_query(query, qcx, DUMMY_SP, key, Some(dep_node))); + ensure_sufficient_stack(|| { + try_execute_query::<_, _, true>(query, qcx, DUMMY_SP, key, Some(dep_node)) + }); } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 32409499047..345255c4c69 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -145,6 +145,15 @@ resolve_param_in_ty_of_const_param = the type of const parameters must not depend on other generic parameters .label = the type must not depend on the parameter `{$name}` +resolve_type_param_in_ty_of_const_param = + type parameters may not be used in the type of const parameters + +resolve_const_param_in_ty_of_const_param = + const parameters may not be used in the type of const parameters + +resolve_lifetime_param_in_ty_of_const_param = + lifetime parameters may not be used in the type of const parameters + resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults .label = `Self` in generic parameter default @@ -156,12 +165,15 @@ resolve_param_in_non_trivial_anon_const = resolve_param_in_non_trivial_anon_const_help = use `#![feature(generic_const_exprs)]` to allow generic const expressions -resolve_param_in_non_trivial_anon_const_sub_type = +resolve_type_param_in_non_trivial_anon_const = type parameters may not be used in const expressions -resolve_param_in_non_trivial_anon_const_sub_non_type = +resolve_const_param_in_non_trivial_anon_const = const parameters may only be used as standalone arguments, i.e. `{$name}` +resolve_lifetime_param_in_non_trivial_anon_const = + lifetime parameters may not be used in const expressions + resolve_unreachable_label = use of unreachable label `{$name}` .label = unreachable label `{$name}` @@ -187,6 +199,10 @@ resolve_invalid_asm_sym = .label = is a local variable .help = `sym` operands must refer to either a function or a static +resolve_lowercase_self = + attempt to use a non-constant value in a constant + .suggestion = try using `Self` + resolve_trait_impl_duplicate = duplicate definitions with name `{$name}`: .label = duplicate definition @@ -233,3 +249,16 @@ resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern resolve_accessible_unsure = not sure whether the path is accessible or not .note = the type may have associated items, but we are currently not checking them + +resolve_param_in_enum_discriminant = + generic parameters may not be used in enum discriminant values + .label = cannot perform const operation using `{$name}` + +resolve_type_param_in_enum_discriminant = + type parameters may not be used in enum discriminant values + +resolve_const_param_in_enum_discriminant = + const parameters may not be used in enum discriminant values + +resolve_lifetime_param_in_enum_discriminant = + lifetime parameters may not be used in enum discriminant values diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index fae7d549592..59eda9db97f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -550,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let sm = self.tcx.sess.source_map(); let def_id = match outer_res { - Res::SelfTyParam { .. } | Res::SelfCtor(_) => { + Res::SelfTyParam { .. } => { err.span_label(span, "can't use `Self` here"); return err; } @@ -864,18 +864,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::ForwardDeclaredGenericParam => { self.tcx.sess.create_err(errs::ForwardDeclaredGenericParam { span }) } - ResolutionError::ParamInTyOfConstParam(name) => { - self.tcx.sess.create_err(errs::ParamInTyOfConstParam { span, name }) - } - ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => { + ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self + .tcx + .sess + .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }), + ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => { self.tcx.sess.create_err(errs::ParamInNonTrivialAnonConst { span, name, - sub_is_type: if is_type { - errs::ParamInNonTrivialAnonConstIsType::AType - } else { - errs::ParamInNonTrivialAnonConstIsType::NotAType { name } - }, + param_kind: is_type, help: self .tcx .sess @@ -883,6 +880,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .then_some(errs::ParamInNonTrivialAnonConstHelp), }) } + ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self + .tcx + .sess + .create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }), ResolutionError::SelfInGenericParamDefault => { self.tcx.sess.create_err(errs::SelfInGenericParamDefault { span }) } @@ -947,6 +948,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::InvalidAsmSym => { self.tcx.sess.create_err(errs::InvalidAsmSym { span }) } + ResolutionError::LowercaseSelf => { + self.tcx.sess.create_err(errs::LowercaseSelf { span }) + } } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 4f9f1c7e856..2ab55f12637 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -326,6 +326,18 @@ pub(crate) struct ParamInTyOfConstParam { #[label] pub(crate) span: Span, pub(crate) name: Symbol, + #[subdiagnostic] + pub(crate) param_kind: Option<ParamKindInTyOfConstParam>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum ParamKindInTyOfConstParam { + #[note(resolve_type_param_in_ty_of_const_param)] + Type, + #[note(resolve_const_param_in_ty_of_const_param)] + Const, + #[note(resolve_lifetime_param_in_ty_of_const_param)] + Lifetime, } #[derive(Diagnostic)] @@ -344,7 +356,7 @@ pub(crate) struct ParamInNonTrivialAnonConst { pub(crate) span: Span, pub(crate) name: Symbol, #[subdiagnostic] - pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType, + pub(crate) param_kind: ParamKindInNonTrivialAnonConst, #[subdiagnostic] pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>, } @@ -354,11 +366,13 @@ pub(crate) struct ParamInNonTrivialAnonConst { pub(crate) struct ParamInNonTrivialAnonConstHelp; #[derive(Subdiagnostic)] -pub(crate) enum ParamInNonTrivialAnonConstIsType { - #[note(resolve_param_in_non_trivial_anon_const_sub_type)] - AType, - #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)] - NotAType { name: Symbol }, +pub(crate) enum ParamKindInNonTrivialAnonConst { + #[note(resolve_type_param_in_non_trivial_anon_const)] + Type, + #[help(resolve_const_param_in_non_trivial_anon_const)] + Const { name: Symbol }, + #[note(resolve_lifetime_param_in_non_trivial_anon_const)] + Lifetime, } #[derive(Diagnostic)] @@ -429,6 +443,14 @@ pub(crate) struct InvalidAsmSym { } #[derive(Diagnostic)] +#[diag(resolve_lowercase_self)] +pub(crate) struct LowercaseSelf { + #[primary_span] + #[suggestion(code = "Self", applicability = "maybe-incorrect", style = "short")] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] #[diag(resolve_trait_impl_duplicate, code = "E0201")] pub(crate) struct TraitImplDuplicate { #[primary_span] @@ -539,3 +561,24 @@ pub(crate) struct CfgAccessibleUnsure { #[primary_span] pub(crate) span: Span, } + +#[derive(Diagnostic)] +#[diag(resolve_param_in_enum_discriminant)] +pub(crate) struct ParamInEnumDiscriminant { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + #[subdiagnostic] + pub(crate) param_kind: ParamKindInEnumDiscriminant, +} + +#[derive(Subdiagnostic)] +pub(crate) enum ParamKindInEnumDiscriminant { + #[note(resolve_type_param_in_enum_discriminant)] + Type, + #[note(resolve_const_param_in_enum_discriminant)] + Const, + #[note(resolve_lifetime_param_in_enum_discriminant)] + Lifetime, +} diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2db1d83d4fd..f065c4ddd2e 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -13,8 +13,9 @@ use rustc_span::{Span, DUMMY_SP}; use std::ptr; +use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use crate::late::{ - ConstantHasGenerics, ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind, + ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind, }; use crate::macros::{sub_namespace_match, MacroRulesScope}; use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize}; @@ -1125,35 +1126,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { RibKind::ConstantItem(_, item) => { // Still doesn't deal with upvars if let Some(span) = finalize { - let (span, resolution_error) = - if let Some((ident, constant_item_kind)) = item { - let kind_str = match constant_item_kind { - ConstantItemKind::Const => "const", - ConstantItemKind::Static => "static", - }; - ( - span, - AttemptToUseNonConstantValueInConstant( - ident, "let", kind_str, - ), - ) - } else { - ( - rib_ident.span, - AttemptToUseNonConstantValueInConstant( - original_rib_ident_def, - "const", - "let", - ), - ) - }; + let (span, resolution_error) = match item { + None if rib_ident.as_str() == "self" => (span, LowercaseSelf), + None => ( + rib_ident.span, + AttemptToUseNonConstantValueInConstant( + original_rib_ident_def, + "const", + "let", + ), + ), + Some((ident, kind)) => ( + span, + AttemptToUseNonConstantValueInConstant( + ident, + "let", + kind.as_str(), + ), + ), + }; self.report_error(span, resolution_error); } return Res::Err; } RibKind::ConstParamTy => { if let Some(span) = finalize { - self.report_error(span, ParamInTyOfConstParam(rib_ident.name)); + self.report_error( + span, + ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: None, + }, + ); } return Res::Err; } @@ -1170,10 +1174,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return Res::Err; } } - Res::Def(DefKind::TyParam, _) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } - | Res::SelfCtor(_) => { + Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { for rib in ribs { let has_generic_params: HasGenericParams = match rib.kind { RibKind::Normal @@ -1188,11 +1189,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } RibKind::ConstantItem(trivial, _) => { - let features = self.tcx.sess.features_untracked(); - // HACK(min_const_generics): We currently only allow `N` or `{ N }`. - if !(trivial == ConstantHasGenerics::Yes - || features.generic_const_exprs) - { + if let ConstantHasGenerics::No(cause) = trivial { // HACK(min_const_generics): If we encounter `Self` in an anonymous // constant we can't easily tell if it's generic at this stage, so // we instead remember this and then enforce the self type to be @@ -1210,13 +1207,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } else { if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInNonTrivialAnonConst { - name: rib_ident.name, - is_type: true, - }, - ); + let error = match cause { + NoConstantGenericsReason::IsEnumDiscriminant => { + ResolutionError::ParamInEnumDiscriminant { + name: rib_ident.name, + param_kind: ParamKindInEnumDiscriminant::Type, + } + } + NoConstantGenericsReason::NonTrivialConstArg => { + ResolutionError::ParamInNonTrivialAnonConst { + name: rib_ident.name, + param_kind: + ParamKindInNonTrivialAnonConst::Type, + } + } + }; + self.report_error(span, error); self.tcx.sess.delay_span_bug(span, CG_BUG_STR); } @@ -1233,7 +1239,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(span) = finalize { self.report_error( span, - ResolutionError::ParamInTyOfConstParam(rib_ident.name), + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: Some(errors::ParamKindInTyOfConstParam::Type), + }, ); } return Res::Err; @@ -1264,20 +1273,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | RibKind::ForwardGenericParamBan => continue, RibKind::ConstantItem(trivial, _) => { - let features = self.tcx.sess.features_untracked(); - // HACK(min_const_generics): We currently only allow `N` or `{ N }`. - if !(trivial == ConstantHasGenerics::Yes - || features.generic_const_exprs) - { + if let ConstantHasGenerics::No(cause) = trivial { if let Some(span) = finalize { - self.report_error( - span, - ResolutionError::ParamInNonTrivialAnonConst { - name: rib_ident.name, - is_type: false, - }, - ); - self.tcx.sess.delay_span_bug(span, CG_BUG_STR); + let error = match cause { + NoConstantGenericsReason::IsEnumDiscriminant => { + ResolutionError::ParamInEnumDiscriminant { + name: rib_ident.name, + param_kind: ParamKindInEnumDiscriminant::Const, + } + } + NoConstantGenericsReason::NonTrivialConstArg => { + ResolutionError::ParamInNonTrivialAnonConst { + name: rib_ident.name, + param_kind: ParamKindInNonTrivialAnonConst::Const { + name: rib_ident.name, + }, + } + } + }; + self.report_error(span, error); } return Res::Err; @@ -1291,7 +1305,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(span) = finalize { self.report_error( span, - ResolutionError::ParamInTyOfConstParam(rib_ident.name), + ResolutionError::ParamInTyOfConstParam { + name: rib_ident.name, + param_kind: Some(errors::ParamKindInTyOfConstParam::Const), + }, ); } return Res::Err; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6f5d54bcf87..c053ea222a0 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -66,6 +66,15 @@ enum IsRepeatExpr { Yes, } +/// Describes whether an `AnonConst` is a type level const arg or +/// some other form of anon const (i.e. inline consts or enum discriminants) +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum AnonConstKind { + EnumDiscriminant, + InlineConst, + ConstArg(IsRepeatExpr), +} + impl PatternSource { fn descr(self) -> &'static str { match self { @@ -105,7 +114,7 @@ pub(crate) enum HasGenericParams { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum ConstantHasGenerics { Yes, - No, + No(NoConstantGenericsReason), } impl ConstantHasGenerics { @@ -114,12 +123,42 @@ impl ConstantHasGenerics { } } +/// Reason for why an anon const is not allowed to reference generic parameters +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub(crate) enum NoConstantGenericsReason { + /// Const arguments are only allowed to use generic parameters when: + /// - `feature(generic_const_exprs)` is enabled + /// or + /// - the const argument is a sole const generic paramater, i.e. `foo::<{ N }>()` + /// + /// If neither of the above are true then this is used as the cause. + NonTrivialConstArg, + /// Enum discriminants are not allowed to reference generic parameters ever, this + /// is used when an anon const is in the following position: + /// + /// ```rust,compile_fail + /// enum Foo<const N: isize> { + /// Variant = { N }, // this anon const is not allowed to use generics + /// } + /// ``` + IsEnumDiscriminant, +} + #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum ConstantItemKind { Const, Static, } +impl ConstantItemKind { + pub(crate) fn as_str(&self) -> &'static str { + match self { + Self::Const => "const", + Self::Static => "static", + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum RecordPartialRes { Yes, @@ -273,15 +312,18 @@ enum LifetimeRibKind { /// Signal we cannot find which should be the anonymous lifetime. ElisionFailure, - /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const - /// generics. We are disallowing this until we can decide on how we want to handle non-'static - /// lifetimes in const generics. See issue #74052 for discussion. - ConstGeneric, + /// This rib forbids usage of generic parameters inside of const parameter types. + /// + /// While this is desirable to support eventually, it is difficult to do and so is + /// currently forbidden. See rust-lang/project-const-generics#28 for more info. + ConstParamTy, - /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. - /// This function will emit an error if `generic_const_exprs` is not enabled, the body - /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static. - AnonConst, + /// Usage of generic parameters is forbidden in various positions for anon consts: + /// - const arguments when `generic_const_exprs` is not enabled + /// - enum discriminant values + /// + /// This rib emits an error when a lifetime would resolve to a lifetime parameter. + ConcreteAnonConst(NoConstantGenericsReason), /// This rib acts as a barrier to forbid reference to lifetimes of a parent item. Item, @@ -648,13 +690,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.resolve_block(block); self.parent_scope.macro_rules = old_macro_rules; } - fn visit_anon_const(&mut self, constant: &'ast AnonConst) { - // We deal with repeat expressions explicitly in `resolve_expr`. - self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { - this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { - this.resolve_anon_const(constant, IsRepeatExpr::No); - }) - }) + fn visit_anon_const(&mut self, _constant: &'ast AnonConst) { + bug!("encountered anon const without a manual call to `resolve_anon_const`"); } fn visit_expr(&mut self, expr: &'ast Expr) { self.resolve_expr(expr, None); @@ -676,7 +713,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, fn visit_ty(&mut self, ty: &'ast Ty) { let prev = self.diagnostic_metadata.current_trait_object; let prev_ty = self.diagnostic_metadata.current_type_path; - match ty.kind { + match &ty.kind { TyKind::Ref(None, _) => { // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with // NodeId `ty.id`. @@ -685,7 +722,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.resolve_elided_lifetime(ty.id, span); visit::walk_ty(self, ty); } - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { self.diagnostic_metadata.current_type_path = Some(ty); self.smart_resolve_path(ty.id, &qself, path, PathSource::Type); @@ -730,11 +767,11 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, visit::walk_ty(self, ty); self.lifetime_elision_candidates = candidates; } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { self.diagnostic_metadata.current_trait_object = Some(&bounds[..]); visit::walk_ty(self, ty) } - TyKind::BareFn(ref bare_fn) => { + TyKind::BareFn(bare_fn) => { let span = ty.span.shrink_to_lo().to(bare_fn.decl_span.shrink_to_lo()); self.with_generic_param_rib( &bare_fn.generic_params, @@ -769,6 +806,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, }, ) } + TyKind::Array(element_ty, length) => { + self.visit_ty(element_ty); + self.resolve_anon_const(length, AnonConstKind::ConstArg(IsRepeatExpr::No)); + } + TyKind::Typeof(ct) => { + self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No)) + } _ => visit::walk_ty(self, ty), } self.diagnostic_metadata.current_trait_object = prev; @@ -994,36 +1038,25 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, // namespace first, and if that fails we try again in the value namespace. If // resolution in the value namespace succeeds, we have an generic const argument on // our hands. - if let TyKind::Path(ref qself, ref path) = ty.kind { + if let TyKind::Path(None, ref path) = ty.kind { // We cannot disambiguate multi-segment paths right now as that requires type // checking. - if path.segments.len() == 1 && path.segments[0].args.is_none() { + if path.is_potential_trivial_const_arg() { let mut check_ns = |ns| { self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns) .is_some() }; if !check_ns(TypeNS) && check_ns(ValueNS) { - // This must be equivalent to `visit_anon_const`, but we cannot call it - // directly due to visitor lifetimes so we have to copy-paste some code. - // - // Note that we might not be inside of an repeat expression here, - // but considering that `IsRepeatExpr` is only relevant for - // non-trivial constants this is doesn't matter. - self.with_constant_rib( - IsRepeatExpr::No, - ConstantHasGenerics::Yes, - None, + self.resolve_anon_const_manual( + true, + AnonConstKind::ConstArg(IsRepeatExpr::No), |this| { this.smart_resolve_path( ty.id, - qself, + &None, path, PathSource::Expr(None), ); - - if let Some(ref qself) = *qself { - this.visit_ty(&qself.ty); - } this.visit_path(path, ty.id); }, ); @@ -1037,7 +1070,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.visit_ty(ty); } GenericArg::Lifetime(lt) => self.visit_lifetime(lt, visit::LifetimeCtxt::GenericArg), - GenericArg::Const(ct) => self.visit_anon_const(ct), + GenericArg::Const(ct) => { + self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::No)) + } } self.diagnostic_metadata.currently_processing_generics = prev; } @@ -1053,7 +1088,9 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, match constraint.kind { AssocConstraintKind::Equality { ref term } => match term { Term::Ty(ty) => self.visit_ty(ty), - Term::Const(c) => self.visit_anon_const(c), + Term::Const(c) => { + self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No)) + } }, AssocConstraintKind::Bound { ref bounds } => { walk_list!(self, visit_param_bound, bounds, BoundKind::Bound); @@ -1102,8 +1139,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, | LifetimeRibKind::AnonymousReportError | LifetimeRibKind::Elided(_) | LifetimeRibKind::ElisionFailure - | LifetimeRibKind::AnonConst - | LifetimeRibKind::ConstGeneric => {} + | LifetimeRibKind::ConcreteAnonConst(_) + | LifetimeRibKind::ConstParamTy => {} } } } @@ -1164,7 +1201,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, InlineAsmOperand::Const { anon_const, .. } => { // Although this is `DefKind::AnonConst`, it is allowed to reference outer // generic parameters like an inline const. - self.resolve_inline_const(anon_const); + self.resolve_anon_const(anon_const, AnonConstKind::InlineConst); } InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym), } @@ -1188,6 +1225,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, visit::walk_variant(self, v) } + fn visit_variant_discr(&mut self, discr: &'ast AnonConst) { + self.resolve_anon_const(discr, AnonConstKind::EnumDiscriminant); + } + fn visit_field_def(&mut self, f: &'ast FieldDef) { self.resolve_doc_links(&f.attrs, MaybeExported::Ok(f.id)); visit::walk_field_def(self, f) @@ -1386,7 +1427,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy)); this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy)); - this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { + this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| { this.visit_ty(ty) }); this.ribs[TypeNS].pop().unwrap(); @@ -1395,9 +1436,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { if let Some(ref expr) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); - this.with_lifetime_rib(LifetimeRibKind::ConstGeneric, |this| { - this.resolve_anon_const(expr, IsRepeatExpr::No) - }); + this.resolve_anon_const( + expr, + AnonConstKind::ConstArg(IsRepeatExpr::No), + ); forward_const_ban_rib = this.ribs[ValueNS].pop().unwrap(); forward_ty_ban_rib = this.ribs[TypeNS].pop().unwrap(); } @@ -1449,7 +1491,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) { self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named); - if let LifetimeRes::Param { param, .. } = res { + if let LifetimeRes::Param { param, binder } = res { match self.lifetime_uses.entry(param) { Entry::Vacant(v) => { debug!("First use of {:?} at {:?}", res, ident.span); @@ -1463,10 +1505,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { LifetimeRibKind::Item | LifetimeRibKind::AnonymousReportError | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many), - // An anonymous lifetime is legal here, go ahead. - LifetimeRibKind::AnonymousCreateParameter { .. } => { - Some(LifetimeUseSet::One { use_span: ident.span, use_ctxt }) - } + // An anonymous lifetime is legal here, and bound to the right + // place, go ahead. + LifetimeRibKind::AnonymousCreateParameter { + binder: anon_binder, + .. + } => Some(if binder == anon_binder { + LifetimeUseSet::One { use_span: ident.span, use_ctxt } + } else { + LifetimeUseSet::Many + }), // Only report if eliding the lifetime would have the same // semantics. LifetimeRibKind::Elided(r) => Some(if res == r { @@ -1475,8 +1523,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { LifetimeUseSet::Many }), LifetimeRibKind::Generics { .. } - | LifetimeRibKind::ConstGeneric => None, - LifetimeRibKind::AnonConst => { + | LifetimeRibKind::ConstParamTy => None, + LifetimeRibKind::ConcreteAnonConst(_) => { span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind) } }) @@ -1495,8 +1543,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { match rib.kind { LifetimeRibKind::Item => break, - LifetimeRibKind::ConstGeneric => { - self.emit_non_static_lt_in_const_generic_error(lifetime); + LifetimeRibKind::ConstParamTy => { + self.emit_non_static_lt_in_const_param_ty_error(lifetime); self.record_lifetime_res( lifetime.id, LifetimeRes::Error, @@ -1504,8 +1552,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ); return; } - LifetimeRibKind::AnonConst => { - self.maybe_emit_forbidden_non_static_lifetime_error(lifetime); + LifetimeRibKind::ConcreteAnonConst(cause) => { + self.emit_forbidden_non_static_lifetime_error(cause, lifetime); self.record_lifetime_res( lifetime.id, LifetimeRes::Error, @@ -1604,9 +1652,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { return; } LifetimeRibKind::Item => break, - LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {} - LifetimeRibKind::AnonConst => { - // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`. + LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {} + LifetimeRibKind::ConcreteAnonConst(_) => { + // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`. span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind) } } @@ -1826,9 +1874,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); break; } - LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {} - LifetimeRibKind::AnonConst => { - // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`. + LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstParamTy => {} + LifetimeRibKind::ConcreteAnonConst(_) => { + // There is always an `Elided(LifetimeRes::Infer)` inside an `AnonConst`. span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind) } } @@ -2560,7 +2608,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f)) } - // HACK(min_const_generics,const_evaluatable_unchecked): We + // HACK(min_const_generics, generic_const_exprs): We // want to keep allowing `[0; std::mem::size_of::<*mut T>()]` // with a future compat lint for now. We do this by adding an // additional special case for repeat expressions. @@ -2576,18 +2624,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { item: Option<(Ident, ConstantItemKind)>, f: impl FnOnce(&mut Self), ) { - self.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| { - this.with_rib( - TypeNS, - RibKind::ConstantItem( - may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes), - item, - ), - |this| { - this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f); - }, - ) - }); + let f = |this: &mut Self| { + this.with_rib(ValueNS, RibKind::ConstantItem(may_use_generics, item), |this| { + this.with_rib( + TypeNS, + RibKind::ConstantItem( + may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes), + item, + ), + |this| { + this.with_label_rib(RibKind::ConstantItem(may_use_generics, item), f); + }, + ) + }) + }; + + if let ConstantHasGenerics::No(cause) = may_use_generics { + self.with_lifetime_rib(LifetimeRibKind::ConcreteAnonConst(cause), f) + } else { + f(self) + } } fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T { @@ -3487,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`. @@ -3924,24 +3976,54 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { debug!("(resolving block) leaving block"); } - fn resolve_anon_const(&mut self, constant: &'ast AnonConst, is_repeat: IsRepeatExpr) { - debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat); - self.with_constant_rib( - is_repeat, - if constant.value.is_potential_trivial_const_param() { - ConstantHasGenerics::Yes - } else { - ConstantHasGenerics::No - }, - None, - |this| visit::walk_anon_const(this, constant), + fn resolve_anon_const(&mut self, constant: &'ast AnonConst, anon_const_kind: AnonConstKind) { + debug!( + "resolve_anon_const(constant: {:?}, anon_const_kind: {:?})", + constant, anon_const_kind ); + + self.resolve_anon_const_manual( + constant.value.is_potential_trivial_const_arg(), + anon_const_kind, + |this| this.resolve_expr(&constant.value, None), + ) } - fn resolve_inline_const(&mut self, constant: &'ast AnonConst) { - debug!("resolve_anon_const {constant:?}"); - self.with_constant_rib(IsRepeatExpr::No, ConstantHasGenerics::Yes, None, |this| { - visit::walk_anon_const(this, constant) + /// There are a few places that we need to resolve an anon const but we did not parse an + /// anon const so cannot provide an `&'ast AnonConst`. Right now this is just unbraced + /// const arguments that were parsed as type arguments, and `legact_const_generics` which + /// parse as normal function argument expressions. To avoid duplicating the code for resolving + /// an anon const we have this function which lets the caller manually call `resolve_expr` or + /// `smart_resolve_path`. + fn resolve_anon_const_manual( + &mut self, + is_trivial_const_arg: bool, + anon_const_kind: AnonConstKind, + resolve_expr: impl FnOnce(&mut Self), + ) { + let is_repeat_expr = match anon_const_kind { + AnonConstKind::ConstArg(is_repeat_expr) => is_repeat_expr, + _ => IsRepeatExpr::No, + }; + + let may_use_generics = match anon_const_kind { + AnonConstKind::EnumDiscriminant => { + ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant) + } + AnonConstKind::InlineConst => ConstantHasGenerics::Yes, + AnonConstKind::ConstArg(_) => { + if self.r.tcx.features().generic_const_exprs || is_trivial_const_arg { + ConstantHasGenerics::Yes + } else { + ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg) + } + } + }; + + self.with_constant_rib(is_repeat_expr, may_use_generics, None, |this| { + this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { + resolve_expr(this); + }); }); } @@ -4046,17 +4128,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // Constant arguments need to be treated as AnonConst since // that is how they will be later lowered to HIR. if const_args.contains(&idx) { - self.with_constant_rib( - IsRepeatExpr::No, - if argument.is_potential_trivial_const_param() { - ConstantHasGenerics::Yes - } else { - ConstantHasGenerics::No - }, - None, - |this| { - this.resolve_expr(argument, None); - }, + self.resolve_anon_const_manual( + argument.is_potential_trivial_const_arg(), + AnonConstKind::ConstArg(IsRepeatExpr::No), + |this| this.resolve_expr(argument, None), ); } else { self.resolve_expr(argument, None); @@ -4115,14 +4190,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } ExprKind::Repeat(ref elem, ref ct) => { self.visit_expr(elem); - self.with_lifetime_rib(LifetimeRibKind::AnonConst, |this| { - this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Infer), |this| { - this.resolve_anon_const(ct, IsRepeatExpr::Yes) - }) - }); + self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes)); } ExprKind::ConstBlock(ref ct) => { - self.resolve_inline_const(ct); + self.resolve_anon_const(ct, AnonConstKind::InlineConst); } ExprKind::Index(ref elem, ref idx) => { self.resolve_expr(elem, Some(expr)); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 42d498c7ee0..c9131d8c8a9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1,7 +1,7 @@ use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind}; use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet}; -use crate::path_names_to_string; +use crate::{errors, path_names_to_string}; use crate::{Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, Segment}; @@ -22,7 +22,6 @@ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::PrimTy; use rustc_session::lint; -use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; @@ -35,6 +34,8 @@ use std::ops::Deref; use thin_vec::ThinVec; +use super::NoConstantGenericsReason; + type Res = def::Res<ast::NodeId>; /// A field or associated item from self type suggested in case of resolution failure. @@ -2316,37 +2317,56 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } - pub(crate) fn emit_non_static_lt_in_const_generic_error(&self, lifetime_ref: &ast::Lifetime) { - struct_span_err!( - self.r.tcx.sess, - lifetime_ref.ident.span, - E0771, - "use of non-static lifetime `{}` in const generic", - lifetime_ref.ident - ) - .note( - "for more information, see issue #74052 \ - <https://github.com/rust-lang/rust/issues/74052>", - ) - .emit(); + pub(crate) fn emit_non_static_lt_in_const_param_ty_error(&self, lifetime_ref: &ast::Lifetime) { + self.r + .tcx + .sess + .create_err(errors::ParamInTyOfConstParam { + span: lifetime_ref.ident.span, + name: lifetime_ref.ident.name, + param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime), + }) + .emit(); } /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`. /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by /// `body_id` is an anonymous constant and `lifetime_ref` is non-static. - pub(crate) fn maybe_emit_forbidden_non_static_lifetime_error( + pub(crate) fn emit_forbidden_non_static_lifetime_error( &self, + cause: NoConstantGenericsReason, lifetime_ref: &ast::Lifetime, ) { - let feature_active = self.r.tcx.sess.features_untracked().generic_const_exprs; - if !feature_active { - feature_err( - &self.r.tcx.sess.parse_sess, - sym::generic_const_exprs, - lifetime_ref.ident.span, - "a non-static lifetime is not allowed in a `const`", - ) - .emit(); + match cause { + NoConstantGenericsReason::IsEnumDiscriminant => { + self.r + .tcx + .sess + .create_err(errors::ParamInEnumDiscriminant { + span: lifetime_ref.ident.span, + name: lifetime_ref.ident.name, + param_kind: errors::ParamKindInEnumDiscriminant::Lifetime, + }) + .emit(); + } + NoConstantGenericsReason::NonTrivialConstArg => { + assert!(!self.r.tcx.features().generic_const_exprs); + self.r + .tcx + .sess + .create_err(errors::ParamInNonTrivialAnonConst { + span: lifetime_ref.ident.span, + name: lifetime_ref.ident.name, + param_kind: errors::ParamKindInNonTrivialAnonConst::Lifetime, + help: self + .r + .tcx + .sess + .is_nightly_build() + .then_some(errors::ParamInNonTrivialAnonConstHelp), + }) + .emit(); + } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e46463579fe..323b78fcd98 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -21,6 +21,9 @@ #[macro_use] extern crate tracing; +use errors::{ + ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam, +}; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::{self as ast, attr, NodeId, CRATE_NODE_ID}; @@ -44,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}; @@ -223,11 +227,15 @@ enum ResolutionError<'a> { /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. ForwardDeclaredGenericParam, /// ERROR E0770: the type of const parameters must not depend on other generic parameters. - ParamInTyOfConstParam(Symbol), + ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> }, /// generic parameters must not be used inside const evaluations. /// /// This error is only emitted when using `min_const_generics`. - ParamInNonTrivialAnonConst { name: Symbol, is_type: bool }, + ParamInNonTrivialAnonConst { name: Symbol, param_kind: ParamKindInNonTrivialAnonConst }, + /// generic parameters must not be used inside enum discriminants. + /// + /// This error is emitted even with `generic_const_exprs`. + ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant }, /// Error E0735: generic parameters with a default cannot use `Self` SelfInGenericParamDefault, /// Error E0767: use of unreachable label @@ -244,6 +252,8 @@ enum ResolutionError<'a> { TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span }, /// Inline asm `sym` operand must refer to a `fn` or `static`. InvalidAsmSym, + /// `self` used instead of `Self` in a generic parameter + LowercaseSelf, } enum VisResolutionError<'a> { @@ -2017,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/Cargo.toml b/compiler/rustc_session/Cargo.toml index 3477b97438c..3af83aaaaa8 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -25,7 +25,7 @@ termize = "0.1.1" libc = "0.2" [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = [ "Win32_Foundation", "Win32_System_LibraryLoader", diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index aa3cb03bad8..e2b8d3eea2d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1060,6 +1060,9 @@ fn default_configuration(sess: &Session) -> CrateConfig { if sess.opts.debug_assertions { ret.insert((sym::debug_assertions, None)); } + if sess.overflow_checks() { + ret.insert((sym::overflow_checks, None)); + } // JUSTIFICATION: before wrapper fn is available #[allow(rustc::bad_opt_access)] if sess.opts.crate_types.contains(&CrateType::ProcMacro) { @@ -1209,6 +1212,7 @@ impl CrateCheckConfig { sym::windows, sym::proc_macro, sym::debug_assertions, + sym::overflow_checks, sym::target_thread_local, ] { self.expecteds.entry(name).or_insert_with(no_values); diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index dd1721801f3..dc475e8c6d5 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,7 +6,8 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; -use rustc_data_structures::sync::{self, AppendOnlyIndexVec, MetadataRef, RwLock}; +use rustc_data_structures::owned_slice::OwnedSlice; +use rustc_data_structures::sync::{self, AppendOnlyIndexVec, RwLock}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_span::hygiene::{ExpnHash, ExpnId}; @@ -203,11 +204,11 @@ pub enum ExternCrateSource { /// metadata in library -- this trait just serves to decouple rustc_metadata from /// the archive reader, which depends on LLVM. pub trait MetadataLoader: std::fmt::Debug { - fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>; - fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>; + fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>; + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, 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 +253,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_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 7fdbd48d563..3988416d0c7 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -135,13 +135,13 @@ fn current_dll_path() -> Result<PathBuf, String> { use windows::{ core::PCWSTR, - Win32::Foundation::HINSTANCE, + Win32::Foundation::HMODULE, Win32::System::LibraryLoader::{ GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, }, }; - let mut module = HINSTANCE::default(); + let mut module = HMODULE::default(); unsafe { GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 5cbd7f98b6b..5976b9aa3e7 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1720,6 +1720,10 @@ options! { #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED], "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), + staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], + "allow staticlibs to have rust dylib dependencies"), + staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED], + "prefer dynamic linking to static linking for staticlibs (default: no)"), strict_init_checks: bool = (false, parse_bool, [TRACKED], "control if mem::uninitialized and mem::zeroed panic on more UB"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 54d474db038..b00f0a1c153 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -11,6 +11,8 @@ test(attr(allow(unused_variables), deny(warnings))) )] #![cfg_attr(not(feature = "default"), feature(rustc_private))] +#![feature(local_key_cell_methods)] +#![feature(ptr_metadata)] pub mod rustc_internal; pub mod stable_mir; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 5998c8b6500..609a04d263c 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,30 +3,49 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::sync::RwLock; - -use crate::stable_mir; +use crate::{ + rustc_smir::Tables, + stable_mir::{self, with}, +}; +use rustc_middle::ty::TyCtxt; pub use rustc_span::def_id::{CrateNum, DefId}; -static DEF_ID_MAP: RwLock<Vec<DefId>> = RwLock::new(Vec::new()); +fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R { + let mut ret = None; + with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t)))); + ret.unwrap() +} pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { - DEF_ID_MAP.read().unwrap()[item.0] + with_tables(|t| t.item_def_id(item)) } pub fn crate_item(did: DefId) -> stable_mir::CrateItem { - // FIXME: this becomes inefficient when we have too many ids - let mut map = DEF_ID_MAP.write().unwrap(); - for (i, &d) in map.iter().enumerate() { - if d == did { - return stable_mir::CrateItem(i); + with_tables(|t| t.crate_item(did)) +} + +impl<'tcx> Tables<'tcx> { + pub fn item_def_id(&self, item: &stable_mir::CrateItem) -> DefId { + self.def_ids[item.0] + } + + pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { + // FIXME: this becomes inefficient when we have too many ids + for (i, &d) in self.def_ids.iter().enumerate() { + if d == did { + return stable_mir::CrateItem(i); + } } + let id = self.def_ids.len(); + self.def_ids.push(did); + stable_mir::CrateItem(id) } - let id = map.len(); - map.push(did); - stable_mir::CrateItem(id) } pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { item.id.into() } + +pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { + crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f); +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 241cd182059..6af43f5d3f3 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,41 +7,107 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::{ - rustc_internal::{crate_item, item_def_id}, - stable_mir::{self}, -}; -use rustc_middle::ty::{tls::with, TyCtxt}; -use rustc_span::def_id::{CrateNum, LOCAL_CRATE}; +use crate::stable_mir::{self, ty::TyKind, Context}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use tracing::debug; -/// Get information about the local crate. -pub fn local_crate() -> stable_mir::Crate { - with(|tcx| smir_crate(tcx, LOCAL_CRATE)) -} +impl<'tcx> Context for Tables<'tcx> { + fn local_crate(&self) -> stable_mir::Crate { + smir_crate(self.tcx, LOCAL_CRATE) + } -/// Retrieve a list of all external crates. -pub fn external_crates() -> Vec<stable_mir::Crate> { - with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect()) -} + fn external_crates(&self) -> Vec<stable_mir::Crate> { + self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect() + } -/// Find a crate with the given name. -pub fn find_crate(name: &str) -> Option<stable_mir::Crate> { - with(|tcx| { - [LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| { - let crate_name = tcx.crate_name(*crate_num).to_string(); - (name == crate_name).then(|| smir_crate(tcx, *crate_num)) + fn find_crate(&self, name: &str) -> Option<stable_mir::Crate> { + [LOCAL_CRATE].iter().chain(self.tcx.crates(()).iter()).find_map(|crate_num| { + let crate_name = self.tcx.crate_name(*crate_num).to_string(); + (name == crate_name).then(|| smir_crate(self.tcx, *crate_num)) }) - }) + } + + fn all_local_items(&mut self) -> stable_mir::CrateItems { + self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect() + } + fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> { + Some(self.crate_item(self.tcx.entry_fn(())?.0)) + } + fn mir_body(&mut self, item: &stable_mir::CrateItem) -> stable_mir::mir::Body { + let def_id = self.item_def_id(item); + let mir = self.tcx.optimized_mir(def_id); + stable_mir::mir::Body { + blocks: mir + .basic_blocks + .iter() + .map(|block| stable_mir::mir::BasicBlock { + terminator: rustc_terminator_to_terminator(block.terminator()), + statements: block.statements.iter().map(rustc_statement_to_statement).collect(), + }) + .collect(), + locals: mir.local_decls.iter().map(|decl| self.intern_ty(decl.ty)).collect(), + } + } + + fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) { + f(self) + } + + fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind { + self.rustc_ty_to_ty(self.types[ty.0]) + } } -/// Retrieve all items of the local crate that have a MIR associated with them. -pub fn all_local_items() -> stable_mir::CrateItems { - with(|tcx| tcx.mir_keys(()).iter().map(|item| crate_item(item.to_def_id())).collect()) +pub struct Tables<'tcx> { + pub tcx: TyCtxt<'tcx>, + pub def_ids: Vec<DefId>, + pub types: Vec<Ty<'tcx>>, } -pub fn entry_fn() -> Option<stable_mir::CrateItem> { - with(|tcx| Some(crate_item(tcx.entry_fn(())?.0))) +impl<'tcx> Tables<'tcx> { + fn rustc_ty_to_ty(&mut self, ty: Ty<'tcx>) -> TyKind { + match ty.kind() { + ty::Bool => TyKind::Bool, + ty::Char => todo!(), + ty::Int(_) => todo!(), + ty::Uint(_) => todo!(), + ty::Float(_) => todo!(), + ty::Adt(_, _) => todo!(), + ty::Foreign(_) => todo!(), + ty::Str => todo!(), + ty::Array(_, _) => todo!(), + ty::Slice(_) => todo!(), + ty::RawPtr(_) => todo!(), + ty::Ref(_, _, _) => todo!(), + ty::FnDef(_, _) => todo!(), + ty::FnPtr(_) => todo!(), + ty::Placeholder(..) => todo!(), + ty::Dynamic(_, _, _) => todo!(), + ty::Closure(_, _) => todo!(), + ty::Generator(_, _, _) => todo!(), + ty::GeneratorWitness(_) => todo!(), + ty::GeneratorWitnessMIR(_, _) => todo!(), + ty::Never => todo!(), + ty::Tuple(fields) => { + TyKind::Tuple(fields.iter().map(|ty| self.intern_ty(ty)).collect()) + } + ty::Alias(_, _) => todo!(), + ty::Param(_) => todo!(), + ty::Bound(_, _) => todo!(), + ty::Infer(_) => todo!(), + ty::Error(_) => todo!(), + } + } + + fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty { + if let Some(id) = self.types.iter().position(|&t| t == ty) { + return stable_mir::ty::Ty(id); + } + let id = self.types.len(); + self.types.push(ty); + stable_mir::ty::Ty(id) + } } /// Build a stable mir crate from a given crate number. @@ -52,23 +118,6 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } -pub fn mir_body(item: &stable_mir::CrateItem) -> stable_mir::mir::Body { - with(|tcx| { - let def_id = item_def_id(item); - let mir = tcx.optimized_mir(def_id); - stable_mir::mir::Body { - blocks: mir - .basic_blocks - .iter() - .map(|block| stable_mir::mir::BasicBlock { - terminator: rustc_terminator_to_terminator(block.terminator()), - statements: block.statements.iter().map(rustc_statement_to_statement).collect(), - }) - .collect(), - } - }) -} - fn rustc_statement_to_statement( s: &rustc_middle::mir::Statement<'_>, ) -> stable_mir::mir::Statement { diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 4baf3f1f75e..6328c35aa59 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1,6 +1,9 @@ +use crate::stable_mir::ty::Ty; + #[derive(Clone, Debug)] pub struct Body { pub blocks: Vec<BasicBlock>, + pub locals: Vec<Ty>, } #[derive(Clone, Debug)] diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 1d2efb5eab9..612777b9c75 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -11,7 +11,14 @@ //! There shouldn't be any direct references to internal compiler constructs in this module. //! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. +use std::cell::Cell; + +use crate::rustc_smir::Tables; + +use self::ty::{Ty, TyKind}; + pub mod mir; +pub mod ty; /// Use String for now but we should replace it. pub type Symbol = String; @@ -41,7 +48,7 @@ pub struct CrateItem(pub(crate) DefId); impl CrateItem { pub fn body(&self) -> mir::Body { - crate::rustc_smir::mir_body(self) + with(|cx| cx.mir_body(self)) } } @@ -49,25 +56,72 @@ impl CrateItem { /// crate defines that. This is usually `main`, but could be /// `start` if the crate is a no-std crate. pub fn entry_fn() -> Option<CrateItem> { - crate::rustc_smir::entry_fn() + with(|cx| cx.entry_fn()) } /// Access to the local crate. pub fn local_crate() -> Crate { - crate::rustc_smir::local_crate() + with(|cx| cx.local_crate()) } /// Try to find a crate with the given name. pub fn find_crate(name: &str) -> Option<Crate> { - crate::rustc_smir::find_crate(name) + with(|cx| cx.find_crate(name)) } /// Try to find a crate with the given name. pub fn external_crates() -> Vec<Crate> { - crate::rustc_smir::external_crates() + with(|cx| cx.external_crates()) } /// Retrieve all items in the local crate that have a MIR associated with them. pub fn all_local_items() -> CrateItems { - crate::rustc_smir::all_local_items() + with(|cx| cx.all_local_items()) +} + +pub trait Context { + fn entry_fn(&mut self) -> Option<CrateItem>; + /// Retrieve all items of the local crate that have a MIR associated with them. + fn all_local_items(&mut self) -> CrateItems; + fn mir_body(&mut self, item: &CrateItem) -> mir::Body; + /// Get information about the local crate. + fn local_crate(&self) -> Crate; + /// Retrieve a list of all external crates. + fn external_crates(&self) -> Vec<Crate>; + + /// Find a crate with the given name. + fn find_crate(&self, name: &str) -> Option<Crate>; + + /// Obtain the representation of a type. + fn ty_kind(&mut self, ty: Ty) -> TyKind; + + /// HACK: Until we have fully stable consumers, we need an escape hatch + /// to get `DefId`s out of `CrateItem`s. + fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)); +} + +thread_local! { + /// A thread local variable that stores a pointer to the tables mapping between TyCtxt + /// datastructures and stable MIR datastructures. + static TLV: Cell<*mut ()> = const { Cell::new(std::ptr::null_mut()) }; +} + +pub fn run(mut context: impl Context, f: impl FnOnce()) { + assert!(TLV.get().is_null()); + fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) { + TLV.set(&mut context as *mut &mut _ as _); + f(); + TLV.replace(std::ptr::null_mut()); + } + g(&mut context, f); +} + +/// Loads the current context and calls a function with it. +/// Do not nest these, as that will ICE. +pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { + let ptr = TLV.replace(std::ptr::null_mut()) as *mut &mut dyn Context; + assert!(!ptr.is_null()); + let ret = f(unsafe { *ptr }); + TLV.set(ptr as _); + ret } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs new file mode 100644 index 00000000000..f27801b0f6c --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -0,0 +1,15 @@ +use super::with; + +#[derive(Copy, Clone, Debug)] +pub struct Ty(pub usize); + +impl Ty { + pub fn kind(&self) -> TyKind { + with(|context| context.ty_kind(*self)) + } +} + +pub enum TyKind { + Bool, + Tuple(Vec<Ty>), +} 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_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b97ec6c684b..874d578fe1d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -95,6 +95,7 @@ symbols! { // Weak keywords, have special meaning only in specific contexts. Auto: "auto", + Builtin: "builtin", Catch: "catch", Default: "default", MacroRules: "macro_rules", @@ -163,6 +164,7 @@ symbols! { Capture, Center, Clone, + ConstParamTy, Context, Continue, Copy, @@ -440,6 +442,7 @@ symbols! { breakpoint, bridge, bswap, + builtin_syntax, c_str, c_str_literals, c_unwind, @@ -461,6 +464,7 @@ symbols! { cfg_doctest, cfg_eval, cfg_hide, + cfg_overflow_checks, cfg_panic, cfg_sanitize, cfg_target_abi, @@ -1031,6 +1035,7 @@ symbols! { non_exhaustive_omitted_patterns_lint, non_lifetime_binders, non_modrs_mods, + none, nontemporal_store, noop_method_borrow, noop_method_clone, @@ -1062,6 +1067,7 @@ symbols! { or_patterns, other, out, + overflow_checks, overlapping_marker_traits, owned_box, packed, @@ -1578,6 +1584,7 @@ symbols! { unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, unsafe_cell, + unsafe_cell_from_mut, unsafe_no_drop_flag, unsafe_pin_internals, unsize, 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_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 81dbff9ea4e..cda16e3a3f5 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -4,7 +4,7 @@ /// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, /// see design document in the tracking issue #89653. use bitflags::bitflags; -use rustc_middle::ty::{FnSig, Ty, TyCtxt}; +use rustc_middle::ty::{FnSig, Instance, Ty, TyCtxt}; use rustc_target::abi::call::FnAbi; use std::hash::Hasher; use twox_hash::XxHash64; @@ -38,6 +38,15 @@ pub fn typeid_for_fnsig<'tcx>( typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options) } +/// Returns a type metadata identifier for the specified Instance. +pub fn typeid_for_instance<'tcx>( + tcx: TyCtxt<'tcx>, + instance: &Instance<'tcx>, + options: TypeIdOptions, +) -> String { + typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options) +} + /// Returns a KCFI type metadata identifier for the specified FnAbi. pub fn kcfi_typeid_for_fnabi<'tcx>( tcx: TyCtxt<'tcx>, @@ -63,3 +72,16 @@ pub fn kcfi_typeid_for_fnsig<'tcx>( hash.write(typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options).as_bytes()); hash.finish() as u32 } + +/// Returns a KCFI type metadata identifier for the specified Instance. +pub fn kcfi_typeid_for_instance<'tcx>( + tcx: TyCtxt<'tcx>, + instance: &Instance<'tcx>, + options: TypeIdOptions, +) -> u32 { + // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the + // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) + let mut hash: XxHash64 = Default::default(); + hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes()); + hash.finish() as u32 +} diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 5310ef26da7..c281aa7e83a 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -14,8 +14,8 @@ use rustc_errors::DiagnosticMessage; use rustc_hir as hir; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - self, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind, TermKind, - Ty, TyCtxt, UintTy, + self, Const, ExistentialPredicate, FloatTy, FnSig, Instance, IntTy, List, Region, RegionKind, + TermKind, Ty, TyCtxt, UintTy, }; use rustc_span::def_id::DefId; use rustc_span::sym; @@ -1010,3 +1010,56 @@ pub fn typeid_for_fnsig<'tcx>( typeid } + +/// Returns a type metadata identifier for the specified Instance using the Itanium C++ ABI with +/// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary. +pub fn typeid_for_instance<'tcx>( + tcx: TyCtxt<'tcx>, + instance: &Instance<'tcx>, + options: TypeIdOptions, +) -> String { + let fn_abi = tcx + .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, ty::List::empty()))) + .unwrap_or_else(|instance| { + bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance) + }); + + // If this instance is a method and self is a reference, get the impl it belongs to + let impl_def_id = tcx.impl_of_method(instance.def_id()); + if impl_def_id.is_some() && !fn_abi.args.is_empty() && fn_abi.args[0].layout.ty.is_ref() { + // If this impl is not an inherent impl, get the trait it implements + if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id.unwrap()) { + // Transform the concrete self into a reference to a trait object + let existential_predicate = trait_ref.map_bound(|trait_ref| { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty( + tcx, trait_ref, + )) + }); + let existential_predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy( + existential_predicate.skip_binder(), + )]); + // Is the concrete self mutable? + let self_ty = if fn_abi.args[0].layout.ty.is_mutable_ptr() { + tcx.mk_mut_ref( + tcx.lifetimes.re_erased, + tcx.mk_dynamic(existential_predicates, tcx.lifetimes.re_erased, ty::Dyn), + ) + } else { + tcx.mk_imm_ref( + tcx.lifetimes.re_erased, + tcx.mk_dynamic(existential_predicates, tcx.lifetimes.re_erased, ty::Dyn), + ) + }; + + // Replace the concrete self in an fn_abi clone by the reference to a trait object + let mut fn_abi = fn_abi.clone(); + // HACK(rcvalle): It is okay to not replace or update the entire ArgAbi here because the + // other fields are never used. + fn_abi.args[0].layout.ty = self_ty; + + return typeid_for_fnabi(tcx, &fn_abi, options); + } + } + + typeid_for_fnabi(tcx, &fn_abi, options) +} diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 52159a7b06a..1ae11f5671c 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -28,7 +28,7 @@ mod x86; mod x86_64; mod x86_win64; -#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum PassMode { /// Ignore the argument. /// @@ -211,7 +211,7 @@ impl Uniform { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct CastTarget { pub prefix: [Option<Reg>; 8], pub rest: Uniform, @@ -458,7 +458,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// Information about how to pass an argument to, /// or return a value from, a function, under some ABI. -#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct ArgAbi<'a, Ty> { pub layout: TyAndLayout<'a, Ty>, pub mode: PassMode, @@ -605,7 +605,7 @@ pub enum Conv { /// /// I will do my best to describe this structure, but these /// comments are reverse-engineered and may be inaccurate. -NDM -#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct FnAbi<'a, Ty> { /// The LLVM types of each argument. pub args: Box<[ArgAbi<'a, Ty>]>, diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 705966f5237..e60b8e78e5d 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -882,8 +882,8 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::LoongArch64 => match name { - "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), - _ => Err(&["C", "system", "efiapi"]), + "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), + _ => Err(&["C", "system"]), }, _ => Err(&[]), } diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 14eb4a5502d..8fea3fc140d 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -20,3 +20,5 @@ trait_selection_negative_positive_conflict = found both positive and negative im .negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}` .positive_implementation_here = positive implementation here .positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}` + +trait_selection_inherent_projection_normalization_overflow = overflow evaluating associated type `{$ty}` diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index df7c4df1868..54e22cc3d7f 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -89,3 +89,11 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> { diag } } + +#[derive(Diagnostic)] +#[diag(trait_selection_inherent_projection_normalization_overflow)] +pub struct InherentProjectionNormalizationOverflow { + #[primary_span] + pub span: Span, + pub ty: String, +} diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index bacb0e32efc..25cc82f01d5 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::util::elaborate; +use rustc_infer::traits::Reveal; use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult}; use rustc_middle::ty::fast_reject::TreatProjections; use rustc_middle::ty::TypeFoldable; @@ -87,7 +88,9 @@ pub(super) enum CandidateSource { } /// Methods used to assemble candidates for either trait or projection goals. -pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq { +pub(super) trait GoalKind<'tcx>: + TypeFoldable<TyCtxt<'tcx>> + Copy + Eq + std::fmt::Display +{ fn self_ty(self) -> Ty<'tcx>; fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx>; @@ -96,6 +99,17 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq { fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId; + // Try equating an assumption predicate against a goal's predicate. If it + // holds, then execute the `then` callback, which should do any additional + // work, then produce a response (typically by executing + // [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]). + fn probe_and_match_goal_against_assumption( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + assumption: ty::Predicate<'tcx>, + then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, + ) -> QueryResult<'tcx>; + // Consider a clause, which consists of a "assumption" and some "requirements", // to satisfy a goal. If the requirements hold, then attempt to satisfy our // goal by equating it with the assumption. @@ -104,7 +118,26 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq { goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>, - ) -> QueryResult<'tcx>; + ) -> QueryResult<'tcx> { + Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { + ecx.add_goals(requirements); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + + /// Consider a bound originating from the item bounds of an alias. For this we + /// require that the well-formed requirements of the self type of the goal + /// are "satisfied from the param-env". + /// See [`EvalCtxt::validate_alias_bound_self_from_param_env`]. + fn consider_alias_bound_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + assumption: ty::Predicate<'tcx>, + ) -> QueryResult<'tcx> { + Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { + ecx.validate_alias_bound_self_from_param_env(goal) + }) + } // Consider a clause specifically for a `dyn Trait` self type. This requires // additionally checking all of the supertraits and object bounds to hold, @@ -113,7 +146,25 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - ) -> QueryResult<'tcx>; + ) -> QueryResult<'tcx> { + Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| { + let tcx = ecx.tcx(); + let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { + bug!("expected object type in `consider_object_bound_candidate`"); + }; + ecx.add_goals( + structural_traits::predicates_for_object_candidate( + &ecx, + goal.param_env, + goal.predicate.trait_ref(tcx), + bounds, + ) + .into_iter() + .map(|pred| goal.with(tcx, pred)), + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, @@ -463,7 +514,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs) { - match G::consider_implied_clause(self, goal, assumption, []) { + match G::consider_alias_bound_candidate(self, goal, assumption) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::AliasBound, result }) } @@ -472,6 +523,105 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } + /// Check that we are allowed to use an alias bound originating from the self + /// type of this goal. This means something different depending on the self type's + /// alias kind. + /// + /// * Projection: Given a goal with a self type such as `<Ty as Trait>::Assoc`, + /// we require that the bound `Ty: Trait` can be proven using either a nested alias + /// bound candidate, or a param-env candidate. + /// + /// * Opaque: The param-env must be in `Reveal::UserFacing` mode. Otherwise, + /// the goal should be proven by using the hidden type instead. + #[instrument(level = "debug", skip(self), ret)] + pub(super) fn validate_alias_bound_self_from_param_env<G: GoalKind<'tcx>>( + &mut self, + goal: Goal<'tcx, G>, + ) -> QueryResult<'tcx> { + match *goal.predicate.self_ty().kind() { + ty::Alias(ty::Projection, projection_ty) => { + let mut param_env_candidates = vec![]; + let self_trait_ref = projection_ty.trait_ref(self.tcx()); + + if self_trait_ref.self_ty().is_ty_var() { + return self + .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); + } + + let trait_goal: Goal<'_, ty::TraitPredicate<'tcx>> = goal.with( + self.tcx(), + ty::TraitPredicate { + trait_ref: self_trait_ref, + constness: ty::BoundConstness::NotConst, + polarity: ty::ImplPolarity::Positive, + }, + ); + + self.assemble_param_env_candidates(trait_goal, &mut param_env_candidates); + // FIXME: We probably need some sort of recursion depth check here. + // Can't come up with an example yet, though, and the worst case + // we can have is a compiler stack overflow... + self.assemble_alias_bound_candidates(trait_goal, &mut param_env_candidates); + + // FIXME: We must also consider alias-bound candidates for a peculiar + // class of built-in candidates that I'll call "defaulted" built-ins. + // + // For example, we always know that `T: Pointee` is implemented, but + // we do not always know what `<T as Pointee>::Metadata` actually is, + // similar to if we had a user-defined impl with a `default type ...`. + // For these traits, since we're not able to always normalize their + // associated types to a concrete type, we must consider their alias bounds + // instead, so we can prove bounds such as `<T as Pointee>::Metadata: Copy`. + self.assemble_alias_bound_candidates_for_builtin_impl_default_items( + trait_goal, + &mut param_env_candidates, + ); + + self.merge_candidates(param_env_candidates) + } + ty::Alias(ty::Opaque, _opaque_ty) => match goal.param_env.reveal() { + Reveal::UserFacing => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + Reveal::All => return Err(NoSolution), + }, + _ => bug!("only expected to be called on alias tys"), + } + } + + /// Assemble a subset of builtin impl candidates for a class of candidates called + /// "defaulted" built-in traits. + /// + /// For example, we always know that `T: Pointee` is implemented, but we do not + /// always know what `<T as Pointee>::Metadata` actually is! See the comment in + /// [`EvalCtxt::validate_alias_bound_self_from_param_env`] for more detail. + #[instrument(level = "debug", skip_all)] + fn assemble_alias_bound_candidates_for_builtin_impl_default_items<G: GoalKind<'tcx>>( + &mut self, + goal: Goal<'tcx, G>, + candidates: &mut Vec<Candidate<'tcx>>, + ) { + let lang_items = self.tcx().lang_items(); + let trait_def_id = goal.predicate.trait_def_id(self.tcx()); + + // You probably shouldn't add anything to this list unless you + // know what you're doing. + let result = if lang_items.pointee_trait() == Some(trait_def_id) { + G::consider_builtin_pointee_candidate(self, goal) + } else if lang_items.discriminant_kind_trait() == Some(trait_def_id) { + G::consider_builtin_discriminant_kind_candidate(self, goal) + } else { + Err(NoSolution) + }; + + match result { + Ok(result) => { + candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }) + } + Err(NoSolution) => (), + } + } + #[instrument(level = "debug", skip_all)] fn assemble_object_bound_candidates<G: GoalKind<'tcx>>( &mut self, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 996dc329dcb..0ede32c753c 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -33,7 +33,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) - | ty::Alias(ty::Projection, ..) + | ty::Alias(ty::Projection | ty::Inherent, ..) | ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => { diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index e5d51064c8d..d3228074421 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -56,11 +56,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { self.trait_def_id(tcx) } - fn consider_implied_clause( + fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>, + then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, ) -> QueryResult<'tcx> { if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() && poly_projection_pred.projection_def_id() == goal.predicate.def_id() @@ -75,49 +75,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { )?; ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) .expect("expected goal term to be fully unconstrained"); - ecx.add_goals(requirements); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } else { - Err(NoSolution) - } - } - - fn consider_object_bound_candidate( - ecx: &mut EvalCtxt<'_, 'tcx>, - goal: Goal<'tcx, Self>, - assumption: ty::Predicate<'tcx>, - ) -> QueryResult<'tcx> { - if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() - && poly_projection_pred.projection_def_id() == goal.predicate.def_id() - { - ecx.probe(|ecx| { - let tcx = ecx.tcx(); - - let assumption_projection_pred = - ecx.instantiate_binder_with_infer(poly_projection_pred); - ecx.eq( - goal.param_env, - goal.predicate.projection_ty, - assumption_projection_pred.projection_ty, - )?; - - let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { - bug!("expected object type in `consider_object_bound_candidate`"); - }; - ecx.add_goals( - structural_traits::predicates_for_object_candidate( - &ecx, - goal.param_env, - goal.predicate.projection_ty.trait_ref(tcx), - bounds, - ) - .into_iter() - .map(|pred| goal.with(tcx, pred)), - ); - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) - .expect("expected goal term to be fully unconstrained"); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + then(ecx) }) } else { Err(NoSolution) @@ -166,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/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 6c98fadd148..dcfa33ae842 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -78,11 +78,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }) } - fn consider_implied_clause( + fn probe_and_match_goal_against_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>, + then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, ) -> QueryResult<'tcx> { if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() && poly_trait_pred.def_id() == goal.predicate.def_id() @@ -97,48 +97,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { goal.predicate.trait_ref, assumption_trait_pred.trait_ref, )?; - ecx.add_goals(requirements); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } else { - Err(NoSolution) - } - } - - fn consider_object_bound_candidate( - ecx: &mut EvalCtxt<'_, 'tcx>, - goal: Goal<'tcx, Self>, - assumption: ty::Predicate<'tcx>, - ) -> QueryResult<'tcx> { - if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() - && poly_trait_pred.def_id() == goal.predicate.def_id() - && poly_trait_pred.polarity() == goal.predicate.polarity - { - // FIXME: Constness and polarity - ecx.probe(|ecx| { - let assumption_trait_pred = - ecx.instantiate_binder_with_infer(poly_trait_pred); - ecx.eq( - goal.param_env, - goal.predicate.trait_ref, - assumption_trait_pred.trait_ref, - )?; - - let tcx = ecx.tcx(); - let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { - bug!("expected object type in `consider_object_bound_candidate`"); - }; - ecx.add_goals( - structural_traits::predicates_for_object_candidate( - &ecx, - goal.param_env, - goal.predicate.trait_ref, - bounds, - ) - .into_iter() - .map(|pred| goal.with(tcx, pred)), - ); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + then(ecx) }) } else { Err(NoSolution) @@ -655,7 +614,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) - | ty::Alias(ty::Projection, ..) + | ty::Alias(ty::Projection | ty::Inherent, ..) | ty::Placeholder(..) => Some(Err(NoSolution)), ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"), 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/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index b7690f79933..969e5fa64b0 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -322,7 +322,9 @@ fn negative_impl(tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId) -> b let selcx = &mut SelectionContext::new(&infcx); let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id); let (subject2, obligations) = - impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs); + impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs, |_, _| { + ObligationCause::dummy() + }); !equate(&infcx, impl_env, subject1, subject2, obligations, impl1_def_id) } @@ -673,7 +675,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> { | ty::RawPtr(..) | ty::Never | ty::Tuple(..) - | ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty), + | ty::Alias(ty::Projection | ty::Inherent, ..) => self.found_non_local_ty(ty), ty::Param(..) => self.found_param_ty(ty), 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/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index afb64da8b61..f5f2fe54217 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -28,6 +28,7 @@ use rustc_hir::{GenericParam, Item, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; +use rustc_middle::traits::SelectionOutputTypeParameterMismatch; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; @@ -796,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_label(span, explanation); } - if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() && - Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { - self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty); + if let ObligationCauseCode::Coercion { source, target } = + *obligation.cause.code().peel_derives() + { + if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + self.suggest_borrowing_for_object_cast( + &mut err, + &root_obligation, + source, + target, + ); + } } let UnsatisfiedConst(unsatisfied_const) = self @@ -1087,17 +1096,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - OutputTypeParameterMismatch( + OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch { found_trait_ref, expected_trait_ref, - terr @ TypeError::CyclicTy(_), - ) => self.report_type_parameter_mismatch_cyclic_type_error( + terr: terr @ TypeError::CyclicTy(_), + }) => self.report_type_parameter_mismatch_cyclic_type_error( &obligation, found_trait_ref, expected_trait_ref, terr, ), - OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => { + OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch { + found_trait_ref, + expected_trait_ref, + terr: _, + }) => { match self.report_type_parameter_mismatch_error( &obligation, span, @@ -1505,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ExprItemObligation(..) | ObligationCauseCode::ExprBindingObligation(..) - | ObligationCauseCode::ObjectCastObligation(..) + | ObligationCauseCode::Coercion { .. } | ObligationCauseCode::OpaqueType ); @@ -1687,13 +1700,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::Tuple(..) => Some(10), ty::Param(..) => Some(11), ty::Alias(ty::Projection, ..) => Some(12), - ty::Alias(ty::Opaque, ..) => Some(13), - ty::Never => Some(14), - ty::Adt(..) => Some(15), - ty::Generator(..) => Some(16), - ty::Foreign(..) => Some(17), - ty::GeneratorWitness(..) => Some(18), - ty::GeneratorWitnessMIR(..) => Some(19), + ty::Alias(ty::Inherent, ..) => Some(13), + ty::Alias(ty::Opaque, ..) => Some(14), + ty::Never => Some(15), + ty::Adt(..) => Some(16), + ty::Generator(..) => Some(17), + ty::Foreign(..) => Some(18), + ty::GeneratorWitness(..) => Some(19), + ty::GeneratorWitnessMIR(..) => Some(20), ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None, } } 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 53bf38c0a34..ea17f23434b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, self_ty: Ty<'tcx>, - object_ty: Ty<'tcx>, + target_ty: Ty<'tcx>, ) { + let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else { return; }; let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; }; let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty); @@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_suggestion( obligation.cause.span.shrink_to_lo(), format!( - "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`" + "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`" ), "&", Applicability::MaybeIncorrect, @@ -2446,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) { @@ -2851,30 +2851,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_note(tcx.def_span(item_def_id), descr); } } - ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => { - let (concrete_ty, concrete_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty)); - let (object_ty, object_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty)); + ObligationCauseCode::Coercion { source, target } => { + let (source, source_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(source)); + let (target, target_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(target)); err.note(with_forced_trimmed_paths!(format!( - "required for the cast from `{concrete_ty}` to the object type `{object_ty}`", + "required for the cast from `{source}` to `{target}`", ))); - if let Some(file) = concrete_file { + if let Some(file) = source_file { err.note(format!( - "the full name for the casted type has been written to '{}'", + "the full name for the source type has been written to '{}'", file.display(), )); } - if let Some(file) = object_file { + if let Some(file) = target_file { err.note(format!( - "the full name for the object type has been written to '{}'", + "the full name for the target type has been written to '{}'", file.display(), )); } } - ObligationCauseCode::Coercion { source: _, target } => { - err.note(format!("required by cast to type `{}`", self.ty_to_string(target))); - } ObligationCauseCode::RepeatElementCopy { is_const_fn } => { err.note( "the `Copy` trait is required because this value will be copied for each element of the array", 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 d8e5725d3ca..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}; @@ -49,12 +50,15 @@ pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::ObjectSafetyViolation; -pub use self::project::{normalize_projection_type, NormalizeExt}; +pub use self::project::NormalizeExt; +pub use self::project::{normalize_inherent_projection, normalize_projection_type}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::specialization_graph::FutureCompatOverlapError; pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; -pub use self::specialize::{specialization_graph, translate_substs, OverlapError}; +pub use self::specialize::{ + specialization_graph, translate_substs, translate_substs_with_cause, OverlapError, +}; pub use self::structural_match::{ search_for_adt_const_param_violation, search_for_structural_match_violation, }; @@ -495,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/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 8c74860cdf3..8e684b7ac23 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -16,6 +16,7 @@ use super::{ }; use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; +use crate::errors::InherentProjectionNormalizationOverflow; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::traits::error_reporting::TypeErrCtxtExt as _; @@ -370,10 +371,14 @@ pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( reveal: Reveal, ) -> bool { match reveal { - Reveal::UserFacing => value - .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION), + Reveal::UserFacing => value.has_type_flags( + ty::TypeFlags::HAS_TY_PROJECTION + | ty::TypeFlags::HAS_TY_INHERENT + | ty::TypeFlags::HAS_CT_PROJECTION, + ), Reveal::All => value.has_type_flags( ty::TypeFlags::HAS_TY_PROJECTION + | ty::TypeFlags::HAS_TY_INHERENT | ty::TypeFlags::HAS_TY_OPAQUE | ty::TypeFlags::HAS_CT_PROJECTION, ), @@ -616,6 +621,51 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx ); normalized_ty } + + ty::Inherent if !data.has_escaping_bound_vars() => { + // This branch is *mostly* just an optimization: when we don't + // have escaping bound vars, we don't need to replace them with + // placeholders (see branch below). *Also*, we know that we can + // register an obligation to *later* project, since we know + // there won't be bound vars there. + + let data = data.fold_with(self); + + // FIXME(inherent_associated_types): Do we need to honor `self.eager_inference_replacement` + // here like `ty::Projection`? + normalize_inherent_projection( + self.selcx, + self.param_env, + data, + self.cause.clone(), + self.depth, + &mut self.obligations, + ) + } + + ty::Inherent => { + let infcx = self.selcx.infcx; + let (data, mapped_regions, mapped_types, mapped_consts) = + BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); + let data = data.fold_with(self); + let ty = normalize_inherent_projection( + self.selcx, + self.param_env, + data, + self.cause.clone(), + self.depth, + &mut self.obligations, + ); + + PlaceholderReplacer::replace_placeholders( + infcx, + mapped_regions, + mapped_types, + mapped_consts, + &self.universes, + ty, + ) + } } } @@ -1204,6 +1254,115 @@ fn normalize_to_error<'a, 'tcx>( Normalized { value: new_value, obligations: vec![trait_obligation] } } +/// Confirm and normalize the given inherent projection. +#[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] +pub fn normalize_inherent_projection<'a, 'b, 'tcx>( + selcx: &'a mut SelectionContext<'b, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + alias_ty: ty::AliasTy<'tcx>, + cause: ObligationCause<'tcx>, + depth: usize, + obligations: &mut Vec<PredicateObligation<'tcx>>, +) -> Ty<'tcx> { + let tcx = selcx.tcx(); + + if !tcx.recursion_limit().value_within_limit(depth) { + // Halt compilation because it is important that overflows never be masked. + tcx.sess.emit_fatal(InherentProjectionNormalizationOverflow { + span: cause.span, + ty: alias_ty.to_string(), + }); + } + + let substs = compute_inherent_assoc_ty_substs( + selcx, + param_env, + alias_ty, + cause.clone(), + depth, + obligations, + ); + + // Register the obligations arising from the impl and from the associated type itself. + let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, substs); + for (predicate, span) in predicates { + let predicate = normalize_with_depth_to( + selcx, + param_env, + cause.clone(), + depth + 1, + predicate, + obligations, + ); + + let nested_cause = ObligationCause::new( + cause.span, + cause.body_id, + // FIXME(inherent_associated_types): Since we can't pass along the self type to the + // cause code, inherent projections will be printed with identity substitutions in + // diagnostics which is not ideal. + // Consider creating separate cause codes for this specific situation. + if span.is_dummy() { + super::ItemObligation(alias_ty.def_id) + } else { + super::BindingObligation(alias_ty.def_id, span) + }, + ); + + obligations.push(Obligation::with_depth( + tcx, + nested_cause, + depth + 1, + param_env, + predicate, + )); + } + + let ty = tcx.type_of(alias_ty.def_id).subst(tcx, substs); + + let mut ty = selcx.infcx.resolve_vars_if_possible(ty); + if ty.has_projections() { + ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations); + } + + ty +} + +pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>( + selcx: &'a mut SelectionContext<'b, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + alias_ty: ty::AliasTy<'tcx>, + cause: ObligationCause<'tcx>, + depth: usize, + obligations: &mut Vec<PredicateObligation<'tcx>>, +) -> ty::SubstsRef<'tcx> { + let tcx = selcx.tcx(); + + let impl_def_id = tcx.parent(alias_ty.def_id); + let impl_substs = selcx.infcx.fresh_substs_for_item(cause.span, impl_def_id); + + let impl_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs); + let impl_ty = + normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations); + + // Infer the generic parameters of the impl by unifying the + // impl type with the self type of the projection. + let self_ty = alias_ty.self_ty(); + match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) { + Ok(mut ok) => obligations.append(&mut ok.obligations), + Err(_) => { + tcx.sess.delay_span_bug( + cause.span, + format!( + "{self_ty:?} was a subtype of {impl_ty:?} during selection but now it is not" + ), + ); + } + } + + alias_ty.rebase_substs_onto_impl(impl_substs, tcx) +} + enum Projected<'tcx> { Progress(Progress<'tcx>), NoProgress(ty::Term<'tcx>), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a986a9b6a71..8bf934cb78a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -257,11 +257,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> ty::Opaque => ty.try_super_fold_with(self)?, - ty::Projection => { + ty::Projection | ty::Inherent => { // See note in `rustc_trait_selection::traits::project` - let tcx = self.infcx.tcx; let infcx = self.infcx; + let tcx = infcx.tcx; // Just an optimization: When we don't have escaping bound vars, // we don't need to replace them with placeholders. let (data, maps) = if data.has_escaping_bound_vars() { @@ -276,12 +276,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, // so we cannot canonicalize it. - let c_data = self - .infcx + let c_data = infcx .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); - let result = tcx.normalize_projection_ty(c_data)?; + let result = match kind { + ty::Projection => tcx.normalize_projection_ty(c_data), + ty::Inherent => tcx.normalize_inherent_projection_ty(c_data), + _ => unreachable!(), + }?; // We don't expect ambiguity. if result.is_ambiguous() { // Rustdoc normalizes possibly not well-formed types, so only @@ -294,8 +297,8 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> } return Err(NoSolution); } - let InferOk { value: result, obligations } = - self.infcx.instantiate_query_response_and_region_obligations( + let InferOk { value: result, obligations } = infcx + .instantiate_query_response_and_region_obligations( self.cause, self.param_env, &orig_values, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 33f502f8182..a8fb55df2d3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -498,7 +498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // this trait and type. } ty::Param(..) - | ty::Alias(ty::Projection, ..) + | ty::Alias(ty::Projection | ty::Inherent, ..) | ty::Placeholder(..) | ty::Bound(..) => { // In these cases, we don't know what the actual diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 422285d9474..6a648294efd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -10,6 +10,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::traits::SelectionOutputTypeParameterMismatch; use rustc_middle::ty::{ self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt, @@ -28,9 +29,9 @@ use crate::traits::{ ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData, - ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, - Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, - SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, + ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation, + ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, + TraitNotObjectSafe, TraitObligation, Unimplemented, }; use super::BuiltinImplConditions; @@ -811,7 +812,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_poly_trait_refs( &mut self, obligation: &TraitObligation<'tcx>, - expected_trait_ref: ty::PolyTraitRef<'tcx>, + self_ty_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); // Normalize the obligation and expected trait refs together, because why not @@ -822,7 +823,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - (obligation_trait_ref, expected_trait_ref), + (obligation_trait_ref, self_ty_trait_ref), ) }); @@ -834,7 +835,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.extend(nested); obligations }) - .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) + .map_err(|terr| { + OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch { + expected_trait_ref: obligation_trait_ref, + found_trait_ref: expected_trait_ref, + terr, + })) + }) } fn confirm_trait_upcasting_unsize_candidate( @@ -898,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map_err(|_| Unimplemented)?; nested.extend(obligations); - // Register one obligation for 'a: 'b. - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( tcx, - cause, + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, obligation.predicate.rebind(outlives), @@ -998,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested.extend(obligations); // Register one obligation for 'a: 'b. - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( tcx, - cause, + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, obligation.predicate.rebind(outlives), @@ -1020,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(TraitNotObjectSafe(did)); } - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); - let predicate_to_obligation = |predicate| { Obligation::with_depth( tcx, - cause.clone(), + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, predicate, @@ -1049,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]); + let tr = ty::TraitRef::from_lang_item( + tcx, + LangItem::Sized, + obligation.cause.span, + [source], + ); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type @@ -1268,7 +1263,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If we have a projection type, make sure to normalize it so we replace it // with a fresh infer variable - ty::Alias(ty::Projection, ..) => { + ty::Alias(ty::Projection | ty::Inherent, ..) => { let predicate = normalize_with_depth_to( self, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 246d3ea2ef2..b72ff5b78e4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2315,7 +2315,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) - | ty::Alias(ty::Projection, ..) + | ty::Alias(ty::Projection | ty::Inherent, ..) | ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { bug!("asked to assemble constituent types of unexpected type: {:?}", t); @@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let predicates = predicates.instantiate_own(tcx, substs); let mut obligations = Vec::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { - let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { - ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_or_alias_def_id: def_id, - impl_def_predicate_index: Some(index), - span, - })) - }); + let cause = + if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() { + cause.clone() + } else { + cause.clone().derived_cause(parent_trait_pred, |derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_or_alias_def_id: def_id, + impl_def_predicate_index: Some(index), + span, + })) + }) + }; let predicate = normalize_with_depth_to( self, param_env, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 233d35aed38..9a4b72013b8 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -83,6 +83,30 @@ pub fn translate_substs<'tcx>( source_substs: SubstsRef<'tcx>, target_node: specialization_graph::Node, ) -> SubstsRef<'tcx> { + translate_substs_with_cause( + infcx, + param_env, + source_impl, + source_substs, + target_node, + |_, _| ObligationCause::dummy(), + ) +} + +/// Like [translate_substs], but obligations from the parent implementation +/// are registered with the provided `ObligationCause`. +/// +/// This is for reporting *region* errors from those bounds. Type errors should +/// not happen because the specialization graph already checks for those, and +/// will result in an ICE. +pub fn translate_substs_with_cause<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + source_impl: DefId, + source_substs: SubstsRef<'tcx>, + target_node: specialization_graph::Node, + cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, +) -> SubstsRef<'tcx> { debug!( "translate_substs({:?}, {:?}, {:?}, {:?})", param_env, source_impl, source_substs, target_node @@ -99,14 +123,13 @@ pub fn translate_substs<'tcx>( return source_substs; } - fulfill_implication(infcx, param_env, source_trait_ref, target_impl).unwrap_or_else( - |()| { + fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause) + .unwrap_or_else(|()| { bug!( "When translating substitutions from {source_impl:?} to {target_impl:?}, \ the expected specialization failed to hold" ) - }, - ) + }) } specialization_graph::Node::Trait(..) => source_trait_ref.substs, }; @@ -153,20 +176,12 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, // Create an infcx, taking the predicates of impl1 as assumptions: let infcx = tcx.infer_ctxt().build(); - let impl1_trait_ref = - match traits::fully_normalize(&infcx, ObligationCause::dummy(), penv, impl1_trait_ref) { - Ok(impl1_trait_ref) => impl1_trait_ref, - Err(_errors) => { - tcx.sess.delay_span_bug( - tcx.def_span(impl1_def_id), - format!("failed to fully normalize {impl1_trait_ref}"), - ); - impl1_trait_ref - } - }; // Attempt to prove that impl2 applies, given all of the above. - fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok() + fulfill_implication(&infcx, penv, impl1_trait_ref, impl1_def_id, impl2_def_id, |_, _| { + ObligationCause::dummy() + }) + .is_ok() } /// Attempt to fulfill all obligations of `target_impl` after unification with @@ -178,23 +193,41 @@ fn fulfill_implication<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, source_trait_ref: ty::TraitRef<'tcx>, + source_impl: DefId, target_impl: DefId, + error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, ) -> Result<SubstsRef<'tcx>, ()> { debug!( "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", param_env, source_trait_ref, target_impl ); + let source_trait_ref = match traits::fully_normalize( + &infcx, + ObligationCause::dummy(), + param_env, + source_trait_ref, + ) { + Ok(source_trait_ref) => source_trait_ref, + Err(_errors) => { + infcx.tcx.sess.delay_span_bug( + infcx.tcx.def_span(source_impl), + format!("failed to fully normalize {source_trait_ref}"), + ); + source_trait_ref + } + }; + let source_trait = ImplSubject::Trait(source_trait_ref); let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); let (target_trait, obligations) = - util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs); + util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs, error_cause); // do the impls unify? If not, no specialization. let Ok(InferOk { obligations: more_obligations, .. }) = - infcx.at(&ObligationCause::dummy(), param_env, ).eq(DefineOpaqueTypes::No,source_trait, target_trait) + infcx.at(&ObligationCause::dummy(), param_env).eq(DefineOpaqueTypes::No, source_trait, target_trait) else { debug!( "fulfill_implication: {:?} does not unify with {:?}", diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 7b7e297c64b..82f3df40198 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -197,6 +197,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( param_env: ty::ParamEnv<'tcx>, impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, + cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, ) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) { let subject = selcx.tcx().impl_subject(impl_def_id); let subject = subject.subst(selcx.tcx(), impl_substs); @@ -208,8 +209,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( let predicates = predicates.instantiate(selcx.tcx(), impl_substs); let InferOk { value: predicates, obligations: normalization_obligations2 } = selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates); - let impl_obligations = - super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates); + let impl_obligations = super::predicates_for_generics(cause, param_env, predicates); let impl_obligations = impl_obligations .chain(normalization_obligations1.into_iter()) 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_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 22710c7c059..086ab32b520 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -58,15 +58,8 @@ pub fn obligations<'tcx>( GenericArgKind::Lifetime(..) => return Some(Vec::new()), }; - let mut wf = WfPredicates { - tcx: infcx.tcx, - param_env, - body_id, - span, - out: vec![], - recursion_depth, - item: None, - }; + let mut wf = + WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None }; wf.compute(arg); debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out); @@ -91,7 +84,7 @@ pub fn unnormalized_obligations<'tcx>( debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); let mut wf = WfPredicates { - tcx: infcx.tcx, + infcx, param_env, body_id: CRATE_DEF_ID, span: DUMMY_SP, @@ -116,7 +109,7 @@ pub fn trait_obligations<'tcx>( item: &'tcx hir::Item<'tcx>, ) -> Vec<traits::PredicateObligation<'tcx>> { let mut wf = WfPredicates { - tcx: infcx.tcx, + infcx, param_env, body_id, span, @@ -138,7 +131,7 @@ pub fn predicate_obligations<'tcx>( span: Span, ) -> Vec<traits::PredicateObligation<'tcx>> { let mut wf = WfPredicates { - tcx: infcx.tcx, + infcx, param_env, body_id, span, @@ -190,8 +183,8 @@ pub fn predicate_obligations<'tcx>( wf.normalize(infcx) } -struct WfPredicates<'tcx> { - tcx: TyCtxt<'tcx>, +struct WfPredicates<'a, 'tcx> { + infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, span: Span, @@ -290,9 +283,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>( } } -impl<'tcx> WfPredicates<'tcx> { +impl<'a, 'tcx> WfPredicates<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx + self.infcx.tcx } fn cause(&self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> { @@ -325,7 +318,7 @@ impl<'tcx> WfPredicates<'tcx> { /// Pushes the obligations required for `trait_ref` to be WF into `self.out`. fn compute_trait_pred(&mut self, trait_pred: &ty::TraitPredicate<'tcx>, elaborate: Elaborate) { - let tcx = self.tcx; + let tcx = self.tcx(); let trait_ref = &trait_pred.trait_ref; // Negative trait predicates don't require supertraits to hold, just @@ -369,7 +362,6 @@ impl<'tcx> WfPredicates<'tcx> { self.out.extend(obligations); } - let tcx = self.tcx(); self.out.extend( trait_ref .substs @@ -436,13 +428,45 @@ impl<'tcx> WfPredicates<'tcx> { let obligations = self.nominal_obligations_without_const(data.def_id, data.substs); self.out.extend(obligations); + self.compute_projection_substs(data.substs); + } + + fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) { + // An inherent projection is well-formed if + // + // (a) its predicates hold (*) + // (b) its substs are wf + // + // (*) The predicates of an inherent associated type include the + // predicates of the impl that it's contained in. + + if !data.self_ty().has_escaping_bound_vars() { + // FIXME(inherent_associated_types): Should this happen inside of a snapshot? + // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm! + let substs = traits::project::compute_inherent_assoc_ty_substs( + &mut traits::SelectionContext::new(self.infcx), + self.param_env, + data, + self.cause(traits::WellFormed(None)), + self.recursion_depth, + &mut self.out, + ); + // Inherent projection types do not require const predicates. + let obligations = self.nominal_obligations_without_const(data.def_id, substs); + self.out.extend(obligations); + } + + self.compute_projection_substs(data.substs); + } + + fn compute_projection_substs(&mut self, substs: SubstsRef<'tcx>) { let tcx = self.tcx(); let cause = self.cause(traits::WellFormed(None)); let param_env = self.param_env; let depth = self.recursion_depth; self.out.extend( - data.substs + substs .iter() .filter(|arg| { matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..)) @@ -464,9 +488,9 @@ impl<'tcx> WfPredicates<'tcx> { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); let trait_ref = - ty::TraitRef::from_lang_item(self.tcx, LangItem::Sized, cause.span, [subty]); + ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [subty]); self.out.push(traits::Obligation::with_depth( - self.tcx, + self.tcx(), cause, self.recursion_depth, self.param_env, @@ -605,6 +629,10 @@ impl<'tcx> WfPredicates<'tcx> { walker.skip_current_subtree(); // Subtree handled by compute_projection. self.compute_projection(data); } + ty::Alias(ty::Inherent, data) => { + walker.skip_current_subtree(); // Subtree handled by compute_inherent_projection. + self.compute_inherent_projection(data); + } ty::Adt(def, substs) => { // WfNominalType @@ -697,7 +725,7 @@ impl<'tcx> WfPredicates<'tcx> { // All of the requirements on type parameters // have already been checked for `impl Trait` in // return position. We do need to check type-alias-impl-trait though. - if self.tcx.is_type_alias_impl_trait(def_id) { + if self.tcx().is_type_alias_impl_trait(def_id) { let obligations = self.nominal_obligations(def_id, substs); self.out.extend(obligations); } @@ -767,15 +795,15 @@ impl<'tcx> WfPredicates<'tcx> { substs: SubstsRef<'tcx>, remap_constness: bool, ) -> Vec<traits::PredicateObligation<'tcx>> { - let predicates = self.tcx.predicates_of(def_id); + let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; while let Some(parent) = head.parent { - head = self.tcx.predicates_of(parent); + head = self.tcx().predicates_of(parent); origins.extend(iter::repeat(parent).take(head.predicates.len())); } - let predicates = predicates.instantiate(self.tcx, substs); + let predicates = predicates.instantiate(self.tcx(), substs); trace!("{:#?}", predicates); debug_assert_eq!(predicates.predicates.len(), origins.len()); @@ -788,10 +816,10 @@ impl<'tcx> WfPredicates<'tcx> { }; let cause = self.cause(code); if remap_constness { - pred = pred.without_const(self.tcx); + pred = pred.without_const(self.tcx()); } traits::Obligation::with_depth( - self.tcx, + self.tcx(), cause, self.recursion_depth, self.param_env, @@ -856,7 +884,7 @@ impl<'tcx> WfPredicates<'tcx> { // Note: in fact we only permit builtin traits, not `Bar<'d>`, I // am looking forward to the future here. if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() { - let implicit_bounds = object_region_bounds(self.tcx, data); + let implicit_bounds = object_region_bounds(self.tcx(), data); let explicit_bound = region; @@ -866,7 +894,7 @@ impl<'tcx> WfPredicates<'tcx> { let outlives = ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound)); self.out.push(traits::Obligation::with_depth( - self.tcx, + self.tcx(), cause, self.recursion_depth, self.param_env, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 4d225e36b22..2f9e480d8bd 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -372,6 +372,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { substitution: substs.lower_into(interner), })) } + ty::Alias(ty::Inherent, _) => unimplemented!(), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id: chalk_ir::OpaqueTyId(def_id), 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 e805eb42821..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::{ @@ -10,7 +10,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext}; use std::sync::atomic::Ordering; pub(crate) fn provide(p: &mut Providers) { - *p = Providers { normalize_projection_ty, ..*p }; + *p = Providers { normalize_projection_ty, normalize_inherent_projection_ty, ..*p }; } fn normalize_projection_ty<'tcx>( @@ -42,3 +42,30 @@ fn normalize_projection_ty<'tcx>( }, ) } + +fn normalize_inherent_projection_ty<'tcx>( + tcx: TyCtxt<'tcx>, + goal: CanonicalProjectionGoal<'tcx>, +) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>, NoSolution> { + debug!("normalize_provider(goal={:#?})", goal); + + tcx.infer_ctxt().enter_canonical_trait_query( + &goal, + |ocx, ParamEnvAnd { param_env, value: goal }| { + let selcx = &mut SelectionContext::new(ocx.infcx); + let cause = ObligationCause::dummy(); + let mut obligations = vec![]; + let answer = traits::normalize_inherent_projection( + selcx, + param_env, + goal, + cause, + 0, + &mut obligations, + ); + ocx.register_obligations(obligations); + + Ok(NormalizationResult { normalized_ty: answer }) + }, + ) +} 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/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index 15a14112f4a..5bc3e3c00c9 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -55,3 +55,11 @@ ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes} ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` + +ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope + .label = generic argument `{$arg}` used twice + .note = for this opaque type + +ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope + .label = argument `{$arg}` is not a generic parameter + .note = for this opaque type 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 b08a92570ed..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") } @@ -394,7 +393,7 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { pub fn thir_abstract_const( tcx: TyCtxt<'_>, def: LocalDefId, -) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> { +) -> Result<Option<ty::EarlyBinder<ty::Const<'_>>>, ErrorGuaranteed> { if !tcx.features().generic_const_exprs { return Ok(None); } @@ -420,9 +419,9 @@ pub fn thir_abstract_const( let root_span = body.exprs[body_id].span; - Some(recurse_build(tcx, body, body_id, root_span)).transpose() + 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/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 3d3fc50e6e5..553bf40ef3a 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by ty_utils use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{GenericArg, Ty}; use rustc_span::Span; #[derive(Diagnostic)] @@ -100,3 +100,25 @@ pub struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_duplicate_arg)] +pub struct DuplicateArg<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_not_param)] +pub struct NotParam<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 56d6cc28bc8..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<'_>> { @@ -31,6 +32,18 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { } } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), + DefKind::OpaqueTy => match tcx.def_kind(tcx.parent(def_id)) { + DefKind::TyAlias => ty::List::empty(), + DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), + // Nested opaque types only occur in associated types: + // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; ` + // assumed_wf_types should include those of `Opaque<T>`, `Opaque<T>` itself + // and `&'static T`. + DefKind::OpaqueTy => bug!("unimplemented implied bounds for neseted opaque types"), + def_kind @ _ => { + bug!("unimplemented implied bounds for opaque types with parent {def_kind:?}") + } + }, DefKind::Mod | DefKind::Struct | DefKind::Union @@ -51,7 +64,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { | DefKind::ForeignMod | DefKind::AnonConst | DefKind::InlineConst - | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder | DefKind::Field | DefKind::LifetimeParam diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index ec577072e19..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}; @@ -194,21 +195,18 @@ fn resolve_associated_item<'tcx>( }) } traits::ImplSource::Future(future_data) => { - if cfg!(debug_assertions) && tcx.item_name(trait_item_id) != sym::poll { - // For compiler developers who'd like to add new items to `Future`, - // you either need to generate a shim body, or perhaps return - // `InstanceDef::Item` pointing to a trait default method body if - // it is given a default implementation by the trait. - span_bug!( - tcx.def_span(future_data.generator_def_id), - "no definition for `{trait_ref}::{}` for built-in async generator type", - tcx.item_name(trait_item_id) - ) + if Some(trait_item_id) == tcx.lang_items().future_poll_fn() { + // `Future::poll` is generated by the compiler. + Some(Instance { + def: ty::InstanceDef::Item(future_data.generator_def_id), + substs: future_data.substs, + }) + } else { + // All other methods are default methods of the `Future` trait. + // (this assumes that `ImplSource::Future` is only used for methods on `Future`) + debug_assert!(tcx.impl_defaultness(trait_item_id).has_value()); + Some(Instance::new(trait_item_id, rcvr_substs)) } - Some(Instance { - def: ty::InstanceDef::Item(future_data.generator_def_id), - substs: future_data.substs, - }) } traits::ImplSource::Closure(closure_data) => { if cfg!(debug_assertions) @@ -322,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 73a2f6af579..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; @@ -33,6 +33,7 @@ pub mod instance; mod layout; mod layout_sanity_check; mod needs_drop; +mod opaque_types; pub mod representability; mod structural_match; mod ty; @@ -47,6 +48,7 @@ pub fn provide(providers: &mut Providers) { implied_bounds::provide(providers); layout::provide(providers); needs_drop::provide(providers); + opaque_types::provide(providers); representability::provide(providers); ty::provide(providers); instance::provide(providers); 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 new file mode 100644 index 00000000000..4e91dd380e8 --- /dev/null +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -0,0 +1,198 @@ +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}; +use rustc_span::Span; +use rustc_type_ir::AliasKind; +use std::ops::ControlFlow; + +use crate::errors::{DuplicateArg, NotParam}; + +struct OpaqueTypeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + opaques: Vec<LocalDefId>, + /// The `DefId` of the item which we are collecting opaque types for. + item: LocalDefId, + + /// Avoid infinite recursion due to recursive declarations. + seen: FxHashSet<LocalDefId>, +} + +impl<'tcx> OpaqueTypeCollector<'tcx> { + fn collect( + tcx: TyCtxt<'tcx>, + item: LocalDefId, + val: ty::Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>, + ) -> Vec<LocalDefId> { + let mut collector = Self { tcx, opaques: Vec::new(), item, seen: Default::default() }; + val.skip_binder().visit_with(&mut collector); + collector.opaques + } + + fn span(&self) -> Span { + self.tcx.def_span(self.item) + } + + fn parent(&self) -> Option<LocalDefId> { + match self.tcx.def_kind(self.item) { + DefKind::Fn => None, + DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + Some(self.tcx.local_parent(self.item)) + } + other => span_bug!( + self.tcx.def_span(self.item), + "unhandled item with opaque types: {other:?}" + ), + } + } +} + +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { + type BreakTy = ErrorGuaranteed; + + #[instrument(skip(self), ret, level = "trace")] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<ErrorGuaranteed> { + match t.kind() { + ty::Alias(AliasKind::Opaque, alias_ty) if alias_ty.def_id.is_local() => { + if !self.seen.insert(alias_ty.def_id.expect_local()) { + return ControlFlow::Continue(()); + } + match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) { + Ok(()) => { + // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not + // supported at all, so this is sound to do, but once we want to support them, you'll + // start seeing the error below. + + self.opaques.push(alias_ty.def_id.expect_local()); + + // Collect opaque types nested within the associated type bounds of this opaque type. + for (pred, _span) in self + .tcx + .explicit_item_bounds(alias_ty.def_id) + .subst_iter_copied(self.tcx, alias_ty.substs) + { + trace!(?pred); + pred.visit_with(self)?; + } + + ControlFlow::Continue(()) + } + Err(NotUniqueParam::NotParam(arg)) => { + let err = self.tcx.sess.emit_err(NotParam { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) + } + Err(NotUniqueParam::DuplicateParam(arg)) => { + let err = self.tcx.sess.emit_err(DuplicateArg { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) + } + } + } + ty::Alias(AliasKind::Projection, alias_ty) => { + if let Some(parent) = self.parent() { + trace!(?alias_ty); + let (trait_ref, own_substs) = alias_ty.trait_ref_and_own_substs(self.tcx); + + trace!(?trait_ref, ?own_substs); + // This avoids having to do normalization of `Self::AssocTy` by only + // supporting the case of a method defining opaque types from assoc types + // in the same impl block. + if trait_ref.self_ty() == self.tcx.type_of(parent).subst_identity() { + for assoc in self.tcx.associated_items(parent).in_definition_order() { + trace!(?assoc); + if assoc.trait_item_def_id == Some(alias_ty.def_id) { + // We reconstruct the generic args of the associated type within the impl + // from the impl's generics and the generic args passed to the type via the + // projection. + let substs = ty::InternalSubsts::identity_for_item( + self.tcx, + parent.to_def_id(), + ); + trace!(?substs); + let substs: Vec<_> = + substs.iter().chain(own_substs.iter().copied()).collect(); + trace!(?substs); + // Find opaque types in this associated type. + return self + .tcx + .type_of(assoc.def_id) + .subst(self.tcx, &substs) + .visit_with(self); + } + } + } + } + t.super_visit_with(self) + } + _ => t.super_visit_with(self), + } + } +} + +fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { + let kind = tcx.def_kind(item); + trace!(?kind); + // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types. + match kind { + // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` + DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + let defined_opaques = match kind { + DefKind::Fn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocFn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocTy | DefKind::AssocConst => OpaqueTypeCollector::collect( + tcx, + item, + ty::Binder::dummy(tcx.type_of(item).subst_identity()), + ), + _ => unreachable!(), + }; + tcx.arena.alloc_from_iter(defined_opaques) + } + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::TyParam + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(_) + | DefKind::Ctor(_, _) + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Impl { .. } + | DefKind::Closure + | DefKind::Generator => &[], + } +} + +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/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 1e91e26e2af..f6b44bdf27e 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -229,29 +229,32 @@ bitflags! { /// Does this have `Projection`? const HAS_TY_PROJECTION = 1 << 10; + /// Does this have `Inherent`? + const HAS_TY_INHERENT = 1 << 11; /// Does this have `Opaque`? - const HAS_TY_OPAQUE = 1 << 11; + const HAS_TY_OPAQUE = 1 << 12; /// Does this have `ConstKind::Unevaluated`? - const HAS_CT_PROJECTION = 1 << 12; + const HAS_CT_PROJECTION = 1 << 13; /// Could this type be normalized further? const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits | TypeFlags::HAS_TY_OPAQUE.bits + | TypeFlags::HAS_TY_INHERENT.bits | TypeFlags::HAS_CT_PROJECTION.bits; /// Is an error type/const reachable? - const HAS_ERROR = 1 << 13; + const HAS_ERROR = 1 << 14; /// Does this have any region that "appears free" in the type? /// Basically anything but `ReLateBound` and `ReErased`. - const HAS_FREE_REGIONS = 1 << 14; + const HAS_FREE_REGIONS = 1 << 15; /// Does this have any `ReLateBound` regions? - const HAS_RE_LATE_BOUND = 1 << 15; + const HAS_RE_LATE_BOUND = 1 << 16; /// Does this have any `Bound` types? - const HAS_TY_LATE_BOUND = 1 << 16; + const HAS_TY_LATE_BOUND = 1 << 17; /// Does this have any `ConstKind::Bound` consts? - const HAS_CT_LATE_BOUND = 1 << 17; + const HAS_CT_LATE_BOUND = 1 << 18; /// Does this have any bound variables? /// Used to check if a global bound is safe to evaluate. const HAS_LATE_BOUND = TypeFlags::HAS_RE_LATE_BOUND.bits @@ -259,20 +262,20 @@ bitflags! { | TypeFlags::HAS_CT_LATE_BOUND.bits; /// Does this have any `ReErased` regions? - const HAS_RE_ERASED = 1 << 18; + const HAS_RE_ERASED = 1 << 19; /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? - const STILL_FURTHER_SPECIALIZABLE = 1 << 19; + const STILL_FURTHER_SPECIALIZABLE = 1 << 20; /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`? - const HAS_TY_FRESH = 1 << 20; + const HAS_TY_FRESH = 1 << 21; /// Does this value have `InferConst::Fresh`? - const HAS_CT_FRESH = 1 << 21; + const HAS_CT_FRESH = 1 << 22; /// Does this have `Generator` or `GeneratorWitness`? - const HAS_TY_GENERATOR = 1 << 22; + const HAS_TY_GENERATOR = 1 << 23; } } @@ -640,7 +643,7 @@ impl UnifyKey for FloatVid { } } -#[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash, HashStable_Generic)] +#[derive(Copy, Clone, PartialEq, Eq, Decodable, Encodable, Hash, HashStable_Generic)] #[rustc_pass_by_value] pub enum Variance { Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type 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/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 4c1f2dd0e53..f7344bacc02 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -37,6 +37,7 @@ pub enum DynKind { #[derive(Encodable, Decodable, HashStable_Generic)] pub enum AliasKind { Projection, + Inherent, Opaque, } diff --git a/config.example.toml b/config.example.toml index 6d9c762ceca..d0eaa9fd7ff 100644 --- a/config.example.toml +++ b/config.example.toml @@ -750,6 +750,10 @@ changelog-seen = 2 # This option will override the same option under [build] section. #profiler = build.profiler (bool) +# This option supports enable `rpath` in each target independently, +# and will override the same option under [rust] section. It only works on Unix platforms +#rpath = rust.rpath (bool) + # Force static or dynamic linkage of the standard library for this target. If # this target is a host for rustc, this will also affect the linkage of the # compiler itself. This is useful for building rustc on targets that normally 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/lib.rs b/library/alloc/src/lib.rs index 18f25aec5fe..59fa91c1066 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -113,7 +113,6 @@ #![feature(const_maybe_uninit_write)] #![feature(const_maybe_uninit_zeroed)] #![feature(const_pin)] -#![feature(const_ptr_read)] #![feature(const_refs_to_cell)] #![feature(const_size_of_val)] #![feature(const_waker)] 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..744767aae44 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2030,6 +2030,27 @@ impl<T> UnsafeCell<T> { } impl<T: ?Sized> UnsafeCell<T> { + /// Converts from `&mut T` to `&mut UnsafeCell<T>`. + /// + /// # Examples + /// + /// ``` + /// # #![feature(unsafe_cell_from_mut)] + /// use std::cell::UnsafeCell; + /// + /// let mut val = 42; + /// let uc = UnsafeCell::from_mut(&mut val); + /// + /// *uc.get_mut() -= 1; + /// assert_eq!(*uc.get_mut(), 41); + /// ``` + #[inline(always)] + #[unstable(feature = "unsafe_cell_from_mut", issue = "111645")] + pub const fn from_mut(value: &mut T) -> &mut UnsafeCell<T> { + // SAFETY: `UnsafeCell<T>` has the same memory layout as `T` due to #[repr(transparent)]. + unsafe { &mut *(value as *mut T as *mut UnsafeCell<T>) } + } + /// Gets a mutable pointer to the wrapped value. /// /// This can be cast to a pointer of any kind. @@ -2100,6 +2121,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/cmp.rs b/library/core/src/cmp.rs index 48b127716f5..faf48ae570f 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1412,6 +1412,7 @@ mod impls { #[unstable(feature = "never_type", issue = "35121")] impl PartialEq for ! { + #[inline] fn eq(&self, _: &!) -> bool { *self } @@ -1422,6 +1423,7 @@ mod impls { #[unstable(feature = "never_type", issue = "35121")] impl PartialOrd for ! { + #[inline] fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } @@ -1429,6 +1431,7 @@ mod impls { #[unstable(feature = "never_type", issue = "35121")] impl Ord for ! { + #[inline] fn cmp(&self, _: &!) -> Ordering { *self } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 3ae787cac71..38a6d1ccdb5 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -915,6 +915,7 @@ impl Ord for Infallible { #[stable(feature = "convert_infallible", since = "1.34.0")] impl From<!> for Infallible { + #[inline] fn from(x: !) -> Self { x } diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 07b11814f96..201bacb28c7 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -517,8 +517,6 @@ impl CStr { /// # Examples /// /// ``` - /// #![feature(cstr_is_empty)] - /// /// use std::ffi::CStr; /// # use std::ffi::FromBytesWithNulError; /// @@ -533,7 +531,8 @@ impl CStr { /// # } /// ``` #[inline] - #[unstable(feature = "cstr_is_empty", issue = "102444")] + #[stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")] pub const fn is_empty(&self) -> bool { // SAFETY: We know there is at least one byte; for empty strings it // is the NUL terminator. 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/fmt/mod.rs b/library/core/src/fmt/mod.rs index aa829edd5b0..bac2f31878b 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2267,6 +2267,7 @@ fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperEx #[unstable(feature = "never_type", issue = "35121")] impl Debug for ! { + #[inline] fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self } @@ -2274,6 +2275,7 @@ impl Debug for ! { #[unstable(feature = "never_type", issue = "35121")] impl Display for ! { + #[inline] fn fmt(&self, _: &mut Formatter<'_>) -> Result { *self } diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 0596f6c30ce..d37888c27bd 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -152,6 +152,21 @@ impl<'a> Argument<'a> { None } } + + /// Used by `format_args` when all arguments are gone after inlining, + /// when using `&[]` would incorrectly allow for a bigger lifetime. + /// + /// This fails without format argument inlining, and that shouldn't be different + /// when the argument is inlined: + /// + /// ```compile_fail,E0716 + /// let f = format_args!("{}", "a"); + /// println!("{f}"); + /// ``` + #[inline(always)] + pub fn none() -> [Self; 0] { + [] + } } /// This struct represents the unsafety of constructing an `Arguments`. diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 077c0fdc380..23ded42fa66 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1187,7 +1187,7 @@ extern "rust-intrinsic" { /// Below are common applications of `transmute` which can be replaced with safer /// constructs. /// - /// Turning raw bytes (`&[u8]`) into `u32`, `f64`, etc.: + /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.: /// /// ``` /// let raw_bytes = [0x78, 0x56, 0x34, 0x12]; @@ -2260,7 +2260,7 @@ extern "rust-intrinsic" { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it /// trivially obeys runtime-MIR rules about derefs in operands. - #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn read_via_copy<T>(ptr: *const T) -> T; @@ -2523,6 +2523,7 @@ macro_rules! assert_unsafe_precondition { } } #[allow(non_snake_case)] + #[inline] const fn comptime$(<$($tt)*>)?($(_:$ty),*) {} ::core::intrinsics::const_eval_select(($($i,)*), comptime, runtime); diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index b4639c07c35..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`]. @@ -263,6 +263,7 @@ pub struct BasicBlock; macro_rules! define { ($name:literal, $( #[ $meta:meta ] )* fn $($sig:tt)*) => { #[rustc_diagnostic_item = $name] + #[inline] $( #[ $meta ] )* pub fn $($sig)* { panic!() } } @@ -278,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/lib.rs b/library/core/src/lib.rs index 3abf66dbe29..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)] @@ -140,7 +141,6 @@ #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_is_null)] -#![feature(const_ptr_read)] #![feature(const_ptr_sub_ptr)] #![feature(const_ptr_write)] #![feature(const_raw_ptr_comparison)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 97f9d01e016..ca45683d3d6 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 @@ -766,16 +766,11 @@ impl<T: ?Sized> !Sync for *mut T {} /// /// ## Ownership and the drop check /// -/// Adding a field of type `PhantomData<T>` indicates that your -/// type owns data of type `T`. This in turn implies that when your -/// type is dropped, it may drop one or more instances of the type -/// `T`. This has bearing on the Rust compiler's [drop check] -/// analysis. +/// The exact interaction of `PhantomData` with drop check **may change in the future**. /// -/// If your struct does not in fact *own* the data of type `T`, it is -/// better to use a reference type, like `PhantomData<&'a T>` -/// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so -/// as not to indicate ownership. +/// Currently, adding a field of type `PhantomData<T>` indicates that your type *owns* data of type +/// `T` in very rare circumstances. This in turn has effects on the Rust compiler's [drop check] +/// analysis. For the exact rules, see the [drop check] documentation. /// /// ## Layout /// @@ -783,7 +778,7 @@ impl<T: ?Sized> !Sync for *mut T {} /// * `size_of::<PhantomData<T>>() == 0` /// * `align_of::<PhantomData<T>>() == 1` /// -/// [drop check]: ../../nomicon/dropck.html +/// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] pub struct PhantomData<T: ?Sized>; @@ -991,6 +986,14 @@ pub trait PointerLike {} #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] pub trait ConstParamTy: StructuralEq {} +/// Derive macro generating an impl of the trait `Copy`. +#[rustc_builtin_macro] +#[unstable(feature = "adt_const_params", issue = "95174")] +#[cfg(not(bootstrap))] +pub macro ConstParamTy($item:item) { + /* compiler built-in */ +} + // FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure` // FIXME(generic_const_parameter_types): handle `ty::Tuple` marker_impls! { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 7d2f2971523..289305253ec 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -968,6 +968,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T { /// Integers and other types implementing [`Copy`] are unaffected by `drop`. /// /// ``` +/// # #![cfg_attr(not(bootstrap), allow(drop_copy))] /// #[derive(Copy, Clone)] /// struct Foo(u8); /// @@ -1315,9 +1316,9 @@ impl<T> SizedTypeProperties for T {} /// /// assert_eq!(mem::offset_of!(NestedA, b.0), 0); /// ``` -#[unstable(feature = "offset_of", issue = "106655")] -#[rustc_builtin_macro] #[cfg(not(bootstrap))] +#[unstable(feature = "offset_of", issue = "106655")] +#[allow_internal_unstable(builtin_syntax)] pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) { - /* compiler built-in */ + builtin # offset_of($Container, $($fields).+) } diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 2ad0f1dc506..14e99578a7c 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -34,6 +34,7 @@ impl From<Infallible> for TryFromIntError { #[unstable(feature = "never_type", issue = "35121")] impl From<!> for TryFromIntError { + #[inline] fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From<Infallible> for TryFromIntError` above will keep working 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/ops/drop.rs b/library/core/src/ops/drop.rs index a2c3d978cc4..9ebf426be95 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -132,6 +132,74 @@ /// are `Copy` get implicitly duplicated by the compiler, making it very /// hard to predict when, and how often destructors will be executed. As such, /// these types cannot have destructors. +/// +/// ## Drop check +/// +/// Dropping interacts with the borrow checker in subtle ways: when a type `T` is being implicitly +/// dropped as some variable of this type goes out of scope, the borrow checker needs to ensure that +/// calling `T`'s destructor at this moment is safe. In particular, it also needs to be safe to +/// recursively drop all the fields of `T`. For example, it is crucial that code like the following +/// is being rejected: +/// +/// ```compile_fail,E0597 +/// use std::cell::Cell; +/// +/// struct S<'a>(Cell<Option<&'a S<'a>>>, Box<i32>); +/// impl Drop for S<'_> { +/// fn drop(&mut self) { +/// if let Some(r) = self.0.get() { +/// // Print the contents of the `Box` in `r`. +/// println!("{}", r.1); +/// } +/// } +/// } +/// +/// fn main() { +/// // Set up two `S` that point to each other. +/// let s1 = S(Cell::new(None), Box::new(42)); +/// let s2 = S(Cell::new(Some(&s1)), Box::new(42)); +/// s1.0.set(Some(&s2)); +/// // Now they both get dropped. But whichever is the 2nd one +/// // to be dropped will access the `Box` in the first one, +/// // which is a use-after-free! +/// } +/// ``` +/// +/// The Nomicon discusses the need for [drop check in more detail][drop check]. +/// +/// To reject such code, the "drop check" analysis determines which types and lifetimes need to +/// still be live when `T` gets dropped. The exact details of this analysis are not yet +/// stably guaranteed and **subject to change**. Currently, the analysis works as follows: +/// - If `T` has no drop glue, then trivially nothing is required to be live. This is the case if +/// neither `T` nor any of its (recursive) fields have a destructor (`impl Drop`). [`PhantomData`] +/// and [`ManuallyDrop`] are considered to never have a destructor, no matter their field type. +/// - If `T` has drop glue, then, for all types `U` that are *owned* by any field of `T`, +/// recursively add the types and lifetimes that need to be live when `U` gets dropped. The set of +/// owned types is determined by recursively traversing `T`: +/// - Recursively descend through `PhantomData`, `Box`, tuples, and arrays (including arrays of +/// length 0). +/// - Stop at reference and raw pointer types as well as function pointers and function items; +/// they do not own anything. +/// - Stop at non-composite types (type parameters that remain generic in the current context and +/// base types such as integers and `bool`); these types are owned. +/// - When hitting an ADT with `impl Drop`, stop there; this type is owned. +/// - When hitting an ADT without `impl Drop`, recursively descend to its fields. (For an `enum`, +/// consider all fields of all variants.) +/// - Furthermore, if `T` implements `Drop`, then all generic (lifetime and type) parameters of `T` +/// must be live. +/// +/// In the above example, the last clause implies that `'a` must be live when `S<'a>` is dropped, +/// and hence the example is rejected. If we remove the `impl Drop`, the liveness requirement +/// disappears and the example is accepted. +/// +/// There exists an unstable way for a type to opt-out of the last clause; this is called "drop +/// check eyepatch" or `may_dangle`. For more details on this nightly-only feature, see the +/// [discussion in the Nomicon][nomicon]. +/// +/// [`ManuallyDrop`]: crate::mem::ManuallyDrop +/// [`PhantomData`]: crate::marker::PhantomData +/// [drop check]: ../../nomicon/dropck.html +/// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] #[const_trait] 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/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 585b648873a..5ee1b5e4afc 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1195,7 +1195,7 @@ impl<T: ?Sized> *const T { /// /// [`ptr::read`]: crate::ptr::read() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read(self) -> T @@ -1236,7 +1236,7 @@ impl<T: ?Sized> *const T { /// /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read_unaligned(self) -> T diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 4737ff5d756..ecbf4e66fa4 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1133,7 +1133,8 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T { /// [valid]: self#safety #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] +#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] +#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read<T>(src: *const T) -> T { // It would be semantically correct to implement this via `copy_nonoverlapping` @@ -1249,7 +1250,8 @@ pub const unsafe fn read<T>(src: *const T) -> T { /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] -#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] +#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] +#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read_unaligned<T>(src: *const T) -> T { let mut tmp = MaybeUninit::<T>::uninit(); diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c339ccb1b4d..5edd291fb76 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1305,7 +1305,7 @@ impl<T: ?Sized> *mut T { /// /// [`ptr::read`]: crate::ptr::read() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read(self) -> T @@ -1346,7 +1346,7 @@ impl<T: ?Sized> *mut T { /// /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")] + #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn read_unaligned(self) -> T diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 61fcdf58b4f..b492d2f07bc 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -449,6 +449,19 @@ impl<T: ?Sized> NonNull<T> { // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) } } + + /// See [`pointer::add`] for semantics and safety requirements. + #[inline] + pub(crate) const unsafe fn add(self, delta: usize) -> Self + where + T: Sized, + { + // SAFETY: We require that the delta stays in-bounds of the object, and + // thus it cannot become null, as that would require wrapping the + // address space, which no legal objects are allowed to do. + // And the caller promised the `delta` is sound to add. + unsafe { NonNull { pointer: self.pointer.add(delta) } } + } } impl<T> NonNull<[T]> { diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 8629aab0070..5369fe0a9a9 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -13,7 +13,7 @@ use crate::iter::{ use crate::marker::{PhantomData, Send, Sized, Sync}; use crate::mem::{self, SizedTypeProperties}; use crate::num::NonZeroUsize; -use crate::ptr::NonNull; +use crate::ptr::{invalid, invalid_mut, NonNull}; use super::{from_raw_parts, from_raw_parts_mut}; @@ -67,9 +67,7 @@ pub struct Iter<'a, T: 'a> { ptr: NonNull<T>, /// For non-ZSTs, the non-null pointer to the past-the-end element. /// - /// For ZSTs, this is `ptr.wrapping_byte_add(len)`. - /// - /// For all types, `ptr == end` tests whether the iterator is empty. + /// For ZSTs, this is `ptr::invalid(len)`. end: *const T, _marker: PhantomData<&'a T>, } @@ -92,10 +90,7 @@ impl<'a, T> Iter<'a, T> { let ptr = slice.as_ptr(); // SAFETY: Similar to `IterMut::new`. unsafe { - assume(!ptr.is_null()); - - let end = - if T::IS_ZST { ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; + let end = if T::IS_ZST { invalid(slice.len()) } else { ptr.add(slice.len()) }; Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData } } @@ -193,9 +188,7 @@ pub struct IterMut<'a, T: 'a> { ptr: NonNull<T>, /// For non-ZSTs, the non-null pointer to the past-the-end element. /// - /// For ZSTs, this is `ptr.wrapping_byte_add(len)`. - /// - /// For all types, `ptr == end` tests whether the iterator is empty. + /// For ZSTs, this is `ptr::invalid_mut(len)`. end: *mut T, _marker: PhantomData<&'a mut T>, } @@ -233,10 +226,7 @@ impl<'a, T> IterMut<'a, T> { // See the `next_unchecked!` and `is_empty!` macros as well as the // `post_inc_start` method for more information. unsafe { - assume(!ptr.is_null()); - - let end = - if T::IS_ZST { ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; + let end = if T::IS_ZST { invalid_mut(slice.len()) } else { ptr.add(slice.len()) }; Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData } } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 0a30033778b..3462c0e020a 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -1,11 +1,30 @@ //! Macros used by iterators of slice. +// Shrinks the iterator when T is a ZST, setting the length to `new_len`. +// `new_len` must not exceed `self.len()`. +macro_rules! zst_set_len { + ($self: ident, $new_len: expr) => {{ + #![allow(unused_unsafe)] // we're sometimes used within an unsafe block + + // SAFETY: same as `invalid(_mut)`, but the macro doesn't know + // which versions of that function to call, so open-code it. + $self.end = unsafe { mem::transmute::<usize, _>($new_len) }; + }}; +} + +// Shrinks the iterator when T is a ZST, reducing the length by `n`. +// `n` must not exceed `self.len()`. +macro_rules! zst_shrink { + ($self: ident, $n: ident) => { + let new_len = $self.end.addr() - $n; + zst_set_len!($self, new_len); + }; +} + // Inlining is_empty and len makes a huge performance difference macro_rules! is_empty { - // The way we encode the length of a ZST iterator, this works both for ZST - // and non-ZST. ($self: ident) => { - $self.ptr.as_ptr() as *const T == $self.end + if T::IS_ZST { $self.end.addr() == 0 } else { $self.ptr.as_ptr() as *const _ == $self.end } }; } @@ -13,16 +32,13 @@ macro_rules! len { ($self: ident) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - let start = $self.ptr; if T::IS_ZST { - // This _cannot_ use `ptr_sub` because we depend on wrapping - // to represent the length of long ZST slice iterators. - $self.end.addr().wrapping_sub(start.as_ptr().addr()) + $self.end.addr() } else { // To get rid of some bounds checks (see `position`), we use ptr_sub instead of // offset_from (Tested by `codegen/slice-position-bounds-check`.) // SAFETY: by the type invariant pointers are aligned and `start <= end` - unsafe { $self.end.sub_ptr(start.as_ptr()) } + unsafe { $self.end.sub_ptr($self.ptr.as_ptr()) } } }}; } @@ -50,14 +66,6 @@ macro_rules! iterator { ($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)} } - // Shrinks the iterator when T is a ZST, by moving the end of the iterator - // backwards by `n`. `n` must not exceed `self.len()`. - macro_rules! zst_shrink { - ($self: ident, $n: ident) => { - $self.end = $self.end.wrapping_byte_sub($n); - } - } - impl<'a, T> $name<'a, T> { // Helper function for creating a slice from the iterator. #[inline(always)] @@ -73,16 +81,15 @@ macro_rules! iterator { // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T { + let old = self.ptr; if T::IS_ZST { zst_shrink!(self, offset); - self.ptr.as_ptr() } else { - let old = self.ptr.as_ptr(); // SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`, // so this new pointer is inside `self` and thus guaranteed to be non-null. - self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().add(offset)) }; - old + self.ptr = unsafe { self.ptr.add(offset) }; } + old.as_ptr() } // Helper function for moving the end of the iterator backwards by `offset` elements, @@ -124,12 +131,10 @@ macro_rules! iterator { fn next(&mut self) -> Option<$elem> { // could be implemented with slices, but this avoids bounds checks - // SAFETY: `assume` calls are safe since a slice's start pointer - // must be non-null, and slices over non-ZSTs must also have a - // non-null end pointer. The call to `next_unchecked!` is safe - // since we check if the iterator is empty first. + // SAFETY: `assume` call is safe because slices over non-ZSTs must + // have a non-null end pointer. The call to `next_unchecked!` is + // safe since we check if the iterator is empty first. unsafe { - assume(!self.ptr.as_ptr().is_null()); if !<T>::IS_ZST { assume(!self.end.is_null()); } @@ -157,9 +162,7 @@ macro_rules! iterator { if n >= len!(self) { // This iterator is now empty. if T::IS_ZST { - // We have to do it this way as `ptr` may never be 0, but `end` - // could be (due to wrapping). - self.end = self.ptr.as_ptr(); + zst_set_len!(self, 0); } else { // SAFETY: end can't be 0 if T isn't ZST because ptr isn't 0 and end >= ptr unsafe { @@ -339,12 +342,10 @@ macro_rules! iterator { fn next_back(&mut self) -> Option<$elem> { // could be implemented with slices, but this avoids bounds checks - // SAFETY: `assume` calls are safe since a slice's start pointer must be non-null, - // and slices over non-ZSTs must also have a non-null end pointer. - // The call to `next_back_unchecked!` is safe since we check if the iterator is - // empty first. + // SAFETY: `assume` call is safe because slices over non-ZSTs must + // have a non-null end pointer. The call to `next_back_unchecked!` + // is safe since we check if the iterator is empty first. unsafe { - assume(!self.ptr.as_ptr().is_null()); if !<T>::IS_ZST { assume(!self.end.is_null()); } @@ -360,7 +361,11 @@ macro_rules! iterator { fn nth_back(&mut self, n: usize) -> Option<$elem> { if n >= len!(self) { // This iterator is now empty. - self.end = self.ptr.as_ptr(); + if T::IS_ZST { + zst_set_len!(self, 0); + } else { + self.end = self.ptr.as_ptr(); + } return None; } // SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 4c891ba550f..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] @@ -3478,44 +3479,13 @@ impl<T> [T] { // Ts = size_of::<U> / gcd(size_of::<T>, size_of::<U>) // // Luckily since all this is constant-evaluated... performance here matters not! - #[inline] - fn gcd(a: usize, b: usize) -> usize { - use crate::intrinsics; - // iterative stein’s algorithm - // We should still make this `const fn` (and revert to recursive algorithm if we do) - // because relying on llvm to consteval all this is… well, it makes me uncomfortable. - - // SAFETY: `a` and `b` are checked to be non-zero values. - let (ctz_a, mut ctz_b) = unsafe { - if a == 0 { - return b; - } - if b == 0 { - return a; - } - (intrinsics::cttz_nonzero(a), intrinsics::cttz_nonzero(b)) - }; - let k = ctz_a.min(ctz_b); - let mut a = a >> ctz_a; - let mut b = b; - loop { - // remove all factors of 2 from b - b >>= ctz_b; - if a > b { - mem::swap(&mut a, &mut b); - } - b = b - a; - // SAFETY: `b` is checked to be non-zero. - unsafe { - if b == 0 { - break; - } - ctz_b = intrinsics::cttz_nonzero(b); - } - } - a << k + const fn gcd(a: usize, b: usize) -> usize { + if b == 0 { a } else { gcd(b, a % b) } } - let gcd: usize = gcd(mem::size_of::<T>(), mem::size_of::<U>()); + + // Explicitly wrap the function call in a const block so it gets + // constant-evaluated even in debug mode. + let gcd: usize = const { gcd(mem::size_of::<T>(), mem::size_of::<U>()) }; let ts: usize = mem::size_of::<U>() / gcd; let us: usize = mem::size_of::<T>() / gcd; 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/poll.rs b/library/core/src/task/poll.rs index 168516263f1..5283a576d1b 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -116,7 +116,7 @@ impl<T> Poll<T> { /// let fut = Pin::new(&mut fut); /// /// let num = fut.poll(cx).ready()?; - /// # drop(num); + /// # let _ = num; // to silence unused warning /// // ... use num /// /// Poll::Ready(()) diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index b1daf545fbe..8d12625e88d 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -22,7 +22,7 @@ use core::task::Poll; /// let fut = Pin::new(&mut fut); /// /// let num = ready!(fut.poll(cx)); -/// # drop(num); +/// # let _ = num; /// // ... use num /// /// Poll::Ready(()) @@ -44,7 +44,7 @@ use core::task::Poll; /// Poll::Ready(t) => t, /// Poll::Pending => return Poll::Pending, /// }; -/// # drop(num); +/// # let _ = num; // to silence unused warning /// # // ... use num /// # /// # Poll::Ready(()) 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 84859a54c26..3933e328951 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -18,7 +18,6 @@ #![feature(const_pointer_byte_offsets)] #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] -#![feature(const_ptr_read)] #![feature(const_ptr_write)] #![feature(const_trait_impl)] #![feature(const_likely)] @@ -54,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/.github/workflows/ci.yml b/library/portable-simd/.github/workflows/ci.yml index d50dfa1be4c..acd47a3da72 100644 --- a/library/portable-simd/.github/workflows/ci.yml +++ b/library/portable-simd/.github/workflows/ci.yml @@ -241,6 +241,10 @@ jobs: - "--features std" - "--features generic_const_exprs" - "--features std --features generic_const_exprs" + - "--features all_lane_counts" + - "--features all_lane_counts --features std" + - "--features all_lane_counts --features generic_const_exprs" + - "--features all_lane_counts --features std --features generic_const_exprs" steps: - uses: actions/checkout@v2 diff --git a/library/portable-simd/README.md b/library/portable-simd/README.md index db0af2da606..e8ac600debe 100644 --- a/library/portable-simd/README.md +++ b/library/portable-simd/README.md @@ -24,19 +24,10 @@ or by setting up `rustup default nightly` or else with `cargo +nightly {build,te ```bash cargo new hellosimd ``` -to create a new crate. Edit `hellosimd/Cargo.toml` to be -```toml -[package] -name = "hellosimd" -version = "0.1.0" -edition = "2018" -[dependencies] -core_simd = { git = "https://github.com/rust-lang/portable-simd" } -``` - -and finally write this in `src/main.rs`: +to create a new crate. Finally write this in `src/main.rs`: ```rust -use core_simd::*; +#![feature(portable_simd)] +use std::simd::f32x4; fn main() { let a = f32x4::splat(10.0); let b = f32x4::from_array([1.0, 2.0, 3.0, 4.0]); @@ -44,24 +35,23 @@ fn main() { } ``` -Explanation: We import all the bindings from the crate with the first line. Then, we construct our SIMD vectors with methods like `splat` or `from_array`. Finally, we can use operators on them like `+` and the appropriate SIMD instructions will be carried out. When we run `cargo run` you should get `[11.0, 12.0, 13.0, 14.0]`. - -## Code Organization +Explanation: We construct our SIMD vectors with methods like `splat` or `from_array`. Next, we can use operators like `+` on them, and the appropriate SIMD instructions will be carried out. When we run `cargo run` you should get `[11.0, 12.0, 13.0, 14.0]`. -Currently the crate is organized so that each element type is a file, and then the 64-bit, 128-bit, 256-bit, and 512-bit vectors using those types are contained in said file. +## Supported vectors -All types are then exported as a single, flat module. +Currently, vectors may have up to 64 elements, but aliases are provided only up to 512-bit vectors. Depending on the size of the primitive type, the number of lanes the vector will have varies. For example, 128-bit vectors have four `f32` lanes and two `f64` lanes. The supported element types are as follows: * **Floating Point:** `f32`, `f64` -* **Signed Integers:** `i8`, `i16`, `i32`, `i64`, `i128`, `isize` -* **Unsigned Integers:** `u8`, `u16`, `u32`, `u64`, `u128`, `usize` -* **Masks:** `mask8`, `mask16`, `mask32`, `mask64`, `mask128`, `masksize` +* **Signed Integers:** `i8`, `i16`, `i32`, `i64`, `isize` (`i128` excluded) +* **Unsigned Integers:** `u8`, `u16`, `u32`, `u64`, `usize` (`u128` excluded) +* **Pointers:** `*const T` and `*mut T` (zero-sized metadata only) +* **Masks:** 8-bit, 16-bit, 32-bit, 64-bit, and `usize`-sized masks -Floating point, signed integers, and unsigned integers are the [primitive types](https://doc.rust-lang.org/core/primitive/index.html) you're already used to. -The `mask` types are "truthy" values, but they use the number of bits in their name instead of just 1 bit like a normal `bool` uses. +Floating point, signed integers, unsigned integers, and pointers are the [primitive types](https://doc.rust-lang.org/core/primitive/index.html) you're already used to. +The mask types have elements that are "truthy" values, like `bool`, but have an unspecified layout because different architectures prefer different layouts for mask types. [simd-guide]: ./beginners-guide.md [zulip-project-portable-simd]: https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd diff --git a/library/portable-simd/crates/core_simd/Cargo.toml b/library/portable-simd/crates/core_simd/Cargo.toml index 8a29cf15696..d1a3a515a7e 100644 --- a/library/portable-simd/crates/core_simd/Cargo.toml +++ b/library/portable-simd/crates/core_simd/Cargo.toml @@ -13,12 +13,11 @@ default = ["as_crate"] as_crate = [] std = [] generic_const_exprs = [] +all_lane_counts = [] -[target.'cfg(target_arch = "wasm32")'.dev-dependencies.wasm-bindgen] -version = "0.2" - -[dev-dependencies.wasm-bindgen-test] -version = "0.3" +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +wasm-bindgen = "0.2" +wasm-bindgen-test = "0.3" [dev-dependencies.proptest] version = "0.10" diff --git a/library/portable-simd/crates/core_simd/examples/README.md b/library/portable-simd/crates/core_simd/examples/README.md new file mode 100644 index 00000000000..82747f1b5a6 --- /dev/null +++ b/library/portable-simd/crates/core_simd/examples/README.md @@ -0,0 +1,13 @@ +### `stdsimd` examples + +This crate is a port of example uses of `stdsimd`, mostly taken from the `packed_simd` crate. + +The examples contain, as in the case of `dot_product.rs`, multiple ways of solving the problem, in order to show idiomatic uses of SIMD and iteration of performance designs. + +Run the tests with the command + +``` +cargo run --example dot_product +``` + +and verify the code for `dot_product.rs` on your machine. diff --git a/library/portable-simd/crates/core_simd/examples/dot_product.rs b/library/portable-simd/crates/core_simd/examples/dot_product.rs new file mode 100644 index 00000000000..391f08f55a0 --- /dev/null +++ b/library/portable-simd/crates/core_simd/examples/dot_product.rs @@ -0,0 +1,169 @@ +// Code taken from the `packed_simd` crate +// Run this code with `cargo test --example dot_product` +//use std::iter::zip; + +#![feature(array_chunks)] +#![feature(slice_as_chunks)] +// Add these imports to use the stdsimd library +#![feature(portable_simd)] +use core_simd::simd::*; + +// This is your barebones dot product implementation: +// Take 2 vectors, multiply them element wise and *then* +// go along the resulting array and add up the result. +// In the next example we will see if there +// is any difference to adding and multiplying in tandem. +pub fn dot_prod_scalar_0(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + + a.iter().zip(b.iter()).map(|(a, b)| a * b).sum() +} + +// When dealing with SIMD, it is very important to think about the amount +// of data movement and when it happens. We're going over simple computation examples here, and yet +// it is not trivial to understand what may or may not contribute to performance +// changes. Eventually, you will need tools to inspect the generated assembly and confirm your +// hypothesis and benchmarks - we will mention them later on. +// With the use of `fold`, we're doing a multiplication, +// and then adding it to the sum, one element from both vectors at a time. +pub fn dot_prod_scalar_1(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + a.iter() + .zip(b.iter()) + .fold(0.0, |a, zipped| a + zipped.0 * zipped.1) +} + +// We now move on to the SIMD implementations: notice the following constructs: +// `array_chunks::<4>`: mapping this over the vector will let use construct SIMD vectors +// `f32x4::from_array`: construct the SIMD vector from a slice +// `(a * b).reduce_sum()`: Multiply both f32x4 vectors together, and then reduce them. +// This approach essentially uses SIMD to produce a vector of length N/4 of all the products, +// and then add those with `sum()`. This is suboptimal. +// TODO: ASCII diagrams +pub fn dot_prod_simd_0(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + // TODO handle remainder when a.len() % 4 != 0 + a.array_chunks::<4>() + .map(|&a| f32x4::from_array(a)) + .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .map(|(a, b)| (a * b).reduce_sum()) + .sum() +} + +// There's some simple ways to improve the previous code: +// 1. Make a `zero` `f32x4` SIMD vector that we will be accumulating into +// So that there is only one `sum()` reduction when the last `f32x4` has been processed +// 2. Exploit Fused Multiply Add so that the multiplication, addition and sinking into the reduciton +// happen in the same step. +// If the arrays are large, minimizing the data shuffling will lead to great perf. +// If the arrays are small, handling the remainder elements when the length isn't a multiple of 4 +// Can become a problem. +pub fn dot_prod_simd_1(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + // TODO handle remainder when a.len() % 4 != 0 + a.array_chunks::<4>() + .map(|&a| f32x4::from_array(a)) + .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .fold(f32x4::splat(0.0), |acc, zipped| acc + zipped.0 * zipped.1) + .reduce_sum() +} + +// A lot of knowledgeable use of SIMD comes from knowing specific instructions that are +// available - let's try to use the `mul_add` instruction, which is the fused-multiply-add we were looking for. +use std_float::StdFloat; +pub fn dot_prod_simd_2(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + // TODO handle remainder when a.len() % 4 != 0 + let mut res = f32x4::splat(0.0); + a.array_chunks::<4>() + .map(|&a| f32x4::from_array(a)) + .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .for_each(|(a, b)| { + res = a.mul_add(b, res); + }); + res.reduce_sum() +} + +// Finally, we will write the same operation but handling the loop remainder. +const LANES: usize = 4; +pub fn dot_prod_simd_3(a: &[f32], b: &[f32]) -> f32 { + assert_eq!(a.len(), b.len()); + + let (a_extra, a_chunks) = a.as_rchunks(); + let (b_extra, b_chunks) = b.as_rchunks(); + + // These are always true, but for emphasis: + assert_eq!(a_chunks.len(), b_chunks.len()); + assert_eq!(a_extra.len(), b_extra.len()); + + let mut sums = [0.0; LANES]; + for ((x, y), d) in std::iter::zip(a_extra, b_extra).zip(&mut sums) { + *d = x * y; + } + + let mut sums = f32x4::from_array(sums); + std::iter::zip(a_chunks, b_chunks).for_each(|(x, y)| { + sums += f32x4::from_array(*x) * f32x4::from_array(*y); + }); + + sums.reduce_sum() +} + +// Finally, we present an iterator version for handling remainders in a scalar fashion at the end of the loop. +// Unfortunately, this is allocating 1 `XMM` register on the order of `~len(a)` - we'll see how we can get around it in the +// next example. +pub fn dot_prod_simd_4(a: &[f32], b: &[f32]) -> f32 { + let mut sum = a + .array_chunks::<4>() + .map(|&a| f32x4::from_array(a)) + .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .map(|(a, b)| a * b) + .fold(f32x4::splat(0.0), std::ops::Add::add) + .reduce_sum(); + let remain = a.len() - (a.len() % 4); + sum += a[remain..] + .iter() + .zip(&b[remain..]) + .map(|(a, b)| a * b) + .sum::<f32>(); + sum +} + +// This version allocates a single `XMM` register for accumulation, and the folds don't allocate on top of that. +// Notice the the use of `mul_add`, which can do a multiply and an add operation ber iteration. +pub fn dot_prod_simd_5(a: &[f32], b: &[f32]) -> f32 { + a.array_chunks::<4>() + .map(|&a| f32x4::from_array(a)) + .zip(b.array_chunks::<4>().map(|&b| f32x4::from_array(b))) + .fold(f32x4::splat(0.), |acc, (a, b)| a.mul_add(b, acc)) + .reduce_sum() +} + +fn main() { + // Empty main to make cargo happy +} + +#[cfg(test)] +mod tests { + #[test] + fn smoke_test() { + use super::*; + let a: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]; + let b: Vec<f32> = vec![-8.0, -7.0, -6.0, -5.0, 4.0, 3.0, 2.0, 1.0]; + let x: Vec<f32> = [0.5; 1003].to_vec(); + let y: Vec<f32> = [2.0; 1003].to_vec(); + + // Basic check + assert_eq!(0.0, dot_prod_scalar_0(&a, &b)); + assert_eq!(0.0, dot_prod_scalar_1(&a, &b)); + assert_eq!(0.0, dot_prod_simd_0(&a, &b)); + assert_eq!(0.0, dot_prod_simd_1(&a, &b)); + assert_eq!(0.0, dot_prod_simd_2(&a, &b)); + assert_eq!(0.0, dot_prod_simd_3(&a, &b)); + assert_eq!(0.0, dot_prod_simd_4(&a, &b)); + assert_eq!(0.0, dot_prod_simd_5(&a, &b)); + + // We can handle vectors that are non-multiples of 4 + assert_eq!(1003.0, dot_prod_simd_3(&x, &y)); + } +} diff --git a/library/portable-simd/crates/core_simd/src/alias.rs b/library/portable-simd/crates/core_simd/src/alias.rs new file mode 100644 index 00000000000..23f121c4619 --- /dev/null +++ b/library/portable-simd/crates/core_simd/src/alias.rs @@ -0,0 +1,227 @@ +macro_rules! number { + { 1 } => { "one" }; + { 2 } => { "two" }; + { 4 } => { "four" }; + { 8 } => { "eight" }; + { $x:literal } => { stringify!($x) }; +} + +macro_rules! plural { + { 1 } => { "" }; + { $x:literal } => { "s" }; +} + +macro_rules! alias { + { + $( + $element_ty:ty = { + $($alias:ident $num_elements:tt)* + } + )* + } => { + $( + $( + #[doc = concat!("A SIMD vector with ", number!($num_elements), " element", plural!($num_elements), " of type [`", stringify!($element_ty), "`].")] + #[allow(non_camel_case_types)] + pub type $alias = $crate::simd::Simd<$element_ty, $num_elements>; + )* + )* + } +} + +macro_rules! mask_alias { + { + $( + $element_ty:ty : $size:literal = { + $($alias:ident $num_elements:tt)* + } + )* + } => { + $( + $( + #[doc = concat!("A SIMD mask with ", number!($num_elements), " element", plural!($num_elements), " for vectors with ", $size, " element types.")] + /// + #[doc = concat!( + "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 `[", + stringify!($element_ty), "; ", $num_elements, "]`." + )] + #[allow(non_camel_case_types)] + pub type $alias = $crate::simd::Mask<$element_ty, $num_elements>; + )* + )* + } +} + +alias! { + i8 = { + i8x1 1 + i8x2 2 + i8x4 4 + i8x8 8 + i8x16 16 + i8x32 32 + i8x64 64 + } + + i16 = { + i16x1 1 + i16x2 2 + i16x4 4 + i16x8 8 + i16x16 16 + i16x32 32 + i16x64 64 + } + + i32 = { + i32x1 1 + i32x2 2 + i32x4 4 + i32x8 8 + i32x16 16 + i32x32 32 + i32x64 64 + } + + i64 = { + i64x1 1 + i64x2 2 + i64x4 4 + i64x8 8 + i64x16 16 + i64x32 32 + i64x64 64 + } + + isize = { + isizex1 1 + isizex2 2 + isizex4 4 + isizex8 8 + isizex16 16 + isizex32 32 + isizex64 64 + } + + u8 = { + u8x1 1 + u8x2 2 + u8x4 4 + u8x8 8 + u8x16 16 + u8x32 32 + u8x64 64 + } + + u16 = { + u16x1 1 + u16x2 2 + u16x4 4 + u16x8 8 + u16x16 16 + u16x32 32 + u16x64 64 + } + + u32 = { + u32x1 1 + u32x2 2 + u32x4 4 + u32x8 8 + u32x16 16 + u32x32 32 + u32x64 64 + } + + u64 = { + u64x1 1 + u64x2 2 + u64x4 4 + u64x8 8 + u64x16 16 + u64x32 32 + u64x64 64 + } + + usize = { + usizex1 1 + usizex2 2 + usizex4 4 + usizex8 8 + usizex16 16 + usizex32 32 + usizex64 64 + } + + f32 = { + f32x1 1 + f32x2 2 + f32x4 4 + f32x8 8 + f32x16 16 + f32x32 32 + f32x64 64 + } + + f64 = { + f64x1 1 + f64x2 2 + f64x4 4 + f64x8 8 + f64x16 16 + f64x32 32 + f64x64 64 + } +} + +mask_alias! { + i8 : "8-bit" = { + mask8x1 1 + mask8x2 2 + mask8x4 4 + mask8x8 8 + mask8x16 16 + mask8x32 32 + mask8x64 64 + } + + i16 : "16-bit" = { + mask16x1 1 + mask16x2 2 + mask16x4 4 + mask16x8 8 + mask16x16 16 + mask16x32 32 + mask16x64 64 + } + + i32 : "32-bit" = { + mask32x1 1 + mask32x2 2 + mask32x4 4 + mask32x8 8 + mask32x16 16 + mask32x32 32 + mask32x64 64 + } + + i64 : "64-bit" = { + mask64x1 1 + mask64x2 2 + mask64x4 4 + mask64x8 8 + mask64x16 16 + mask64x32 32 + mask64x64 64 + } + + isize : "pointer-sized" = { + masksizex1 1 + masksizex2 2 + masksizex4 4 + masksizex8 8 + masksizex16 16 + masksizex32 32 + masksizex64 64 + } +} diff --git a/library/portable-simd/crates/core_simd/src/cast.rs b/library/portable-simd/crates/core_simd/src/cast.rs new file mode 100644 index 00000000000..65a3f845ffc --- /dev/null +++ b/library/portable-simd/crates/core_simd/src/cast.rs @@ -0,0 +1,55 @@ +use crate::simd::SimdElement; + +/// Supporting trait for `Simd::cast`. Typically doesn't need to be used directly. +/// +/// # Safety +/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast` or +/// `simd_as` intrinsics. +pub unsafe trait SimdCast: SimdElement {} + +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for i8 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for i16 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for i32 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for i64 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for isize {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for u8 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for u16 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for u32 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for u64 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for usize {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for f32 {} +// Safety: primitive number types can be cast to other primitive number types +unsafe impl SimdCast for f64 {} + +/// Supporting trait for `Simd::cast_ptr`. Typically doesn't need to be used directly. +/// +/// # Safety +/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast_ptr` +/// intrinsic. +pub unsafe trait SimdCastPtr<T> {} + +// Safety: pointers can be cast to other pointer types +unsafe impl<T, U> SimdCastPtr<T> for *const U +where + U: core::ptr::Pointee, + T: core::ptr::Pointee<Metadata = U::Metadata>, +{ +} +// Safety: pointers can be cast to other pointer types +unsafe impl<T, U> SimdCastPtr<T> for *mut U +where + U: core::ptr::Pointee, + T: core::ptr::Pointee<Metadata = U::Metadata>, +{ +} diff --git a/library/portable-simd/crates/core_simd/src/elements.rs b/library/portable-simd/crates/core_simd/src/elements.rs index 701eb66b248..dc7f52a4d57 100644 --- a/library/portable-simd/crates/core_simd/src/elements.rs +++ b/library/portable-simd/crates/core_simd/src/elements.rs @@ -1,11 +1,15 @@ +mod const_ptr; mod float; mod int; +mod mut_ptr; mod uint; mod sealed { pub trait Sealed {} } +pub use const_ptr::*; pub use float::*; pub use int::*; +pub use mut_ptr::*; pub use uint::*; diff --git a/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs b/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs new file mode 100644 index 00000000000..0ef9802b5e2 --- /dev/null +++ b/library/portable-simd/crates/core_simd/src/elements/const_ptr.rs @@ -0,0 +1,141 @@ +use super::sealed::Sealed; +use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount}; + +/// Operations on SIMD vectors of constant pointers. +pub trait SimdConstPtr: Copy + Sealed { + /// Vector of `usize` with the same number of lanes. + type Usize; + + /// Vector of `isize` with the same number of lanes. + type Isize; + + /// Vector of mutable pointers to the same type. + type MutPtr; + + /// Mask type used for manipulating this SIMD vector type. + type Mask; + + /// Returns `true` for each lane that is null. + fn is_null(self) -> Self::Mask; + + /// Changes constness without changing the type. + /// + /// Equivalent to calling [`pointer::cast_mut`] on each lane. + fn cast_mut(self) -> Self::MutPtr; + + /// Gets the "address" portion of the pointer. + /// + /// This method discards pointer semantic metadata, so the result cannot be + /// directly cast into a valid pointer. + /// + /// This method semantically discards *provenance* and + /// *address-space* information. To properly restore that information, use [`Self::with_addr`]. + /// + /// Equivalent to calling [`pointer::addr`] on each lane. + fn addr(self) -> Self::Usize; + + /// Creates a new pointer with the given address. + /// + /// This performs the same operation as a cast, but copies the *address-space* and + /// *provenance* of `self` to the new pointer. + /// + /// Equivalent to calling [`pointer::with_addr`] on each lane. + fn with_addr(self, addr: Self::Usize) -> Self; + + /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use + /// in [`Self::from_exposed_addr`]. + fn expose_addr(self) -> Self::Usize; + + /// Convert an address back to a pointer, picking up a previously "exposed" provenance. + /// + /// Equivalent to calling [`core::ptr::from_exposed_addr`] on each lane. + fn from_exposed_addr(addr: Self::Usize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_offset`] on each lane. + fn wrapping_offset(self, offset: Self::Isize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_add`] on each lane. + fn wrapping_add(self, count: Self::Usize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_sub`] on each lane. + fn wrapping_sub(self, count: Self::Usize) -> Self; +} + +impl<T, const LANES: usize> Sealed for Simd<*const T, LANES> where + LaneCount<LANES>: SupportedLaneCount +{ +} + +impl<T, const LANES: usize> SimdConstPtr for Simd<*const T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + type Usize = Simd<usize, LANES>; + type Isize = Simd<isize, LANES>; + type MutPtr = Simd<*mut T, LANES>; + type Mask = Mask<isize, LANES>; + + #[inline] + fn is_null(self) -> Self::Mask { + Simd::splat(core::ptr::null()).simd_eq(self) + } + + #[inline] + fn cast_mut(self) -> Self::MutPtr { + self.cast_ptr() + } + + #[inline] + fn addr(self) -> Self::Usize { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the + // provenance). + unsafe { core::mem::transmute_copy(&self) } + } + + #[inline] + fn with_addr(self, addr: Self::Usize) -> Self { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // + // In the mean-time, this operation is defined to be "as if" it was + // a wrapping_offset, so we can emulate it as such. This should properly + // restore pointer provenance even under today's compiler. + self.cast_ptr::<*const u8>() + .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>()) + .cast_ptr() + } + + #[inline] + fn expose_addr(self) -> Self::Usize { + // Safety: `self` is a pointer vector + unsafe { intrinsics::simd_expose_addr(self) } + } + + #[inline] + fn from_exposed_addr(addr: Self::Usize) -> Self { + // Safety: `self` is a pointer vector + unsafe { intrinsics::simd_from_exposed_addr(addr) } + } + + #[inline] + fn wrapping_offset(self, count: Self::Isize) -> Self { + // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets + unsafe { intrinsics::simd_arith_offset(self, count) } + } + + #[inline] + fn wrapping_add(self, count: Self::Usize) -> Self { + self.wrapping_offset(count.cast()) + } + + #[inline] + fn wrapping_sub(self, count: Self::Usize) -> Self { + self.wrapping_offset(-count.cast::<isize>()) + } +} diff --git a/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs new file mode 100644 index 00000000000..d87986b4a09 --- /dev/null +++ b/library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs @@ -0,0 +1,136 @@ +use super::sealed::Sealed; +use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount}; + +/// Operations on SIMD vectors of mutable pointers. +pub trait SimdMutPtr: Copy + Sealed { + /// Vector of `usize` with the same number of lanes. + type Usize; + + /// Vector of `isize` with the same number of lanes. + type Isize; + + /// Vector of constant pointers to the same type. + type ConstPtr; + + /// Mask type used for manipulating this SIMD vector type. + type Mask; + + /// Returns `true` for each lane that is null. + fn is_null(self) -> Self::Mask; + + /// Changes constness without changing the type. + /// + /// Equivalent to calling [`pointer::cast_const`] on each lane. + fn cast_const(self) -> Self::ConstPtr; + + /// Gets the "address" portion of the pointer. + /// + /// This method discards pointer semantic metadata, so the result cannot be + /// directly cast into a valid pointer. + /// + /// Equivalent to calling [`pointer::addr`] on each lane. + fn addr(self) -> Self::Usize; + + /// Creates a new pointer with the given address. + /// + /// This performs the same operation as a cast, but copies the *address-space* and + /// *provenance* of `self` to the new pointer. + /// + /// Equivalent to calling [`pointer::with_addr`] on each lane. + fn with_addr(self, addr: Self::Usize) -> Self; + + /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use + /// in [`Self::from_exposed_addr`]. + fn expose_addr(self) -> Self::Usize; + + /// Convert an address back to a pointer, picking up a previously "exposed" provenance. + /// + /// Equivalent to calling [`core::ptr::from_exposed_addr_mut`] on each lane. + fn from_exposed_addr(addr: Self::Usize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_offset`] on each lane. + fn wrapping_offset(self, offset: Self::Isize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_add`] on each lane. + fn wrapping_add(self, count: Self::Usize) -> Self; + + /// Calculates the offset from a pointer using wrapping arithmetic. + /// + /// Equivalent to calling [`pointer::wrapping_sub`] on each lane. + fn wrapping_sub(self, count: Self::Usize) -> Self; +} + +impl<T, const LANES: usize> Sealed for Simd<*mut T, LANES> where LaneCount<LANES>: SupportedLaneCount +{} + +impl<T, const LANES: usize> SimdMutPtr for Simd<*mut T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + type Usize = Simd<usize, LANES>; + type Isize = Simd<isize, LANES>; + type ConstPtr = Simd<*const T, LANES>; + type Mask = Mask<isize, LANES>; + + #[inline] + fn is_null(self) -> Self::Mask { + Simd::splat(core::ptr::null_mut()).simd_eq(self) + } + + #[inline] + fn cast_const(self) -> Self::ConstPtr { + self.cast_ptr() + } + + #[inline] + fn addr(self) -> Self::Usize { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the + // provenance). + unsafe { core::mem::transmute_copy(&self) } + } + + #[inline] + fn with_addr(self, addr: Self::Usize) -> Self { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // + // In the mean-time, this operation is defined to be "as if" it was + // a wrapping_offset, so we can emulate it as such. This should properly + // restore pointer provenance even under today's compiler. + self.cast_ptr::<*mut u8>() + .wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>()) + .cast_ptr() + } + + #[inline] + fn expose_addr(self) -> Self::Usize { + // Safety: `self` is a pointer vector + unsafe { intrinsics::simd_expose_addr(self) } + } + + #[inline] + fn from_exposed_addr(addr: Self::Usize) -> Self { + // Safety: `self` is a pointer vector + unsafe { intrinsics::simd_from_exposed_addr(addr) } + } + + #[inline] + fn wrapping_offset(self, count: Self::Isize) -> Self { + // Safety: simd_arith_offset takes a vector of pointers and a vector of offsets + unsafe { intrinsics::simd_arith_offset(self, count) } + } + + #[inline] + fn wrapping_add(self, count: Self::Usize) -> Self { + self.wrapping_offset(count.cast()) + } + + #[inline] + fn wrapping_sub(self, count: Self::Usize) -> Self { + self.wrapping_offset(-count.cast::<isize>()) + } +} diff --git a/library/portable-simd/crates/core_simd/src/eq.rs b/library/portable-simd/crates/core_simd/src/eq.rs index c7111f720a8..80763c07272 100644 --- a/library/portable-simd/crates/core_simd/src/eq.rs +++ b/library/portable-simd/crates/core_simd/src/eq.rs @@ -1,4 +1,6 @@ -use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{ + intrinsics, LaneCount, Mask, Simd, SimdConstPtr, SimdElement, SimdMutPtr, SupportedLaneCount, +}; /// Parallel `PartialEq`. pub trait SimdPartialEq { @@ -71,3 +73,37 @@ macro_rules! impl_mask { } impl_mask! { i8, i16, i32, i64, isize } + +impl<T, const LANES: usize> SimdPartialEq for Simd<*const T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + type Mask = Mask<isize, LANES>; + + #[inline] + fn simd_eq(self, other: Self) -> Self::Mask { + self.addr().simd_eq(other.addr()) + } + + #[inline] + fn simd_ne(self, other: Self) -> Self::Mask { + self.addr().simd_ne(other.addr()) + } +} + +impl<T, const LANES: usize> SimdPartialEq for Simd<*mut T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + type Mask = Mask<isize, LANES>; + + #[inline] + fn simd_eq(self, other: Self) -> Self::Mask { + self.addr().simd_eq(other.addr()) + } + + #[inline] + fn simd_ne(self, other: Self) -> Self::Mask { + self.addr().simd_ne(other.addr()) + } +} diff --git a/library/portable-simd/crates/core_simd/src/fmt.rs b/library/portable-simd/crates/core_simd/src/fmt.rs index dbd9839c4bf..b7317969cbb 100644 --- a/library/portable-simd/crates/core_simd/src/fmt.rs +++ b/library/portable-simd/crates/core_simd/src/fmt.rs @@ -1,39 +1,21 @@ use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; use core::fmt; -macro_rules! impl_fmt_trait { - { $($trait:ident,)* } => { - $( - impl<T, const LANES: usize> fmt::$trait for Simd<T, LANES> - where - LaneCount<LANES>: SupportedLaneCount, - T: SimdElement + fmt::$trait, - { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[repr(transparent)] - struct Wrapper<'a, T: fmt::$trait>(&'a T); - - impl<T: fmt::$trait> fmt::Debug for Wrapper<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } - } - - f.debug_list() - .entries(self.as_array().iter().map(|x| Wrapper(x))) - .finish() - } - } - )* +impl<T, const LANES: usize> fmt::Debug for Simd<T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, + T: SimdElement + fmt::Debug, +{ + /// A `Simd<T, N>` has a debug format like the one for `[T]`: + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let floats = Simd::<f32, 4>::splat(-1.0); + /// assert_eq!(format!("{:?}", [-1.0; 4]), format!("{:?}", floats)); + /// ``` + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + <[T] as fmt::Debug>::fmt(self.as_array(), f) } } - -impl_fmt_trait! { - Debug, - Binary, - LowerExp, - UpperExp, - Octal, - LowerHex, - UpperHex, -} diff --git a/library/portable-simd/crates/core_simd/src/intrinsics.rs b/library/portable-simd/crates/core_simd/src/intrinsics.rs index 704e6ed0159..dd6698e2ba5 100644 --- a/library/portable-simd/crates/core_simd/src/intrinsics.rs +++ b/library/portable-simd/crates/core_simd/src/intrinsics.rs @@ -61,9 +61,6 @@ extern "platform-intrinsic" { /// xor pub(crate) fn simd_xor<T>(x: T, y: T) -> T; - /// getelementptr (without inbounds) - pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T; - /// fptoui/fptosi/uitofp/sitofp /// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5 /// but the truncated value must fit in the target type or the result is poison. @@ -150,4 +147,17 @@ extern "platform-intrinsic" { pub(crate) fn simd_select<M, T>(m: M, yes: T, no: T) -> T; #[allow(unused)] pub(crate) fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T; + + /// getelementptr (without inbounds) + /// equivalent to wrapping_offset + pub(crate) fn simd_arith_offset<T, U>(ptr: T, offset: U) -> T; + + /// equivalent to `T as U` semantics, specifically for pointers + pub(crate) fn simd_cast_ptr<T, U>(ptr: T) -> U; + + /// expose a pointer as an address + pub(crate) fn simd_expose_addr<T, U>(ptr: T) -> U; + + /// convert an exposed address back to a pointer + pub(crate) fn simd_from_exposed_addr<T, U>(addr: T) -> U; } diff --git a/library/portable-simd/crates/core_simd/src/lane_count.rs b/library/portable-simd/crates/core_simd/src/lane_count.rs index 63723e2ec13..2b91eb9e800 100644 --- a/library/portable-simd/crates/core_simd/src/lane_count.rs +++ b/library/portable-simd/crates/core_simd/src/lane_count.rs @@ -23,24 +23,20 @@ pub trait SupportedLaneCount: Sealed { impl<const LANES: usize> Sealed for LaneCount<LANES> {} -impl SupportedLaneCount for LaneCount<1> { - type BitMask = [u8; 1]; -} -impl SupportedLaneCount for LaneCount<2> { - type BitMask = [u8; 1]; -} -impl SupportedLaneCount for LaneCount<4> { - type BitMask = [u8; 1]; -} -impl SupportedLaneCount for LaneCount<8> { - type BitMask = [u8; 1]; -} -impl SupportedLaneCount for LaneCount<16> { - type BitMask = [u8; 2]; -} -impl SupportedLaneCount for LaneCount<32> { - type BitMask = [u8; 4]; -} -impl SupportedLaneCount for LaneCount<64> { - type BitMask = [u8; 8]; +macro_rules! supported_lane_count { + ($($lanes:literal),+) => { + $( + impl SupportedLaneCount for LaneCount<$lanes> { + type BitMask = [u8; ($lanes + 7) / 8]; + } + )+ + }; } + +supported_lane_count!(1, 2, 4, 8, 16, 32, 64); +#[cfg(feature = "all_lane_counts")] +supported_lane_count!( + 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63 +); diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs index 715f258f617..e5307de2155 100644 --- a/library/portable-simd/crates/core_simd/src/lib.rs +++ b/library/portable-simd/crates/core_simd/src/lib.rs @@ -1,5 +1,8 @@ #![no_std] #![feature( + const_refs_to_cell, + const_maybe_uninit_as_mut_ptr, + const_mut_refs, convert_float_to_int, decl_macro, intra_doc_pointers, @@ -7,7 +10,9 @@ repr_simd, simd_ffi, staged_api, - stdsimd + stdsimd, + strict_provenance, + ptr_metadata )] #![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))] #![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))] @@ -19,4 +24,3 @@ #[path = "mod.rs"] mod core_simd; pub use self::core_simd::simd; -pub use simd::*; diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index c36c336d8a2..e0f3c7beef6 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -55,6 +55,7 @@ pub unsafe trait MaskElement: SimdElement + Sealed {} macro_rules! impl_element { { $ty:ty } => { impl Sealed for $ty { + #[inline] fn valid<const LANES: usize>(value: Simd<Self, LANES>) -> bool where LaneCount<LANES>: SupportedLaneCount, @@ -62,6 +63,7 @@ macro_rules! impl_element { (value.simd_eq(Simd::splat(0 as _)) | value.simd_eq(Simd::splat(-1 as _))).all() } + #[inline] fn eq(self, other: Self) -> bool { self == other } const TRUE: Self = -1; @@ -83,8 +85,10 @@ impl_element! { isize } /// /// Masks represent boolean inclusion/exclusion on a per-lane basis. /// -/// The layout of this type is unspecified. -#[repr(transparent)] +/// 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]`. +#[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, @@ -102,6 +106,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn clone(&self) -> Self { *self } @@ -113,11 +118,13 @@ where LaneCount<LANES>: SupportedLaneCount, { /// Construct a mask by setting all lanes to the given value. + #[inline] pub fn splat(value: bool) -> Self { Self(mask_impl::Mask::splat(value)) } /// Converts an array of bools to a SIMD mask. + #[inline] pub fn from_array(array: [bool; LANES]) -> Self { // SAFETY: Rust's bool has a layout of 1 byte (u8) with a value of // true: 0b_0000_0001 @@ -134,6 +141,7 @@ where } /// Converts a SIMD mask to an array of bools. + #[inline] pub fn to_array(self) -> [bool; LANES] { // This follows mostly the same logic as from_array. // SAFETY: Rust's bool has a layout of 1 byte (u8) with a value of @@ -261,6 +269,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn from(array: [bool; LANES]) -> Self { Self::from_array(array) } @@ -271,6 +280,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn from(vector: Mask<T, LANES>) -> Self { vector.to_array() } @@ -520,60 +530,6 @@ where } } -/// A mask for SIMD vectors with eight elements of 8 bits. -pub type mask8x8 = Mask<i8, 8>; - -/// A mask for SIMD vectors with 16 elements of 8 bits. -pub type mask8x16 = Mask<i8, 16>; - -/// A mask for SIMD vectors with 32 elements of 8 bits. -pub type mask8x32 = Mask<i8, 32>; - -/// A mask for SIMD vectors with 64 elements of 8 bits. -pub type mask8x64 = Mask<i8, 64>; - -/// A mask for SIMD vectors with four elements of 16 bits. -pub type mask16x4 = Mask<i16, 4>; - -/// A mask for SIMD vectors with eight elements of 16 bits. -pub type mask16x8 = Mask<i16, 8>; - -/// A mask for SIMD vectors with 16 elements of 16 bits. -pub type mask16x16 = Mask<i16, 16>; - -/// A mask for SIMD vectors with 32 elements of 16 bits. -pub type mask16x32 = Mask<i16, 32>; - -/// A mask for SIMD vectors with two elements of 32 bits. -pub type mask32x2 = Mask<i32, 2>; - -/// A mask for SIMD vectors with four elements of 32 bits. -pub type mask32x4 = Mask<i32, 4>; - -/// A mask for SIMD vectors with eight elements of 32 bits. -pub type mask32x8 = Mask<i32, 8>; - -/// A mask for SIMD vectors with 16 elements of 32 bits. -pub type mask32x16 = Mask<i32, 16>; - -/// A mask for SIMD vectors with two elements of 64 bits. -pub type mask64x2 = Mask<i64, 2>; - -/// A mask for SIMD vectors with four elements of 64 bits. -pub type mask64x4 = Mask<i64, 4>; - -/// A mask for SIMD vectors with eight elements of 64 bits. -pub type mask64x8 = Mask<i64, 8>; - -/// A mask for SIMD vectors with two elements of pointer width. -pub type masksizex2 = Mask<isize, 2>; - -/// A mask for SIMD vectors with four elements of pointer width. -pub type masksizex4 = Mask<isize, 4>; - -/// A mask for SIMD vectors with eight elements of pointer width. -pub type masksizex8 = Mask<isize, 8>; - macro_rules! impl_from { { $from:ty => $($to:ty),* } => { $( @@ -581,6 +537,7 @@ macro_rules! impl_from { where LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn from(value: Mask<$from, LANES>) -> Self { value.cast() } diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs index 365ecc0a325..20465ba9b07 100644 --- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs +++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs @@ -26,6 +26,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn clone(&self) -> Self { *self } @@ -36,6 +37,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn eq(&self, other: &Self) -> bool { self.0.as_ref() == other.0.as_ref() } @@ -46,6 +48,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { self.0.as_ref().partial_cmp(other.0.as_ref()) } @@ -63,6 +66,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.as_ref().cmp(other.0.as_ref()) } diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index b5ba198e504..1d13c45b8e7 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -37,6 +37,7 @@ where T: MaskElement + PartialEq, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) } @@ -47,6 +48,7 @@ where T: MaskElement + PartialOrd, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { self.0.partial_cmp(&other.0) } @@ -64,6 +66,7 @@ where T: MaskElement + Ord, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.cmp(&other.0) } @@ -262,6 +265,7 @@ where T: MaskElement, LaneCount<LANES>: SupportedLaneCount, { + #[inline] fn from(value: Mask<T, LANES>) -> Self { value.0 } diff --git a/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs index 2235f016c71..fc7d6b781f2 100644 --- a/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs +++ b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs @@ -48,10 +48,12 @@ macro_rules! impl_integer_intrinsic { impl<T: MaskElement> ToBitMask for Mask<T, $lanes> { type BitMask = $int; + #[inline] fn to_bitmask(self) -> $int { self.0.to_bitmask_integer() } + #[inline] fn from_bitmask(bitmask: $int) -> Self { Self(mask_impl::Mask::from_bitmask_integer(bitmask)) } @@ -83,10 +85,12 @@ where { const BYTES: usize = bitmask_len(LANES); + #[inline] fn to_bitmask_array(self) -> [u8; Self::BYTES] { self.0.to_bitmask_array() } + #[inline] fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self { Mask(mask_impl::Mask::from_bitmask_array(bitmask)) } diff --git a/library/portable-simd/crates/core_simd/src/mod.rs b/library/portable-simd/crates/core_simd/src/mod.rs index b472aa3abe2..35c659b7a42 100644 --- a/library/portable-simd/crates/core_simd/src/mod.rs +++ b/library/portable-simd/crates/core_simd/src/mod.rs @@ -6,6 +6,8 @@ pub(crate) mod intrinsics; #[cfg(feature = "generic_const_exprs")] mod to_bytes; +mod alias; +mod cast; mod elements; mod eq; mod fmt; @@ -15,6 +17,7 @@ mod masks; mod ops; mod ord; mod select; +mod swizzle_dyn; mod vector; mod vendor; @@ -22,11 +25,14 @@ mod vendor; pub mod simd { pub(crate) use crate::core_simd::intrinsics; + pub use crate::core_simd::alias::*; + pub use crate::core_simd::cast::*; pub use crate::core_simd::elements::*; pub use crate::core_simd::eq::*; pub use crate::core_simd::lane_count::{LaneCount, SupportedLaneCount}; pub use crate::core_simd::masks::*; pub use crate::core_simd::ord::*; pub use crate::core_simd::swizzle::*; + pub use crate::core_simd::swizzle_dyn::*; pub use crate::core_simd::vector::*; } diff --git a/library/portable-simd/crates/core_simd/src/ord.rs b/library/portable-simd/crates/core_simd/src/ord.rs index 9a87bc2e344..1ae9cd061fb 100644 --- a/library/portable-simd/crates/core_simd/src/ord.rs +++ b/library/portable-simd/crates/core_simd/src/ord.rs @@ -1,4 +1,6 @@ -use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount}; +use crate::simd::{ + intrinsics, LaneCount, Mask, Simd, SimdConstPtr, SimdMutPtr, SimdPartialEq, SupportedLaneCount, +}; /// Parallel `PartialOrd`. pub trait SimdPartialOrd: SimdPartialEq { @@ -211,3 +213,101 @@ macro_rules! impl_mask { } impl_mask! { i8, i16, i32, i64, isize } + +impl<T, const LANES: usize> SimdPartialOrd for Simd<*const T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + #[inline] + fn simd_lt(self, other: Self) -> Self::Mask { + self.addr().simd_lt(other.addr()) + } + + #[inline] + fn simd_le(self, other: Self) -> Self::Mask { + self.addr().simd_le(other.addr()) + } + + #[inline] + fn simd_gt(self, other: Self) -> Self::Mask { + self.addr().simd_gt(other.addr()) + } + + #[inline] + fn simd_ge(self, other: Self) -> Self::Mask { + self.addr().simd_ge(other.addr()) + } +} + +impl<T, const LANES: usize> SimdOrd for Simd<*const T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + #[inline] + fn simd_max(self, other: Self) -> Self { + self.simd_lt(other).select(other, self) + } + + #[inline] + fn simd_min(self, other: Self) -> Self { + self.simd_gt(other).select(other, self) + } + + #[inline] + fn simd_clamp(self, min: Self, max: Self) -> Self { + assert!( + min.simd_le(max).all(), + "each lane in `min` must be less than or equal to the corresponding lane in `max`", + ); + self.simd_max(min).simd_min(max) + } +} + +impl<T, const LANES: usize> SimdPartialOrd for Simd<*mut T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + #[inline] + fn simd_lt(self, other: Self) -> Self::Mask { + self.addr().simd_lt(other.addr()) + } + + #[inline] + fn simd_le(self, other: Self) -> Self::Mask { + self.addr().simd_le(other.addr()) + } + + #[inline] + fn simd_gt(self, other: Self) -> Self::Mask { + self.addr().simd_gt(other.addr()) + } + + #[inline] + fn simd_ge(self, other: Self) -> Self::Mask { + self.addr().simd_ge(other.addr()) + } +} + +impl<T, const LANES: usize> SimdOrd for Simd<*mut T, LANES> +where + LaneCount<LANES>: SupportedLaneCount, +{ + #[inline] + fn simd_max(self, other: Self) -> Self { + self.simd_lt(other).select(other, self) + } + + #[inline] + fn simd_min(self, other: Self) -> Self { + self.simd_gt(other).select(other, self) + } + + #[inline] + fn simd_clamp(self, min: Self, max: Self) -> Self { + assert!( + min.simd_le(max).all(), + "each lane in `min` must be less than or equal to the corresponding lane in `max`", + ); + self.simd_max(min).simd_min(max) + } +} diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs index 22999d24950..68f20516cf5 100644 --- a/library/portable-simd/crates/core_simd/src/swizzle.rs +++ b/library/portable-simd/crates/core_simd/src/swizzle.rs @@ -265,16 +265,13 @@ where /// Interleave two vectors. /// - /// Produces two vectors with lanes taken alternately from `self` and `other`. + /// The resulting vectors contain lanes taken alternatively from `self` and `other`, first + /// filling the first result, and then the second. /// - /// The first result contains the first `LANES / 2` lanes from `self` and `other`, - /// alternating, starting with the first lane of `self`. - /// - /// The second result contains the last `LANES / 2` lanes from `self` and `other`, - /// alternating, starting with the lane `LANES / 2` from the start of `self`. + /// The reverse of this operation is [`Simd::deinterleave`]. /// /// ``` - /// #![feature(portable_simd)] + /// # #![feature(portable_simd)] /// # use core::simd::Simd; /// let a = Simd::from_array([0, 1, 2, 3]); /// let b = Simd::from_array([4, 5, 6, 7]); @@ -285,29 +282,17 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn interleave(self, other: Self) -> (Self, Self) { - const fn lo<const LANES: usize>() -> [Which; LANES] { - let mut idx = [Which::First(0); LANES]; - let mut i = 0; - while i < LANES { - let offset = i / 2; - idx[i] = if i % 2 == 0 { - Which::First(offset) - } else { - Which::Second(offset) - }; - i += 1; - } - idx - } - const fn hi<const LANES: usize>() -> [Which; LANES] { + const fn interleave<const LANES: usize>(high: bool) -> [Which; LANES] { let mut idx = [Which::First(0); LANES]; let mut i = 0; while i < LANES { - let offset = (LANES + i) / 2; - idx[i] = if i % 2 == 0 { - Which::First(offset) + // Treat the source as a concatenated vector + let dst_index = if high { i + LANES } else { i }; + let src_index = dst_index / 2 + (dst_index % 2) * LANES; + idx[i] = if src_index < LANES { + Which::First(src_index) } else { - Which::Second(offset) + Which::Second(src_index % LANES) }; i += 1; } @@ -318,11 +303,11 @@ where struct Hi; impl<const LANES: usize> Swizzle2<LANES, LANES> for Lo { - const INDEX: [Which; LANES] = lo::<LANES>(); + const INDEX: [Which; LANES] = interleave::<LANES>(false); } impl<const LANES: usize> Swizzle2<LANES, LANES> for Hi { - const INDEX: [Which; LANES] = hi::<LANES>(); + const INDEX: [Which; LANES] = interleave::<LANES>(true); } (Lo::swizzle2(self, other), Hi::swizzle2(self, other)) @@ -336,8 +321,10 @@ where /// The second result takes every other lane of `self` and then `other`, starting with /// the second lane. /// + /// The reverse of this operation is [`Simd::interleave`]. + /// /// ``` - /// #![feature(portable_simd)] + /// # #![feature(portable_simd)] /// # use core::simd::Simd; /// let a = Simd::from_array([0, 4, 1, 5]); /// let b = Simd::from_array([2, 6, 3, 7]); @@ -348,22 +335,17 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn deinterleave(self, other: Self) -> (Self, Self) { - const fn even<const LANES: usize>() -> [Which; LANES] { - let mut idx = [Which::First(0); LANES]; - let mut i = 0; - while i < LANES / 2 { - idx[i] = Which::First(2 * i); - idx[i + LANES / 2] = Which::Second(2 * i); - i += 1; - } - idx - } - const fn odd<const LANES: usize>() -> [Which; LANES] { + const fn deinterleave<const LANES: usize>(second: bool) -> [Which; LANES] { let mut idx = [Which::First(0); LANES]; let mut i = 0; - while i < LANES / 2 { - idx[i] = Which::First(2 * i + 1); - idx[i + LANES / 2] = Which::Second(2 * i + 1); + while i < LANES { + // Treat the source as a concatenated vector + let src_index = i * 2 + second as usize; + idx[i] = if src_index < LANES { + Which::First(src_index) + } else { + Which::Second(src_index % LANES) + }; i += 1; } idx @@ -373,11 +355,11 @@ where struct Odd; impl<const LANES: usize> Swizzle2<LANES, LANES> for Even { - const INDEX: [Which; LANES] = even::<LANES>(); + const INDEX: [Which; LANES] = deinterleave::<LANES>(false); } impl<const LANES: usize> Swizzle2<LANES, LANES> for Odd { - const INDEX: [Which; LANES] = odd::<LANES>(); + const INDEX: [Which; LANES] = deinterleave::<LANES>(true); } (Even::swizzle2(self, other), Odd::swizzle2(self, other)) diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs new file mode 100644 index 00000000000..6065d645937 --- /dev/null +++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs @@ -0,0 +1,157 @@ +use crate::simd::{LaneCount, Simd, SupportedLaneCount}; +use core::mem; + +impl<const N: usize> Simd<u8, N> +where + LaneCount<N>: SupportedLaneCount, +{ + /// Swizzle a vector of bytes according to the index vector. + /// Indices within range select the appropriate byte. + /// Indices "out of bounds" instead select 0. + /// + /// Note that the current implementation is selected during build-time + /// of the standard library, so `cargo build -Zbuild-std` may be necessary + /// to unlock better performance, especially for larger vectors. + /// A planned compiler improvement will enable using `#[target_feature]` instead. + #[inline] + pub fn swizzle_dyn(self, idxs: Simd<u8, N>) -> Self { + #![allow(unused_imports, unused_unsafe)] + #[cfg(target_arch = "aarch64")] + use core::arch::aarch64::{uint8x8_t, vqtbl1q_u8, vtbl1_u8}; + #[cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon"))] + use core::arch::arm::{uint8x8_t, vtbl1_u8}; + #[cfg(target_arch = "wasm32")] + use core::arch::wasm32 as wasm; + #[cfg(target_arch = "x86")] + use core::arch::x86; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64 as x86; + // SAFETY: Intrinsics covered by cfg + unsafe { + match N { + #[cfg(target_feature = "neon")] + 8 => transize(vtbl1_u8, self, idxs), + #[cfg(target_feature = "ssse3")] + 16 => transize(x86::_mm_shuffle_epi8, self, idxs), + #[cfg(target_feature = "simd128")] + 16 => transize(wasm::i8x16_swizzle, self, idxs), + #[cfg(all(target_arch = "aarch64", target_feature = "neon"))] + 16 => transize(vqtbl1q_u8, self, idxs), + #[cfg(all(target_feature = "avx2", not(target_feature = "avx512vbmi")))] + 32 => transize_raw(avx2_pshufb, self, idxs), + #[cfg(target_feature = "avx512vl,avx512vbmi")] + 32 => transize(x86::_mm256_permutexvar_epi8, self, idxs), + // Notable absence: avx512bw shuffle + // If avx512bw is available, odds of avx512vbmi are good + // FIXME: initial AVX512VBMI variant didn't actually pass muster + // #[cfg(target_feature = "avx512vbmi")] + // 64 => transize(x86::_mm512_permutexvar_epi8, self, idxs), + _ => { + let mut array = [0; N]; + for (i, k) in idxs.to_array().into_iter().enumerate() { + if (k as usize) < N { + array[i] = self[k as usize]; + }; + } + array.into() + } + } + } + } +} + +/// "vpshufb like it was meant to be" on AVX2 +/// +/// # Safety +/// This requires AVX2 to work +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[target_feature(enable = "avx2")] +#[allow(unused)] +#[inline] +#[allow(clippy::let_and_return)] +unsafe fn avx2_pshufb(bytes: Simd<u8, 32>, idxs: Simd<u8, 32>) -> Simd<u8, 32> { + use crate::simd::SimdPartialOrd; + #[cfg(target_arch = "x86")] + use core::arch::x86; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64 as x86; + use x86::_mm256_permute2x128_si256 as avx2_cross_shuffle; + use x86::_mm256_shuffle_epi8 as avx2_half_pshufb; + let mid = Simd::splat(16u8); + let high = mid + mid; + // SAFETY: Caller promised AVX2 + unsafe { + // This is ordering sensitive, and LLVM will order these how you put them. + // Most AVX2 impls use ~5 "ports", and only 1 or 2 are capable of permutes. + // But the "compose" step will lower to ops that can also use at least 1 other port. + // So this tries to break up permutes so composition flows through "open" ports. + // Comparative benches should be done on multiple AVX2 CPUs before reordering this + + let hihi = avx2_cross_shuffle::<0x11>(bytes.into(), bytes.into()); + let hi_shuf = Simd::from(avx2_half_pshufb( + hihi, // duplicate the vector's top half + idxs.into(), // so that using only 4 bits of an index still picks bytes 16-31 + )); + // A zero-fill during the compose step gives the "all-Neon-like" OOB-is-0 semantics + let compose = idxs.simd_lt(high).select(hi_shuf, Simd::splat(0)); + let lolo = avx2_cross_shuffle::<0x00>(bytes.into(), bytes.into()); + let lo_shuf = Simd::from(avx2_half_pshufb(lolo, idxs.into())); + // Repeat, then pick indices < 16, overwriting indices 0-15 from previous compose step + let compose = idxs.simd_lt(mid).select(lo_shuf, compose); + compose + } +} + +/// This sets up a call to an architecture-specific function, and in doing so +/// it persuades rustc that everything is the correct size. Which it is. +/// This would not be needed if one could convince Rust that, by matching on N, +/// N is that value, and thus it would be valid to substitute e.g. 16. +/// +/// # Safety +/// The correctness of this function hinges on the sizes agreeing in actuality. +#[allow(dead_code)] +#[inline(always)] +unsafe fn transize<T, const N: usize>( + f: unsafe fn(T, T) -> T, + bytes: Simd<u8, N>, + idxs: Simd<u8, N>, +) -> Simd<u8, N> +where + LaneCount<N>: SupportedLaneCount, +{ + let idxs = zeroing_idxs(idxs); + // SAFETY: Same obligation to use this function as to use mem::transmute_copy. + unsafe { mem::transmute_copy(&f(mem::transmute_copy(&bytes), mem::transmute_copy(&idxs))) } +} + +/// Make indices that yield 0 for this architecture +#[inline(always)] +fn zeroing_idxs<const N: usize>(idxs: Simd<u8, N>) -> Simd<u8, N> +where + LaneCount<N>: SupportedLaneCount, +{ + // On x86, make sure the top bit is set. + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + let idxs = { + use crate::simd::SimdPartialOrd; + idxs.simd_lt(Simd::splat(N as u8)) + .select(idxs, Simd::splat(u8::MAX)) + }; + // Simply do nothing on most architectures. + idxs +} + +/// As transize but no implicit call to `zeroing_idxs`. +#[allow(dead_code)] +#[inline(always)] +unsafe fn transize_raw<T, const N: usize>( + f: unsafe fn(T, T) -> T, + bytes: Simd<u8, N>, + idxs: Simd<u8, N>, +) -> Simd<u8, N> +where + LaneCount<N>: SupportedLaneCount, +{ + // SAFETY: Same obligation to use this function as to use mem::transmute_copy. + unsafe { mem::transmute_copy(&f(mem::transmute_copy(&bytes), mem::transmute_copy(&idxs))) } +} diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs index d52d1ac4d3a..3809cc96151 100644 --- a/library/portable-simd/crates/core_simd/src/vector.rs +++ b/library/portable-simd/crates/core_simd/src/vector.rs @@ -1,60 +1,63 @@ -mod float; -mod int; -mod uint; - -pub use float::*; -pub use int::*; -pub use uint::*; - -// Vectors of pointers are not for public use at the current time. -pub(crate) mod ptr; - use crate::simd::{ - intrinsics, LaneCount, Mask, MaskElement, SimdPartialOrd, SupportedLaneCount, Swizzle, + intrinsics, LaneCount, Mask, MaskElement, SimdCast, SimdCastPtr, SimdConstPtr, SimdMutPtr, + SimdPartialOrd, SupportedLaneCount, Swizzle, }; +use core::convert::{TryFrom, TryInto}; -/// A SIMD vector of `LANES` elements of type `T`. `Simd<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`. +/// A SIMD vector with the shape of `[T; N]` but the operations of `T`. /// -/// Two vectors of the same type and length will, by convention, support the operators (+, *, etc.) that `T` does. -/// These take the lanes at each index on the left-hand side and right-hand side, perform the operation, -/// and return the result in the same lane in a vector of equal size. For a given operator, this is equivalent to zipping -/// the two arrays together and mapping the operator over each lane. +/// `Simd<T, N>` supports the operators (+, *, etc.) that `T` does in "elementwise" fashion. +/// These take the element at each index from the left-hand side and right-hand side, +/// perform the operation, then return the result in the same index in a vector of equal size. +/// However, `Simd` differs from normal iteration and normal arrays: +/// - `Simd<T, N>` executes `N` operations in a single step with no `break`s +/// - `Simd<T, N>` can have an alignment greater than `T`, for better mechanical sympathy +/// +/// By always imposing these constraints on `Simd`, it is easier to compile elementwise operations +/// into machine instructions that can themselves be executed in parallel. /// /// ```rust -/// # #![feature(array_zip, portable_simd)] +/// # #![feature(portable_simd)] /// # use core::simd::{Simd}; -/// let a0: [i32; 4] = [-2, 0, 2, 4]; -/// let a1 = [10, 9, 8, 7]; -/// let zm_add = a0.zip(a1).map(|(lhs, rhs)| lhs + rhs); -/// let zm_mul = a0.zip(a1).map(|(lhs, rhs)| lhs * rhs); +/// # use core::array; +/// let a: [i32; 4] = [-2, 0, 2, 4]; +/// let b = [10, 9, 8, 7]; +/// let sum = array::from_fn(|i| a[i] + b[i]); +/// let prod = array::from_fn(|i| a[i] * b[i]); /// /// // `Simd<T, N>` implements `From<[T; N]>` -/// let (v0, v1) = (Simd::from(a0), Simd::from(a1)); +/// let (v, w) = (Simd::from(a), Simd::from(b)); /// // Which means arrays implement `Into<Simd<T, N>>`. -/// assert_eq!(v0 + v1, zm_add.into()); -/// assert_eq!(v0 * v1, zm_mul.into()); +/// assert_eq!(v + w, sum.into()); +/// assert_eq!(v * w, prod.into()); /// ``` /// -/// `Simd` with integers has the quirk that these operations are also inherently wrapping, as if `T` was [`Wrapping<T>`]. +/// +/// `Simd` with integer elements treats operators as wrapping, as if `T` was [`Wrapping<T>`]. /// Thus, `Simd` does not implement `wrapping_add`, because that is the default behavior. /// This means there is no warning on overflows, even in "debug" builds. /// For most applications where `Simd` is appropriate, it is "not a bug" to wrap, /// and even "debug builds" are unlikely to tolerate the loss of performance. /// You may want to consider using explicitly checked arithmetic if such is required. -/// Division by zero still causes a panic, so you may want to consider using floating point numbers if that is unacceptable. +/// Division by zero on integers still causes a panic, so +/// you may want to consider using `f32` or `f64` if that is unacceptable. /// /// [`Wrapping<T>`]: core::num::Wrapping /// /// # Layout -/// `Simd<T, N>` has a layout similar to `[T; N]` (identical "shapes"), but with a greater alignment. +/// `Simd<T, N>` has a layout similar to `[T; N]` (identical "shapes"), with a greater alignment. /// `[T; N]` is aligned to `T`, but `Simd<T, N>` will have an alignment based on both `T` and `N`. -/// It is thus sound to [`transmute`] `Simd<T, N>` to `[T; N]`, and will typically optimize to zero cost, -/// but the reverse transmutation is more likely to require a copy the compiler cannot simply elide. +/// Thus it is sound to [`transmute`] `Simd<T, N>` to `[T; N]` and should optimize to "zero cost", +/// but the reverse transmutation may require a copy the compiler cannot simply elide. /// /// # ABI "Features" -/// Due to Rust's safety guarantees, `Simd<T, N>` is currently passed to and from functions via memory, not SIMD registers, -/// except as an optimization. `#[inline]` hints are recommended on functions that accept `Simd<T, N>` or return it. -/// The need for this may be corrected in the future. +/// Due to Rust's safety guarantees, `Simd<T, N>` is currently passed and returned via memory, +/// not SIMD registers, except as an optimization. Using `#[inline]` on functions that accept +/// `Simd<T, N>` or return it is recommended, at the cost of code generation time, as +/// inlining SIMD-using functions can omit a large function prolog or epilog and thus +/// improve both speed and code size. The need for this may be corrected in the future. +/// +/// Using `#[inline(always)]` still requires additional care. /// /// # Safe SIMD with Unsafe Rust /// @@ -65,18 +68,22 @@ use crate::simd::{ /// Thus, when using `unsafe` Rust to read and write `Simd<T, N>` through [raw pointers], it is a good idea to first try with /// [`read_unaligned`] and [`write_unaligned`]. This is because: /// - [`read`] and [`write`] require full alignment (in this case, `Simd<T, N>`'s alignment) -/// - the likely source for reading or destination for writing `Simd<T, N>` is [`[T]`](slice) and similar types, aligned to `T` -/// - combining these actions would violate the `unsafe` contract and explode the program into a puff of **undefined behavior** -/// - the compiler can implicitly adjust layouts to make unaligned reads or writes fully aligned if it sees the optimization -/// - most contemporary processors suffer no performance penalty for "unaligned" reads and writes that are aligned at runtime +/// - `Simd<T, N>` is often read from or written to [`[T]`](slice) and other types aligned to `T` +/// - combining these actions violates the `unsafe` contract and explodes the program into +/// a puff of **undefined behavior** +/// - the compiler can implicitly adjust layouts to make unaligned reads or writes fully aligned +/// if it sees the optimization +/// - most contemporary processors with "aligned" and "unaligned" read and write instructions +/// exhibit no performance difference if the "unaligned" variant is aligned at runtime /// -/// By imposing less obligations, unaligned functions are less likely to make the program unsound, +/// Less obligations mean unaligned reads and writes are less likely to make the program unsound, /// and may be just as fast as stricter alternatives. -/// When trying to guarantee alignment, [`[T]::as_simd`][as_simd] is an option for converting `[T]` to `[Simd<T, N>]`, -/// and allows soundly operating on an aligned SIMD body, but it may cost more time when handling the scalar head and tail. -/// If these are not sufficient, then it is most ideal to design data structures to be already aligned -/// to the `Simd<T, N>` you wish to use before using `unsafe` Rust to read or write. -/// More conventional ways to compensate for these facts, like materializing `Simd` to or from an array first, +/// When trying to guarantee alignment, [`[T]::as_simd`][as_simd] is an option for +/// converting `[T]` to `[Simd<T, N>]`, and allows soundly operating on an aligned SIMD body, +/// but it may cost more time when handling the scalar head and tail. +/// If these are not enough, it is most ideal to design data structures to be already aligned +/// to `mem::align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write. +/// Other ways to compensate for these facts, like materializing `Simd` to or from an array first, /// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`]. /// /// [`transmute`]: core::mem::transmute @@ -86,21 +93,26 @@ use crate::simd::{ /// [`read`]: pointer::read /// [`write`]: pointer::write /// [as_simd]: slice::as_simd +// +// NOTE: Accessing the inner array directly in any way (e.g. by using the `.0` field syntax) or +// directly constructing an instance of the type (i.e. `let vector = Simd(array)`) should be +// avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also +// causes rustc to emit illegal LLVM IR in some cases. #[repr(simd)] -pub struct Simd<T, const LANES: usize>([T; LANES]) +pub struct Simd<T, const N: usize>([T; N]) where - T: SimdElement, - LaneCount<LANES>: SupportedLaneCount; + LaneCount<N>: SupportedLaneCount, + T: SimdElement; -impl<T, const LANES: usize> Simd<T, LANES> +impl<T, const N: usize> Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { - /// Number of lanes in this vector. - pub const LANES: usize = LANES; + /// Number of elements in this vector. + pub const LANES: usize = N; - /// Returns the number of lanes in this SIMD vector. + /// Returns the number of elements in this SIMD vector. /// /// # Examples /// @@ -111,10 +123,10 @@ where /// assert_eq!(v.lanes(), 4); /// ``` pub const fn lanes(&self) -> usize { - LANES + Self::LANES } - /// Constructs a new SIMD vector with all lanes set to the given value. + /// Constructs a new SIMD vector with all elements set to the given value. /// /// # Examples /// @@ -125,11 +137,11 @@ where /// assert_eq!(v.as_array(), &[8, 8, 8, 8]); /// ``` pub fn splat(value: T) -> Self { - // This is preferred over `[value; LANES]`, since it's explicitly a splat: + // This is preferred over `[value; N]`, since it's explicitly a splat: // https://github.com/rust-lang/rust/issues/97804 struct Splat; - impl<const LANES: usize> Swizzle<1, LANES> for Splat { - const INDEX: [usize; LANES] = [0; LANES]; + impl<const N: usize> Swizzle<1, N> for Splat { + const INDEX: [usize; N] = [0; N]; } Splat::swizzle(Simd::<T, 1>::from([value])) } @@ -144,32 +156,100 @@ where /// let v: u64x4 = Simd::from_array([0, 1, 2, 3]); /// assert_eq!(v.as_array(), &[0, 1, 2, 3]); /// ``` - pub const fn as_array(&self) -> &[T; LANES] { - &self.0 + pub const fn as_array(&self) -> &[T; N] { + // SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with + // potential padding at the end, so pointer casting to a + // `&[T; N]` is safe. + // + // NOTE: This deliberately doesn't just use `&self.0`, see the comment + // on the struct definition for details. + unsafe { &*(self as *const Self as *const [T; N]) } } /// Returns a mutable array reference containing the entire SIMD vector. - pub fn as_mut_array(&mut self) -> &mut [T; LANES] { - &mut self.0 + pub fn as_mut_array(&mut self) -> &mut [T; N] { + // SAFETY: `Simd<T, N>` is just an overaligned `[T; N]` with + // potential padding at the end, so pointer casting to a + // `&mut [T; N]` is safe. + // + // NOTE: This deliberately doesn't just use `&mut self.0`, see the comment + // on the struct definition for details. + unsafe { &mut *(self as *mut Self as *mut [T; N]) } + } + + /// Load a vector from an array of `T`. + /// + /// This function is necessary since `repr(simd)` has padding for non-power-of-2 vectors (at the time of writing). + /// With padding, `read_unaligned` will read past the end of an array of N elements. + /// + /// # Safety + /// Reading `ptr` must be safe, as if by `<*const [T; N]>::read_unaligned`. + const unsafe fn load(ptr: *const [T; N]) -> Self { + // There are potentially simpler ways to write this function, but this should result in + // LLVM `load <N x T>` + + let mut tmp = core::mem::MaybeUninit::<Self>::uninit(); + // SAFETY: `Simd<T, N>` always contains `N` elements of type `T`. It may have padding + // which does not need to be initialized. The safety of reading `ptr` is ensured by the + // caller. + unsafe { + core::ptr::copy_nonoverlapping(ptr, tmp.as_mut_ptr().cast(), 1); + tmp.assume_init() + } + } + + /// Store a vector to an array of `T`. + /// + /// See `load` as to why this function is necessary. + /// + /// # Safety + /// Writing to `ptr` must be safe, as if by `<*mut [T; N]>::write_unaligned`. + const unsafe fn store(self, ptr: *mut [T; N]) { + // There are potentially simpler ways to write this function, but this should result in + // LLVM `store <N x T>` + + // Creating a temporary helps LLVM turn the memcpy into a store. + let tmp = self; + // SAFETY: `Simd<T, N>` always contains `N` elements of type `T`. The safety of writing + // `ptr` is ensured by the caller. + unsafe { core::ptr::copy_nonoverlapping(tmp.as_array(), ptr, 1) } } /// Converts an array to a SIMD vector. - pub const fn from_array(array: [T; LANES]) -> Self { - Self(array) + pub const fn from_array(array: [T; N]) -> Self { + // SAFETY: `&array` is safe to read. + // + // FIXME: We currently use a pointer load instead of `transmute_copy` because `repr(simd)` + // results in padding for non-power-of-2 vectors (so vectors are larger than arrays). + // + // NOTE: This deliberately doesn't just use `Self(array)`, see the comment + // on the struct definition for details. + unsafe { Self::load(&array) } } /// Converts a SIMD vector to an array. - pub const fn to_array(self) -> [T; LANES] { - self.0 + pub const fn to_array(self) -> [T; N] { + let mut tmp = core::mem::MaybeUninit::uninit(); + // SAFETY: writing to `tmp` is safe and initializes it. + // + // FIXME: We currently use a pointer store instead of `transmute_copy` because `repr(simd)` + // results in padding for non-power-of-2 vectors (so vectors are larger than arrays). + // + // NOTE: This deliberately doesn't just use `self.0`, see the comment + // on the struct definition for details. + unsafe { + self.store(tmp.as_mut_ptr()); + tmp.assume_init() + } } - /// Converts a slice to a SIMD vector containing `slice[..LANES]`. + /// Converts a slice to a SIMD vector containing `slice[..N]`. /// /// # Panics /// - /// Panics if the slice's length is less than the vector's `Simd::LANES`. + /// Panics if the slice's length is less than the vector's `Simd::N`. /// - /// # Examples + /// # Example /// /// ``` /// # #![feature(portable_simd)] @@ -180,22 +260,49 @@ where /// ``` #[must_use] pub const fn from_slice(slice: &[T]) -> Self { - assert!(slice.len() >= LANES, "slice length must be at least the number of lanes"); - let mut array = [slice[0]; LANES]; - let mut i = 0; - while i < LANES { - array[i] = slice[i]; - i += 1; - } - Self(array) + assert!( + slice.len() >= Self::LANES, + "slice length must be at least the number of elements" + ); + // SAFETY: We just checked that the slice contains + // at least `N` elements. + unsafe { Self::load(slice.as_ptr().cast()) } + } + + /// Writes a SIMD vector to the first `N` elements of a slice. + /// + /// # Panics + /// + /// Panics if the slice's length is less than the vector's `Simd::N`. + /// + /// # Example + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::u32x4; + /// let mut dest = vec![0; 6]; + /// let v = u32x4::from_array([1, 2, 3, 4]); + /// v.copy_to_slice(&mut dest); + /// assert_eq!(&dest, &[1, 2, 3, 4, 0, 0]); + /// ``` + pub fn copy_to_slice(self, slice: &mut [T]) { + assert!( + slice.len() >= Self::LANES, + "slice length must be at least the number of elements" + ); + // SAFETY: We just checked that the slice contains + // at least `N` elements. + unsafe { self.store(slice.as_mut_ptr().cast()) } } - /// Performs lanewise conversion of a SIMD vector's elements to another SIMD-valid type. + /// Performs elementwise conversion of a SIMD vector's elements to another SIMD-valid type. /// - /// This follows the semantics of Rust's `as` conversion for casting - /// integers to unsigned integers (interpreting as the other type, so `-1` to `MAX`), - /// and from floats to integers (truncating, or saturating at the limits) for each lane, - /// or vice versa. + /// This follows the semantics of Rust's `as` conversion for casting integers between + /// signed and unsigned (interpreting integers as 2s complement, so `-1` to `U::MAX` and + /// `1 << (U::BITS -1)` becoming `I::MIN` ), and from floats to integers (truncating, + /// or saturating at the limits) for each element. /// /// # Examples /// ``` @@ -215,11 +322,26 @@ where /// ``` #[must_use] #[inline] - pub fn cast<U: SimdElement>(self) -> Simd<U, LANES> { - // Safety: The input argument is a vector of a valid SIMD element type. + pub fn cast<U: SimdCast>(self) -> Simd<U, N> + where + T: SimdCast, + { + // Safety: supported types are guaranteed by SimdCast unsafe { intrinsics::simd_as(self) } } + /// Casts a vector of pointers to another pointer type. + #[must_use] + #[inline] + pub fn cast_ptr<U>(self) -> Simd<U, N> + where + T: SimdCastPtr<U>, + U: SimdElement, + { + // Safety: supported types are guaranteed by SimdCastPtr + unsafe { intrinsics::simd_cast_ptr(self) } + } + /// Rounds toward zero and converts to the same-width integer type, assuming that /// the value is finite and fits in that type. /// @@ -235,90 +357,90 @@ where /// /// [cast]: Simd::cast #[inline] - pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, LANES> + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, N> where - T: core::convert::FloatToInt<I>, - I: SimdElement, + T: core::convert::FloatToInt<I> + SimdCast, + I: SimdCast, { - // Safety: `self` is a vector, and `FloatToInt` ensures the type can be casted to - // an integer. + // Safety: supported types are guaranteed by SimdCast, the caller is responsible for the extra invariants unsafe { intrinsics::simd_cast(self) } } /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. - /// If an index is out-of-bounds, the lane is instead selected from the `or` vector. + /// If an index is out-of-bounds, the element is instead selected from the `or` vector. /// /// # Examples /// ``` /// # #![feature(portable_simd)] /// # use core::simd::Simd; /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 5]); + /// let idxs = Simd::from_array([9, 3, 0, 5]); // Note the index that is out-of-bounds /// let alt = Simd::from_array([-5, -4, -3, -2]); /// - /// let result = Simd::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds. + /// let result = Simd::gather_or(&vec, idxs, alt); /// assert_eq!(result, Simd::from_array([-5, 13, 10, 15])); /// ``` #[must_use] #[inline] - pub fn gather_or(slice: &[T], idxs: Simd<usize, LANES>, or: Self) -> Self { + pub fn gather_or(slice: &[T], idxs: Simd<usize, N>, or: Self) -> Self { Self::gather_select(slice, Mask::splat(true), idxs, or) } - /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. - /// If an index is out-of-bounds, the lane is set to the default value for the type. + /// Reads from indices in `slice` to construct a SIMD vector. + /// If an index is out-of-bounds, the element is set to the default given by `T: Default`. /// /// # Examples /// ``` /// # #![feature(portable_simd)] /// # use core::simd::Simd; /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 5]); + /// let idxs = Simd::from_array([9, 3, 0, 5]); // Note the index that is out-of-bounds /// - /// let result = Simd::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds. + /// let result = Simd::gather_or_default(&vec, idxs); /// assert_eq!(result, Simd::from_array([0, 13, 10, 15])); /// ``` #[must_use] #[inline] - pub fn gather_or_default(slice: &[T], idxs: Simd<usize, LANES>) -> Self + pub fn gather_or_default(slice: &[T], idxs: Simd<usize, N>) -> Self where T: Default, { Self::gather_or(slice, idxs, Self::splat(T::default())) } - /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. - /// The mask `enable`s all `true` lanes and disables all `false` lanes. - /// If an index is disabled or is out-of-bounds, the lane is selected from the `or` vector. + /// Reads from indices in `slice` to construct a SIMD vector. + /// The mask `enable`s all `true` indices and disables all `false` indices. + /// If an index is disabled or is out-of-bounds, the element is selected from the `or` vector. /// /// # Examples /// ``` /// # #![feature(portable_simd)] /// # use core::simd::{Simd, Mask}; /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 5]); + /// let idxs = Simd::from_array([9, 3, 0, 5]); // Includes an out-of-bounds index /// let alt = Simd::from_array([-5, -4, -3, -2]); - /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane. + /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element /// - /// let result = Simd::gather_select(&vec, enable, idxs, alt); // Note the lane that is out-of-bounds. + /// let result = Simd::gather_select(&vec, enable, idxs, alt); /// assert_eq!(result, Simd::from_array([-5, 13, 10, -2])); /// ``` #[must_use] #[inline] pub fn gather_select( slice: &[T], - enable: Mask<isize, LANES>, - idxs: Simd<usize, LANES>, + enable: Mask<isize, N>, + idxs: Simd<usize, N>, or: Self, ) -> Self { - let enable: Mask<isize, LANES> = enable & idxs.simd_lt(Simd::splat(slice.len())); - // Safety: We have masked-off out-of-bounds lanes. + let enable: Mask<isize, N> = enable & idxs.simd_lt(Simd::splat(slice.len())); + // Safety: We have masked-off out-of-bounds indices. unsafe { Self::gather_select_unchecked(slice, enable, idxs, or) } } - /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. - /// The mask `enable`s all `true` lanes and disables all `false` lanes. - /// If an index is disabled, the lane is selected from the `or` vector. + /// Reads from indices in `slice` to construct a SIMD vector. + /// The mask `enable`s all `true` indices and disables all `false` indices. + /// If an index is disabled, the element is selected from the `or` vector. /// /// # Safety /// @@ -332,57 +454,123 @@ where /// # #[cfg(not(feature = "as_crate"))] use core::simd; /// # use simd::{Simd, SimdPartialOrd, Mask}; /// let vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 5]); + /// let idxs = Simd::from_array([9, 3, 0, 5]); // Includes an out-of-bounds index /// let alt = Simd::from_array([-5, -4, -3, -2]); - /// let enable = Mask::from_array([true, true, true, false]); // Note the final mask lane. + /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element /// // If this mask was used to gather, it would be unsound. Let's fix that. /// let enable = enable & idxs.simd_lt(Simd::splat(vec.len())); /// - /// // We have masked the OOB lane, so it's safe to gather now. + /// // The out-of-bounds index has been masked, so it's safe to gather now. /// let result = unsafe { Simd::gather_select_unchecked(&vec, enable, idxs, alt) }; /// assert_eq!(result, Simd::from_array([-5, 13, 10, -2])); /// ``` /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[must_use] #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn gather_select_unchecked( slice: &[T], - enable: Mask<isize, LANES>, - idxs: Simd<usize, LANES>, + enable: Mask<isize, N>, + idxs: Simd<usize, N>, or: Self, ) -> Self { - let base_ptr = crate::simd::ptr::SimdConstPtr::splat(slice.as_ptr()); + let base_ptr = Simd::<*const T, N>::splat(slice.as_ptr()); // Ferris forgive me, I have done pointer arithmetic here. let ptrs = base_ptr.wrapping_add(idxs); - // Safety: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah - unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) } + // Safety: The caller is responsible for determining the indices are okay to read + unsafe { Self::gather_select_ptr(ptrs, enable, or) } + } + + /// Read elementwise from pointers into a SIMD vector. + /// + /// # Safety + /// + /// Each read must satisfy the same conditions as [`core::ptr::read`]. + /// + /// # Example + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::{Simd, SimdConstPtr}; + /// let values = [6, 2, 4, 9]; + /// let offsets = Simd::from_array([1, 0, 0, 3]); + /// let source = Simd::splat(values.as_ptr()).wrapping_add(offsets); + /// let gathered = unsafe { Simd::gather_ptr(source) }; + /// assert_eq!(gathered, Simd::from_array([2, 6, 6, 9])); + /// ``` + #[must_use] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub unsafe fn gather_ptr(source: Simd<*const T, N>) -> Self + where + T: Default, + { + // TODO: add an intrinsic that doesn't use a passthru vector, and remove the T: Default bound + // Safety: The caller is responsible for upholding all invariants + unsafe { Self::gather_select_ptr(source, Mask::splat(true), Self::default()) } + } + + /// Conditionally read elementwise from pointers into a SIMD vector. + /// The mask `enable`s all `true` pointers and disables all `false` pointers. + /// If a pointer is disabled, the element is selected from the `or` vector, + /// and no read is performed. + /// + /// # Safety + /// + /// Enabled elements must satisfy the same conditions as [`core::ptr::read`]. + /// + /// # Example + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::{Mask, Simd, SimdConstPtr}; + /// let values = [6, 2, 4, 9]; + /// let enable = Mask::from_array([true, true, false, true]); + /// let offsets = Simd::from_array([1, 0, 0, 3]); + /// let source = Simd::splat(values.as_ptr()).wrapping_add(offsets); + /// let gathered = unsafe { Simd::gather_select_ptr(source, enable, Simd::splat(0)) }; + /// assert_eq!(gathered, Simd::from_array([2, 6, 0, 9])); + /// ``` + #[must_use] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub unsafe fn gather_select_ptr( + source: Simd<*const T, N>, + enable: Mask<isize, N>, + or: Self, + ) -> Self { + // Safety: The caller is responsible for upholding all invariants + unsafe { intrinsics::simd_gather(or, source, enable.to_int()) } } /// Writes the values in a SIMD vector to potentially discontiguous indices in `slice`. - /// If two lanes in the scattered vector would write to the same index - /// only the last lane is guaranteed to actually be written. + /// If an index is out-of-bounds, the write is suppressed without panicking. + /// If two elements in the scattered vector would write to the same index + /// only the last element is guaranteed to actually be written. /// /// # Examples /// ``` /// # #![feature(portable_simd)] /// # use core::simd::Simd; /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 0]); + /// let idxs = Simd::from_array([9, 3, 0, 0]); // Note the duplicate index. /// let vals = Simd::from_array([-27, 82, -41, 124]); /// - /// vals.scatter(&mut vec, idxs); // index 0 receives two writes. + /// vals.scatter(&mut vec, idxs); // two logical writes means the last wins. /// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]); /// ``` #[inline] - pub fn scatter(self, slice: &mut [T], idxs: Simd<usize, LANES>) { + pub fn scatter(self, slice: &mut [T], idxs: Simd<usize, N>) { self.scatter_select(slice, Mask::splat(true), idxs) } - /// Writes the values in a SIMD vector to multiple potentially discontiguous indices in `slice`. - /// The mask `enable`s all `true` lanes and disables all `false` lanes. - /// If an enabled index is out-of-bounds, the lane is not written. - /// If two enabled lanes in the scattered vector would write to the same index, - /// only the last lane is guaranteed to actually be written. + /// Writes values from a SIMD vector to multiple potentially discontiguous indices in `slice`. + /// The mask `enable`s all `true` indices and disables all `false` indices. + /// If an enabled index is out-of-bounds, the write is suppressed without panicking. + /// If two enabled elements in the scattered vector would write to the same index, + /// only the last element is guaranteed to actually be written. /// /// # Examples /// ``` @@ -391,29 +579,24 @@ where /// # #[cfg(not(feature = "as_crate"))] use core::simd; /// # use simd::{Simd, Mask}; /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = Simd::from_array([9, 3, 0, 0]); + /// let idxs = Simd::from_array([9, 3, 0, 0]); // Includes an out-of-bounds index /// let vals = Simd::from_array([-27, 82, -41, 124]); - /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane. + /// let enable = Mask::from_array([true, true, true, false]); // Includes a masked element /// - /// vals.scatter_select(&mut vec, enable, idxs); // index 0's second write is masked, thus omitted. + /// vals.scatter_select(&mut vec, enable, idxs); // The last write is masked, thus omitted. /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]); /// ``` #[inline] - pub fn scatter_select( - self, - slice: &mut [T], - enable: Mask<isize, LANES>, - idxs: Simd<usize, LANES>, - ) { - let enable: Mask<isize, LANES> = enable & idxs.simd_lt(Simd::splat(slice.len())); - // Safety: We have masked-off out-of-bounds lanes. + pub fn scatter_select(self, slice: &mut [T], enable: Mask<isize, N>, idxs: Simd<usize, N>) { + let enable: Mask<isize, N> = enable & idxs.simd_lt(Simd::splat(slice.len())); + // Safety: We have masked-off out-of-bounds indices. unsafe { self.scatter_select_unchecked(slice, enable, idxs) } } - /// Writes the values in a SIMD vector to multiple potentially discontiguous indices in `slice`. - /// The mask `enable`s all `true` lanes and disables all `false` lanes. - /// If two enabled lanes in the scattered vector would write to the same index, - /// only the last lane is guaranteed to actually be written. + /// Writes values from a SIMD vector to multiple potentially discontiguous indices in `slice`. + /// The mask `enable`s all `true` indices and disables all `false` indices. + /// If two enabled elements in the scattered vector would write to the same index, + /// only the last element is guaranteed to actually be written. /// /// # Safety /// @@ -429,22 +612,23 @@ where /// let mut vec: Vec<i32> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; /// let idxs = Simd::from_array([9, 3, 0, 0]); /// let vals = Simd::from_array([-27, 82, -41, 124]); - /// let enable = Mask::from_array([true, true, true, false]); // Note the mask of the last lane. + /// let enable = Mask::from_array([true, true, true, false]); // Masks the final index /// // If this mask was used to scatter, it would be unsound. Let's fix that. /// let enable = enable & idxs.simd_lt(Simd::splat(vec.len())); /// - /// // We have masked the OOB lane, so it's safe to scatter now. + /// // We have masked the OOB index, so it's safe to scatter now. /// unsafe { vals.scatter_select_unchecked(&mut vec, enable, idxs); } - /// // index 0's second write is masked, thus was omitted. + /// // The second write to index 0 was masked, thus omitted. /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]); /// ``` /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn scatter_select_unchecked( self, slice: &mut [T], - enable: Mask<isize, LANES>, - idxs: Simd<usize, LANES>, + enable: Mask<isize, N>, + idxs: Simd<usize, N>, ) { // Safety: This block works with *mut T derived from &mut 'a [T], // which means it is delicate in Rust's borrowing model, circa 2021: @@ -458,36 +642,89 @@ where // 3. &mut [T] which will become our base ptr. unsafe { // Now Entering â˜¢ï¸ *mut T Zone - let base_ptr = crate::simd::ptr::SimdMutPtr::splat(slice.as_mut_ptr()); + let base_ptr = Simd::<*mut T, N>::splat(slice.as_mut_ptr()); // Ferris forgive me, I have done pointer arithmetic here. let ptrs = base_ptr.wrapping_add(idxs); // The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah - intrinsics::simd_scatter(self, ptrs, enable.to_int()) + self.scatter_select_ptr(ptrs, enable); // Cleared â˜¢ï¸ *mut T Zone } } + + /// Write pointers elementwise into a SIMD vector. + /// + /// # Safety + /// + /// Each write must satisfy the same conditions as [`core::ptr::write`]. + /// + /// # Example + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::{Simd, SimdMutPtr}; + /// let mut values = [0; 4]; + /// let offset = Simd::from_array([3, 2, 1, 0]); + /// let ptrs = Simd::splat(values.as_mut_ptr()).wrapping_add(offset); + /// unsafe { Simd::from_array([6, 3, 5, 7]).scatter_ptr(ptrs); } + /// assert_eq!(values, [7, 5, 3, 6]); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub unsafe fn scatter_ptr(self, dest: Simd<*mut T, N>) { + // Safety: The caller is responsible for upholding all invariants + unsafe { self.scatter_select_ptr(dest, Mask::splat(true)) } + } + + /// Conditionally write pointers elementwise into a SIMD vector. + /// The mask `enable`s all `true` pointers and disables all `false` pointers. + /// If a pointer is disabled, the write to its pointee is skipped. + /// + /// # Safety + /// + /// Enabled pointers must satisfy the same conditions as [`core::ptr::write`]. + /// + /// # Example + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::{Mask, Simd, SimdMutPtr}; + /// let mut values = [0; 4]; + /// let offset = Simd::from_array([3, 2, 1, 0]); + /// let ptrs = Simd::splat(values.as_mut_ptr()).wrapping_add(offset); + /// let enable = Mask::from_array([true, true, false, false]); + /// unsafe { Simd::from_array([6, 3, 5, 7]).scatter_select_ptr(ptrs, enable); } + /// assert_eq!(values, [0, 0, 3, 6]); + /// ``` + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub unsafe fn scatter_select_ptr(self, dest: Simd<*mut T, N>, enable: Mask<isize, N>) { + // Safety: The caller is responsible for upholding all invariants + unsafe { intrinsics::simd_scatter(self, dest, enable.to_int()) } + } } -impl<T, const LANES: usize> Copy for Simd<T, LANES> +impl<T, const N: usize> Copy for Simd<T, N> where + LaneCount<N>: SupportedLaneCount, T: SimdElement, - LaneCount<LANES>: SupportedLaneCount, { } -impl<T, const LANES: usize> Clone for Simd<T, LANES> +impl<T, const N: usize> Clone for Simd<T, N> where + LaneCount<N>: SupportedLaneCount, T: SimdElement, - LaneCount<LANES>: SupportedLaneCount, { fn clone(&self) -> Self { *self } } -impl<T, const LANES: usize> Default for Simd<T, LANES> +impl<T, const N: usize> Default for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + Default, { #[inline] @@ -496,20 +733,20 @@ where } } -impl<T, const LANES: usize> PartialEq for Simd<T, LANES> +impl<T, const N: usize> PartialEq for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + PartialEq, { #[inline] fn eq(&self, other: &Self) -> bool { // Safety: All SIMD vectors are SimdPartialEq, and the comparison produces a valid mask. let mask = unsafe { - let tfvec: Simd<<T as SimdElement>::Mask, LANES> = intrinsics::simd_eq(*self, *other); + let tfvec: Simd<<T as SimdElement>::Mask, N> = intrinsics::simd_eq(*self, *other); Mask::from_int_unchecked(tfvec) }; - // Two vectors are equal if all lanes tested true for vertical equality. + // Two vectors are equal if all elements are equal when compared elementwise mask.all() } @@ -518,18 +755,18 @@ where fn ne(&self, other: &Self) -> bool { // Safety: All SIMD vectors are SimdPartialEq, and the comparison produces a valid mask. let mask = unsafe { - let tfvec: Simd<<T as SimdElement>::Mask, LANES> = intrinsics::simd_ne(*self, *other); + let tfvec: Simd<<T as SimdElement>::Mask, N> = intrinsics::simd_ne(*self, *other); Mask::from_int_unchecked(tfvec) }; - // Two vectors are non-equal if any lane tested true for vertical non-equality. + // Two vectors are non-equal if any elements are non-equal when compared elementwise mask.any() } } -impl<T, const LANES: usize> PartialOrd for Simd<T, LANES> +impl<T, const N: usize> PartialOrd for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + PartialOrd, { #[inline] @@ -539,16 +776,16 @@ where } } -impl<T, const LANES: usize> Eq for Simd<T, LANES> +impl<T, const N: usize> Eq for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + Eq, { } -impl<T, const LANES: usize> Ord for Simd<T, LANES> +impl<T, const N: usize> Ord for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + Ord, { #[inline] @@ -558,9 +795,9 @@ where } } -impl<T, const LANES: usize> core::hash::Hash for Simd<T, LANES> +impl<T, const N: usize> core::hash::Hash for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement + core::hash::Hash, { #[inline] @@ -573,72 +810,96 @@ where } // array references -impl<T, const LANES: usize> AsRef<[T; LANES]> for Simd<T, LANES> +impl<T, const N: usize> AsRef<[T; N]> for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { #[inline] - fn as_ref(&self) -> &[T; LANES] { - &self.0 + fn as_ref(&self) -> &[T; N] { + self.as_array() } } -impl<T, const LANES: usize> AsMut<[T; LANES]> for Simd<T, LANES> +impl<T, const N: usize> AsMut<[T; N]> for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { #[inline] - fn as_mut(&mut self) -> &mut [T; LANES] { - &mut self.0 + fn as_mut(&mut self) -> &mut [T; N] { + self.as_mut_array() } } // slice references -impl<T, const LANES: usize> AsRef<[T]> for Simd<T, LANES> +impl<T, const N: usize> AsRef<[T]> for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { #[inline] fn as_ref(&self) -> &[T] { - &self.0 + self.as_array() } } -impl<T, const LANES: usize> AsMut<[T]> for Simd<T, LANES> +impl<T, const N: usize> AsMut<[T]> for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { #[inline] fn as_mut(&mut self) -> &mut [T] { - &mut self.0 + self.as_mut_array() } } // vector/array conversion -impl<T, const LANES: usize> From<[T; LANES]> for Simd<T, LANES> +impl<T, const N: usize> From<[T; N]> for Simd<T, N> where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { - fn from(array: [T; LANES]) -> Self { - Self(array) + fn from(array: [T; N]) -> Self { + Self::from_array(array) } } -impl<T, const LANES: usize> From<Simd<T, LANES>> for [T; LANES] +impl<T, const N: usize> From<Simd<T, N>> for [T; N] where - LaneCount<LANES>: SupportedLaneCount, + LaneCount<N>: SupportedLaneCount, T: SimdElement, { - fn from(vector: Simd<T, LANES>) -> Self { + fn from(vector: Simd<T, N>) -> Self { vector.to_array() } } +impl<T, const N: usize> TryFrom<&[T]> for Simd<T, N> +where + LaneCount<N>: SupportedLaneCount, + T: SimdElement, +{ + type Error = core::array::TryFromSliceError; + + fn try_from(slice: &[T]) -> Result<Self, core::array::TryFromSliceError> { + Ok(Self::from_array(slice.try_into()?)) + } +} + +impl<T, const N: usize> TryFrom<&mut [T]> for Simd<T, N> +where + LaneCount<N>: SupportedLaneCount, + T: SimdElement, +{ + type Error = core::array::TryFromSliceError; + + fn try_from(slice: &mut [T]) -> Result<Self, core::array::TryFromSliceError> { + Ok(Self::from_array(slice.try_into()?)) + } +} + mod sealed { pub trait Sealed {} } @@ -740,3 +1001,27 @@ impl Sealed for f64 {} unsafe impl SimdElement for f64 { type Mask = i64; } + +impl<T> Sealed for *const T {} + +// Safety: (thin) const pointers are valid SIMD element types, and are supported by this API +// +// Fat pointers may be supported in the future. +unsafe impl<T> SimdElement for *const T +where + T: core::ptr::Pointee<Metadata = ()>, +{ + type Mask = isize; +} + +impl<T> Sealed for *mut T {} + +// Safety: (thin) mut pointers are valid SIMD element types, and are supported by this API +// +// Fat pointers may be supported in the future. +unsafe impl<T> SimdElement for *mut T +where + T: core::ptr::Pointee<Metadata = ()>, +{ + type Mask = isize; +} diff --git a/library/portable-simd/crates/core_simd/src/vector/float.rs b/library/portable-simd/crates/core_simd/src/vector/float.rs deleted file mode 100644 index f836c99b1e2..00000000000 --- a/library/portable-simd/crates/core_simd/src/vector/float.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![allow(non_camel_case_types)] - -use crate::simd::Simd; - -/// A 64-bit SIMD vector with two elements of type `f32`. -pub type f32x2 = Simd<f32, 2>; - -/// A 128-bit SIMD vector with four elements of type `f32`. -pub type f32x4 = Simd<f32, 4>; - -/// A 256-bit SIMD vector with eight elements of type `f32`. -pub type f32x8 = Simd<f32, 8>; - -/// A 512-bit SIMD vector with 16 elements of type `f32`. -pub type f32x16 = Simd<f32, 16>; - -/// A 128-bit SIMD vector with two elements of type `f64`. -pub type f64x2 = Simd<f64, 2>; - -/// A 256-bit SIMD vector with four elements of type `f64`. -pub type f64x4 = Simd<f64, 4>; - -/// A 512-bit SIMD vector with eight elements of type `f64`. -pub type f64x8 = Simd<f64, 8>; diff --git a/library/portable-simd/crates/core_simd/src/vector/int.rs b/library/portable-simd/crates/core_simd/src/vector/int.rs deleted file mode 100644 index 20e56c7dc64..00000000000 --- a/library/portable-simd/crates/core_simd/src/vector/int.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow(non_camel_case_types)] - -use crate::simd::Simd; - -/// A SIMD vector with two elements of type `isize`. -pub type isizex2 = Simd<isize, 2>; - -/// A SIMD vector with four elements of type `isize`. -pub type isizex4 = Simd<isize, 4>; - -/// A SIMD vector with eight elements of type `isize`. -pub type isizex8 = Simd<isize, 8>; - -/// A 32-bit SIMD vector with two elements of type `i16`. -pub type i16x2 = Simd<i16, 2>; - -/// A 64-bit SIMD vector with four elements of type `i16`. -pub type i16x4 = Simd<i16, 4>; - -/// A 128-bit SIMD vector with eight elements of type `i16`. -pub type i16x8 = Simd<i16, 8>; - -/// A 256-bit SIMD vector with 16 elements of type `i16`. -pub type i16x16 = Simd<i16, 16>; - -/// A 512-bit SIMD vector with 32 elements of type `i16`. -pub type i16x32 = Simd<i16, 32>; - -/// A 64-bit SIMD vector with two elements of type `i32`. -pub type i32x2 = Simd<i32, 2>; - -/// A 128-bit SIMD vector with four elements of type `i32`. -pub type i32x4 = Simd<i32, 4>; - -/// A 256-bit SIMD vector with eight elements of type `i32`. -pub type i32x8 = Simd<i32, 8>; - -/// A 512-bit SIMD vector with 16 elements of type `i32`. -pub type i32x16 = Simd<i32, 16>; - -/// A 128-bit SIMD vector with two elements of type `i64`. -pub type i64x2 = Simd<i64, 2>; - -/// A 256-bit SIMD vector with four elements of type `i64`. -pub type i64x4 = Simd<i64, 4>; - -/// A 512-bit SIMD vector with eight elements of type `i64`. -pub type i64x8 = Simd<i64, 8>; - -/// A 32-bit SIMD vector with four elements of type `i8`. -pub type i8x4 = Simd<i8, 4>; - -/// A 64-bit SIMD vector with eight elements of type `i8`. -pub type i8x8 = Simd<i8, 8>; - -/// A 128-bit SIMD vector with 16 elements of type `i8`. -pub type i8x16 = Simd<i8, 16>; - -/// A 256-bit SIMD vector with 32 elements of type `i8`. -pub type i8x32 = Simd<i8, 32>; - -/// A 512-bit SIMD vector with 64 elements of type `i8`. -pub type i8x64 = Simd<i8, 64>; diff --git a/library/portable-simd/crates/core_simd/src/vector/ptr.rs b/library/portable-simd/crates/core_simd/src/vector/ptr.rs deleted file mode 100644 index fa756344db9..00000000000 --- a/library/portable-simd/crates/core_simd/src/vector/ptr.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! Private implementation details of public gather/scatter APIs. -use crate::simd::intrinsics; -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; - -/// A vector of *const T. -#[derive(Debug, Copy, Clone)] -#[repr(simd)] -pub(crate) struct SimdConstPtr<T, const LANES: usize>([*const T; LANES]); - -impl<T, const LANES: usize> SimdConstPtr<T, LANES> -where - LaneCount<LANES>: SupportedLaneCount, - T: Sized, -{ - #[inline] - #[must_use] - pub fn splat(ptr: *const T) -> Self { - Self([ptr; LANES]) - } - - #[inline] - #[must_use] - pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self { - // Safety: this intrinsic doesn't have a precondition - unsafe { intrinsics::simd_arith_offset(self, addend) } - } -} - -/// A vector of *mut T. Be very careful around potential aliasing. -#[derive(Debug, Copy, Clone)] -#[repr(simd)] -pub(crate) struct SimdMutPtr<T, const LANES: usize>([*mut T; LANES]); - -impl<T, const LANES: usize> SimdMutPtr<T, LANES> -where - LaneCount<LANES>: SupportedLaneCount, - T: Sized, -{ - #[inline] - #[must_use] - pub fn splat(ptr: *mut T) -> Self { - Self([ptr; LANES]) - } - - #[inline] - #[must_use] - pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self { - // Safety: this intrinsic doesn't have a precondition - unsafe { intrinsics::simd_arith_offset(self, addend) } - } -} diff --git a/library/portable-simd/crates/core_simd/src/vector/uint.rs b/library/portable-simd/crates/core_simd/src/vector/uint.rs deleted file mode 100644 index b4a69c44363..00000000000 --- a/library/portable-simd/crates/core_simd/src/vector/uint.rs +++ /dev/null @@ -1,63 +0,0 @@ -#![allow(non_camel_case_types)] - -use crate::simd::Simd; - -/// A SIMD vector with two elements of type `usize`. -pub type usizex2 = Simd<usize, 2>; - -/// A SIMD vector with four elements of type `usize`. -pub type usizex4 = Simd<usize, 4>; - -/// A SIMD vector with eight elements of type `usize`. -pub type usizex8 = Simd<usize, 8>; - -/// A 32-bit SIMD vector with two elements of type `u16`. -pub type u16x2 = Simd<u16, 2>; - -/// A 64-bit SIMD vector with four elements of type `u16`. -pub type u16x4 = Simd<u16, 4>; - -/// A 128-bit SIMD vector with eight elements of type `u16`. -pub type u16x8 = Simd<u16, 8>; - -/// A 256-bit SIMD vector with 16 elements of type `u16`. -pub type u16x16 = Simd<u16, 16>; - -/// A 512-bit SIMD vector with 32 elements of type `u16`. -pub type u16x32 = Simd<u16, 32>; - -/// A 64-bit SIMD vector with two elements of type `u32`. -pub type u32x2 = Simd<u32, 2>; - -/// A 128-bit SIMD vector with four elements of type `u32`. -pub type u32x4 = Simd<u32, 4>; - -/// A 256-bit SIMD vector with eight elements of type `u32`. -pub type u32x8 = Simd<u32, 8>; - -/// A 512-bit SIMD vector with 16 elements of type `u32`. -pub type u32x16 = Simd<u32, 16>; - -/// A 128-bit SIMD vector with two elements of type `u64`. -pub type u64x2 = Simd<u64, 2>; - -/// A 256-bit SIMD vector with four elements of type `u64`. -pub type u64x4 = Simd<u64, 4>; - -/// A 512-bit SIMD vector with eight elements of type `u64`. -pub type u64x8 = Simd<u64, 8>; - -/// A 32-bit SIMD vector with four elements of type `u8`. -pub type u8x4 = Simd<u8, 4>; - -/// A 64-bit SIMD vector with eight elements of type `u8`. -pub type u8x8 = Simd<u8, 8>; - -/// A 128-bit SIMD vector with 16 elements of type `u8`. -pub type u8x16 = Simd<u8, 16>; - -/// A 256-bit SIMD vector with 32 elements of type `u8`. -pub type u8x32 = Simd<u8, 32>; - -/// A 512-bit SIMD vector with 64 elements of type `u8`. -pub type u8x64 = Simd<u8, 64>; diff --git a/library/portable-simd/crates/core_simd/tests/autoderef.rs b/library/portable-simd/crates/core_simd/tests/autoderef.rs index 9359da16ee5..3181826ef59 100644 --- a/library/portable-simd/crates/core_simd/tests/autoderef.rs +++ b/library/portable-simd/crates/core_simd/tests/autoderef.rs @@ -1,6 +1,6 @@ // Test that we handle all our "auto-deref" cases correctly. #![feature(portable_simd)] -use core_simd::f32x4; +use core_simd::simd::f32x4; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; diff --git a/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs b/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs index 795f9e27c44..faafa5fa51f 100644 --- a/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs +++ b/library/portable-simd/crates/core_simd/tests/mask_ops_impl/mask_macros.rs @@ -2,7 +2,7 @@ macro_rules! mask_tests { { $vector:ident, $lanes:literal } => { #[cfg(test)] mod $vector { - use core_simd::$vector as Vector; + use core_simd::simd::$vector as Vector; const LANES: usize = $lanes; #[cfg(target_arch = "wasm32")] diff --git a/library/portable-simd/crates/core_simd/tests/masks.rs b/library/portable-simd/crates/core_simd/tests/masks.rs index 673d0db93fe..9f8bad1c36c 100644 --- a/library/portable-simd/crates/core_simd/tests/masks.rs +++ b/library/portable-simd/crates/core_simd/tests/masks.rs @@ -13,11 +13,13 @@ macro_rules! test_mask_api { #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; + use core_simd::simd::Mask; + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn set_and_test() { let values = [true, false, false, true, false, false, true, false]; - let mut mask = core_simd::Mask::<$type, 8>::splat(false); + let mut mask = Mask::<$type, 8>::splat(false); for (lane, value) in values.iter().copied().enumerate() { mask.set(lane, value); } @@ -29,7 +31,7 @@ macro_rules! test_mask_api { #[test] #[should_panic] fn set_invalid_lane() { - let mut mask = core_simd::Mask::<$type, 8>::splat(false); + let mut mask = Mask::<$type, 8>::splat(false); mask.set(8, true); let _ = mask; } @@ -37,24 +39,24 @@ macro_rules! test_mask_api { #[test] #[should_panic] fn test_invalid_lane() { - let mask = core_simd::Mask::<$type, 8>::splat(false); + let mask = Mask::<$type, 8>::splat(false); let _ = mask.test(8); } #[test] fn any() { - assert!(!core_simd::Mask::<$type, 8>::splat(false).any()); - assert!(core_simd::Mask::<$type, 8>::splat(true).any()); - let mut v = core_simd::Mask::<$type, 8>::splat(false); + assert!(!Mask::<$type, 8>::splat(false).any()); + assert!(Mask::<$type, 8>::splat(true).any()); + let mut v = Mask::<$type, 8>::splat(false); v.set(2, true); assert!(v.any()); } #[test] fn all() { - assert!(!core_simd::Mask::<$type, 8>::splat(false).all()); - assert!(core_simd::Mask::<$type, 8>::splat(true).all()); - let mut v = core_simd::Mask::<$type, 8>::splat(false); + assert!(!Mask::<$type, 8>::splat(false).all()); + assert!(Mask::<$type, 8>::splat(true).all()); + let mut v = Mask::<$type, 8>::splat(false); v.set(2, true); assert!(!v.all()); } @@ -62,57 +64,57 @@ macro_rules! test_mask_api { #[test] fn roundtrip_int_conversion() { let values = [true, false, false, true, false, false, true, false]; - let mask = core_simd::Mask::<$type, 8>::from_array(values); + let mask = Mask::<$type, 8>::from_array(values); let int = mask.to_int(); assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]); - assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask); + assert_eq!(Mask::<$type, 8>::from_int(int), mask); } #[test] fn roundtrip_bitmask_conversion() { - use core_simd::ToBitMask; + use core_simd::simd::ToBitMask; let values = [ true, false, false, true, false, false, true, false, true, true, false, false, false, false, false, true, ]; - let mask = core_simd::Mask::<$type, 16>::from_array(values); + let mask = Mask::<$type, 16>::from_array(values); let bitmask = mask.to_bitmask(); assert_eq!(bitmask, 0b1000001101001001); - assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask); + assert_eq!(Mask::<$type, 16>::from_bitmask(bitmask), mask); } #[test] fn roundtrip_bitmask_conversion_short() { - use core_simd::ToBitMask; + use core_simd::simd::ToBitMask; let values = [ false, false, false, true, ]; - let mask = core_simd::Mask::<$type, 4>::from_array(values); + let mask = Mask::<$type, 4>::from_array(values); let bitmask = mask.to_bitmask(); assert_eq!(bitmask, 0b1000); - assert_eq!(core_simd::Mask::<$type, 4>::from_bitmask(bitmask), mask); + assert_eq!(Mask::<$type, 4>::from_bitmask(bitmask), mask); let values = [true, false]; - let mask = core_simd::Mask::<$type, 2>::from_array(values); + let mask = Mask::<$type, 2>::from_array(values); let bitmask = mask.to_bitmask(); assert_eq!(bitmask, 0b01); - assert_eq!(core_simd::Mask::<$type, 2>::from_bitmask(bitmask), mask); + assert_eq!(Mask::<$type, 2>::from_bitmask(bitmask), mask); } #[test] fn cast() { - fn cast_impl<T: core_simd::MaskElement>() + fn cast_impl<T: core_simd::simd::MaskElement>() where - core_simd::Mask<$type, 8>: Into<core_simd::Mask<T, 8>>, + Mask<$type, 8>: Into<Mask<T, 8>>, { let values = [true, false, false, true, false, false, true, false]; - let mask = core_simd::Mask::<$type, 8>::from_array(values); + let mask = Mask::<$type, 8>::from_array(values); let cast_mask = mask.cast::<T>(); assert_eq!(values, cast_mask.to_array()); - let into_mask: core_simd::Mask<T, 8> = mask.into(); + let into_mask: Mask<T, 8> = mask.into(); assert_eq!(values, into_mask.to_array()); } @@ -126,15 +128,15 @@ macro_rules! test_mask_api { #[cfg(feature = "generic_const_exprs")] #[test] fn roundtrip_bitmask_array_conversion() { - use core_simd::ToBitMaskArray; + use core_simd::simd::ToBitMaskArray; let values = [ true, false, false, true, false, false, true, false, true, true, false, false, false, false, false, true, ]; - let mask = core_simd::Mask::<$type, 16>::from_array(values); + let mask = Mask::<$type, 16>::from_array(values); let bitmask = mask.to_bitmask_array(); assert_eq!(bitmask, [0b01001001, 0b10000011]); - assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask_array(bitmask), mask); + assert_eq!(Mask::<$type, 16>::from_bitmask_array(bitmask), mask); } } } @@ -150,9 +152,10 @@ mod mask_api { #[test] fn convert() { + use core_simd::simd::Mask; let values = [true, false, false, true, false, false, true, false]; assert_eq!( - core_simd::Mask::<i8, 8>::from_array(values), - core_simd::Mask::<i32, 8>::from_array(values).into() + Mask::<i8, 8>::from_array(values), + Mask::<i32, 8>::from_array(values).into() ); } diff --git a/library/portable-simd/crates/core_simd/tests/ops_macros.rs b/library/portable-simd/crates/core_simd/tests/ops_macros.rs index f759394d075..3a02f3f01e1 100644 --- a/library/portable-simd/crates/core_simd/tests/ops_macros.rs +++ b/library/portable-simd/crates/core_simd/tests/ops_macros.rs @@ -7,7 +7,7 @@ macro_rules! impl_unary_op_test { test_helpers::test_lanes! { fn $fn<const LANES: usize>() { test_helpers::test_unary_elementwise( - &<core_simd::Simd<$scalar, LANES> as core::ops::$trait>::$fn, + &<core_simd::simd::Simd<$scalar, LANES> as core::ops::$trait>::$fn, &$scalar_fn, &|_| true, ); @@ -27,7 +27,7 @@ macro_rules! impl_binary_op_test { { $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => { mod $fn { use super::*; - use core_simd::Simd; + use core_simd::simd::Simd; test_helpers::test_lanes! { fn normal<const LANES: usize>() { @@ -64,7 +64,7 @@ macro_rules! impl_binary_checked_op_test { { $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => { mod $fn { use super::*; - use core_simd::Simd; + use core_simd::simd::Simd; test_helpers::test_lanes! { fn normal<const LANES: usize>() { @@ -173,7 +173,7 @@ macro_rules! impl_signed_tests { { $scalar:tt } => { mod $scalar { use core_simd::simd::SimdInt; - type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>; + type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>; type Scalar = $scalar; impl_common_integer_tests! { Vector, Scalar } @@ -314,7 +314,7 @@ macro_rules! impl_unsigned_tests { { $scalar:tt } => { mod $scalar { use core_simd::simd::SimdUint; - type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>; + type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>; type Scalar = $scalar; impl_common_integer_tests! { Vector, Scalar } @@ -348,8 +348,8 @@ macro_rules! impl_unsigned_tests { macro_rules! impl_float_tests { { $scalar:tt, $int_scalar:tt } => { mod $scalar { - use core_simd::SimdFloat; - type Vector<const LANES: usize> = core_simd::Simd<Scalar, LANES>; + use core_simd::simd::SimdFloat; + type Vector<const LANES: usize> = core_simd::simd::Simd<Scalar, LANES>; type Scalar = $scalar; impl_unary_op_test!(Scalar, Neg::neg); diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs new file mode 100644 index 00000000000..0ae8f83b8b9 --- /dev/null +++ b/library/portable-simd/crates/core_simd/tests/pointers.rs @@ -0,0 +1,111 @@ +#![feature(portable_simd, strict_provenance)] + +use core_simd::simd::{Simd, SimdConstPtr, SimdMutPtr}; + +macro_rules! common_tests { + { $constness:ident } => { + test_helpers::test_lanes! { + fn is_null<const LANES: usize>() { + test_helpers::test_unary_mask_elementwise( + &Simd::<*$constness u32, LANES>::is_null, + &<*$constness u32>::is_null, + &|_| true, + ); + } + + fn addr<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*$constness u32, LANES>::addr, + &<*$constness u32>::addr, + &|_| true, + ); + } + + fn with_addr<const LANES: usize>() { + test_helpers::test_binary_elementwise( + &Simd::<*$constness u32, LANES>::with_addr, + &<*$constness u32>::with_addr, + &|_, _| true, + ); + } + + fn expose_addr<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*$constness u32, LANES>::expose_addr, + &<*$constness u32>::expose_addr, + &|_| true, + ); + } + + fn wrapping_offset<const LANES: usize>() { + test_helpers::test_binary_elementwise( + &Simd::<*$constness u32, LANES>::wrapping_offset, + &<*$constness u32>::wrapping_offset, + &|_, _| true, + ); + } + + fn wrapping_add<const LANES: usize>() { + test_helpers::test_binary_elementwise( + &Simd::<*$constness u32, LANES>::wrapping_add, + &<*$constness u32>::wrapping_add, + &|_, _| true, + ); + } + + fn wrapping_sub<const LANES: usize>() { + test_helpers::test_binary_elementwise( + &Simd::<*$constness u32, LANES>::wrapping_sub, + &<*$constness u32>::wrapping_sub, + &|_, _| true, + ); + } + } + } +} + +mod const_ptr { + use super::*; + common_tests! { const } + + test_helpers::test_lanes! { + fn cast_mut<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*const u32, LANES>::cast_mut, + &<*const u32>::cast_mut, + &|_| true, + ); + } + + fn from_exposed_addr<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*const u32, LANES>::from_exposed_addr, + &core::ptr::from_exposed_addr::<u32>, + &|_| true, + ); + } + } +} + +mod mut_ptr { + use super::*; + common_tests! { mut } + + test_helpers::test_lanes! { + fn cast_const<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*mut u32, LANES>::cast_const, + &<*mut u32>::cast_const, + &|_| true, + ); + } + + fn from_exposed_addr<const LANES: usize>() { + test_helpers::test_unary_elementwise( + &Simd::<*mut u32, LANES>::from_exposed_addr, + &core::ptr::from_exposed_addr_mut::<u32>, + &|_| true, + ); + } + } +} diff --git a/library/portable-simd/crates/core_simd/tests/round.rs b/library/portable-simd/crates/core_simd/tests/round.rs index 484fd5bf47d..8b9638ad466 100644 --- a/library/portable-simd/crates/core_simd/tests/round.rs +++ b/library/portable-simd/crates/core_simd/tests/round.rs @@ -5,7 +5,7 @@ macro_rules! float_rounding_test { mod $scalar { use std_float::StdFloat; - type Vector<const LANES: usize> = core_simd::Simd<$scalar, LANES>; + type Vector<const LANES: usize> = core_simd::simd::Simd<$scalar, LANES>; type Scalar = $scalar; type IntScalar = $int_scalar; diff --git a/library/portable-simd/crates/core_simd/tests/swizzle.rs b/library/portable-simd/crates/core_simd/tests/swizzle.rs index 51c63611aba..8cd7c33e823 100644 --- a/library/portable-simd/crates/core_simd/tests/swizzle.rs +++ b/library/portable-simd/crates/core_simd/tests/swizzle.rs @@ -1,5 +1,5 @@ #![feature(portable_simd)] -use core_simd::{Simd, Swizzle}; +use core_simd::simd::{Simd, Swizzle}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -60,3 +60,17 @@ fn interleave() { assert_eq!(even, a); assert_eq!(odd, b); } + +// portable-simd#298 +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn interleave_one() { + let a = Simd::from_array([0]); + let b = Simd::from_array([1]); + let (lo, hi) = a.interleave(b); + assert_eq!(lo.to_array(), [0]); + assert_eq!(hi.to_array(), [1]); + let (even, odd) = lo.deinterleave(hi); + assert_eq!(even, a); + assert_eq!(odd, b); +} diff --git a/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs new file mode 100644 index 00000000000..646cd5f3383 --- /dev/null +++ b/library/portable-simd/crates/core_simd/tests/swizzle_dyn.rs @@ -0,0 +1,74 @@ +#![feature(portable_simd)] +use core::{fmt, ops::RangeInclusive}; +use proptest; +use test_helpers::{self, biteq, make_runner, prop_assert_biteq}; + +fn swizzle_dyn_scalar_ver<const N: usize>(values: [u8; N], idxs: [u8; N]) -> [u8; N] { + let mut array = [0; N]; + for (i, k) in idxs.into_iter().enumerate() { + if (k as usize) < N { + array[i] = values[k as usize]; + }; + } + array +} + +test_helpers::test_lanes! { + fn swizzle_dyn<const N: usize>() { + match_simd_with_fallback( + &core_simd::simd::Simd::<u8, N>::swizzle_dyn, + &swizzle_dyn_scalar_ver, + &|_, _| true, + ); + } +} + +fn match_simd_with_fallback<Scalar, ScalarResult, Vector, VectorResult, const N: usize>( + fv: &dyn Fn(Vector, Vector) -> VectorResult, + fs: &dyn Fn([Scalar; N], [Scalar; N]) -> [ScalarResult; N], + check: &dyn Fn([Scalar; N], [Scalar; N]) -> bool, +) where + Scalar: Copy + fmt::Debug + SwizzleStrategy, + ScalarResult: Copy + biteq::BitEq + fmt::Debug + SwizzleStrategy, + Vector: Into<[Scalar; N]> + From<[Scalar; N]> + Copy, + VectorResult: Into<[ScalarResult; N]> + From<[ScalarResult; N]> + Copy, +{ + test_swizzles_2(&|x: [Scalar; N], y: [Scalar; N]| { + proptest::prop_assume!(check(x, y)); + let result_v: [ScalarResult; N] = fv(x.into(), y.into()).into(); + let result_s: [ScalarResult; N] = fs(x, y); + crate::prop_assert_biteq!(result_v, result_s); + Ok(()) + }); +} + +fn test_swizzles_2<A: fmt::Debug + SwizzleStrategy, B: fmt::Debug + SwizzleStrategy>( + f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult, +) { + let mut runner = make_runner(); + runner + .run( + &(A::swizzled_strategy(), B::swizzled_strategy()), + |(a, b)| f(a, b), + ) + .unwrap(); +} + +pub trait SwizzleStrategy { + type Strategy: proptest::strategy::Strategy<Value = Self>; + fn swizzled_strategy() -> Self::Strategy; +} + +impl SwizzleStrategy for u8 { + type Strategy = RangeInclusive<u8>; + fn swizzled_strategy() -> Self::Strategy { + 0..=64 + } +} + +impl<T: fmt::Debug + SwizzleStrategy, const N: usize> SwizzleStrategy for [T; N] { + type Strategy = test_helpers::array::UniformArrayStrategy<T::Strategy, Self>; + fn swizzled_strategy() -> Self::Strategy { + Self::Strategy::new(T::swizzled_strategy()) + } +} diff --git a/library/portable-simd/crates/core_simd/tests/to_bytes.rs b/library/portable-simd/crates/core_simd/tests/to_bytes.rs index debb4335e2c..be0ee4349c5 100644 --- a/library/portable-simd/crates/core_simd/tests/to_bytes.rs +++ b/library/portable-simd/crates/core_simd/tests/to_bytes.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] #![cfg(feature = "generic_const_exprs")] -use core_simd::Simd; +use core_simd::simd::Simd; #[test] fn byte_convert() { diff --git a/library/portable-simd/crates/core_simd/tests/try_from_slice.rs b/library/portable-simd/crates/core_simd/tests/try_from_slice.rs new file mode 100644 index 00000000000..859e3b94f2c --- /dev/null +++ b/library/portable-simd/crates/core_simd/tests/try_from_slice.rs @@ -0,0 +1,25 @@ +#![feature(portable_simd)] + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_test::*; + +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test_configure!(run_in_browser); + +use core_simd::simd::i32x4; + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn try_from_slice() { + // Equal length + assert_eq!( + i32x4::try_from([1, 2, 3, 4].as_slice()).unwrap(), + i32x4::from_array([1, 2, 3, 4]) + ); + + // Slice length > vector length + assert!(i32x4::try_from([1, 2, 3, 4, 5].as_slice()).is_err()); + + // Slice length < vector length + assert!(i32x4::try_from([1, 2, 3].as_slice()).is_err()); +} diff --git a/library/portable-simd/crates/test_helpers/Cargo.toml b/library/portable-simd/crates/test_helpers/Cargo.toml index a04b0961d7f..1d2bc8b519a 100644 --- a/library/portable-simd/crates/test_helpers/Cargo.toml +++ b/library/portable-simd/crates/test_helpers/Cargo.toml @@ -8,3 +8,6 @@ publish = false version = "0.10" default-features = false features = ["alloc"] + +[features] +all_lane_counts = [] diff --git a/library/portable-simd/crates/test_helpers/src/array.rs b/library/portable-simd/crates/test_helpers/src/array.rs index 5ffc9226976..984a427320d 100644 --- a/library/portable-simd/crates/test_helpers/src/array.rs +++ b/library/portable-simd/crates/test_helpers/src/array.rs @@ -41,6 +41,7 @@ where fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> { let tree: [S::Tree; LANES] = unsafe { + #[allow(clippy::uninit_assumed_init)] let mut tree: [MaybeUninit<S::Tree>; LANES] = MaybeUninit::uninit().assume_init(); for t in tree.iter_mut() { *t = MaybeUninit::new(self.strategy.new_tree(runner)?) @@ -60,6 +61,7 @@ impl<T: ValueTree, const LANES: usize> ValueTree for ArrayValueTree<[T; LANES]> fn current(&self) -> Self::Value { unsafe { + #[allow(clippy::uninit_assumed_init)] let mut value: [MaybeUninit<T::Value>; LANES] = MaybeUninit::uninit().assume_init(); for (tree_elem, value_elem) in self.tree.iter().zip(value.iter_mut()) { *value_elem = MaybeUninit::new(tree_elem.current()); diff --git a/library/portable-simd/crates/test_helpers/src/biteq.rs b/library/portable-simd/crates/test_helpers/src/biteq.rs index 00350e22418..7d91260d838 100644 --- a/library/portable-simd/crates/test_helpers/src/biteq.rs +++ b/library/portable-simd/crates/test_helpers/src/biteq.rs @@ -55,6 +55,26 @@ macro_rules! impl_float_biteq { impl_float_biteq! { f32, f64 } +impl<T> BitEq for *const T { + fn biteq(&self, other: &Self) -> bool { + self == other + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl<T> BitEq for *mut T { + fn biteq(&self, other: &Self) -> bool { + self == other + } + + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:?}", self) + } +} + impl<T: BitEq, const N: usize> BitEq for [T; N] { fn biteq(&self, other: &Self) -> bool { self.iter() diff --git a/library/portable-simd/crates/test_helpers/src/lib.rs b/library/portable-simd/crates/test_helpers/src/lib.rs index 141bee18a9a..b26cdc311a2 100644 --- a/library/portable-simd/crates/test_helpers/src/lib.rs +++ b/library/portable-simd/crates/test_helpers/src/lib.rs @@ -38,6 +38,28 @@ impl_num! { usize } impl_num! { f32 } impl_num! { f64 } +impl<T> DefaultStrategy for *const T { + type Strategy = proptest::strategy::Map<proptest::num::isize::Any, fn(isize) -> *const T>; + fn default_strategy() -> Self::Strategy { + fn map<T>(x: isize) -> *const T { + x as _ + } + use proptest::strategy::Strategy; + proptest::num::isize::ANY.prop_map(map) + } +} + +impl<T> DefaultStrategy for *mut T { + type Strategy = proptest::strategy::Map<proptest::num::isize::Any, fn(isize) -> *mut T>; + fn default_strategy() -> Self::Strategy { + fn map<T>(x: isize) -> *mut T { + x as _ + } + use proptest::strategy::Strategy; + proptest::num::isize::ANY.prop_map(map) + } +} + #[cfg(not(target_arch = "wasm32"))] impl DefaultStrategy for u128 { type Strategy = proptest::num::u128::Any; @@ -135,21 +157,21 @@ pub fn test_unary_elementwise<Scalar, ScalarResult, Vector, VectorResult, const fs: &dyn Fn(Scalar) -> ScalarResult, check: &dyn Fn([Scalar; LANES]) -> bool, ) where - Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy, - ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Scalar: Copy + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + biteq::BitEq + core::fmt::Debug + DefaultStrategy, Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, { test_1(&|x: [Scalar; LANES]| { proptest::prop_assume!(check(x)); let result_1: [ScalarResult; LANES] = fv(x.into()).into(); - let result_2: [ScalarResult; LANES] = { - let mut result = [ScalarResult::default(); LANES]; - for (i, o) in x.iter().zip(result.iter_mut()) { - *o = fs(*i); - } - result - }; + let result_2: [ScalarResult; LANES] = x + .iter() + .copied() + .map(fs) + .collect::<Vec<_>>() + .try_into() + .unwrap(); crate::prop_assert_biteq!(result_1, result_2); Ok(()) }); @@ -162,7 +184,7 @@ pub fn test_unary_mask_elementwise<Scalar, Vector, Mask, const LANES: usize>( fs: &dyn Fn(Scalar) -> bool, check: &dyn Fn([Scalar; LANES]) -> bool, ) where - Scalar: Copy + Default + core::fmt::Debug + DefaultStrategy, + Scalar: Copy + core::fmt::Debug + DefaultStrategy, Vector: Into<[Scalar; LANES]> + From<[Scalar; LANES]> + Copy, Mask: Into<[bool; LANES]> + From<[bool; LANES]> + Copy, { @@ -196,9 +218,9 @@ pub fn test_binary_elementwise< fs: &dyn Fn(Scalar1, Scalar2) -> ScalarResult, check: &dyn Fn([Scalar1; LANES], [Scalar2; LANES]) -> bool, ) where - Scalar1: Copy + Default + core::fmt::Debug + DefaultStrategy, - Scalar2: Copy + Default + core::fmt::Debug + DefaultStrategy, - ScalarResult: Copy + Default + biteq::BitEq + core::fmt::Debug + DefaultStrategy, + Scalar1: Copy + core::fmt::Debug + DefaultStrategy, + Scalar2: Copy + core::fmt::Debug + DefaultStrategy, + ScalarResult: Copy + biteq::BitEq + core::fmt::Debug + DefaultStrategy, Vector1: Into<[Scalar1; LANES]> + From<[Scalar1; LANES]> + Copy, Vector2: Into<[Scalar2; LANES]> + From<[Scalar2; LANES]> + Copy, VectorResult: Into<[ScalarResult; LANES]> + From<[ScalarResult; LANES]> + Copy, @@ -206,13 +228,14 @@ pub fn test_binary_elementwise< test_2(&|x: [Scalar1; LANES], y: [Scalar2; LANES]| { proptest::prop_assume!(check(x, y)); let result_1: [ScalarResult; LANES] = fv(x.into(), y.into()).into(); - let result_2: [ScalarResult; LANES] = { - let mut result = [ScalarResult::default(); LANES]; - for ((i1, i2), o) in x.iter().zip(y.iter()).zip(result.iter_mut()) { - *o = fs(*i1, *i2); - } - result - }; + let result_2: [ScalarResult; LANES] = x + .iter() + .copied() + .zip(y.iter().copied()) + .map(|(x, y)| fs(x, y)) + .collect::<Vec<_>>() + .try_into() + .unwrap(); crate::prop_assert_biteq!(result_1, result_2); Ok(()) }); @@ -333,6 +356,39 @@ pub fn test_ternary_elementwise< ); } +#[doc(hidden)] +#[macro_export] +macro_rules! test_lanes_helper { + ($($(#[$meta:meta])* $fn_name:ident $lanes:literal;)+) => { + $( + #[test] + $(#[$meta])* + fn $fn_name() { + implementation::<$lanes>(); + } + )+ + }; + ( + $(#[$meta:meta])+; + $($(#[$meta_before:meta])+ $fn_name_before:ident $lanes_before:literal;)* + $fn_name:ident $lanes:literal; + $($fn_name_rest:ident $lanes_rest:literal;)* + ) => { + $crate::test_lanes_helper!( + $(#[$meta])+; + $($(#[$meta_before])+ $fn_name_before $lanes_before;)* + $(#[$meta])+ $fn_name $lanes; + $($fn_name_rest $lanes_rest;)* + ); + }; + ( + $(#[$meta_ignored:meta])+; + $($(#[$meta:meta])+ $fn_name:ident $lanes:literal;)+ + ) => { + $crate::test_lanes_helper!($($(#[$meta])+ $fn_name $lanes;)+); + }; +} + /// Expand a const-generic test into separate tests for each possible lane count. #[macro_export] macro_rules! test_lanes { @@ -345,57 +401,96 @@ macro_rules! test_lanes { fn implementation<const $lanes: usize>() where - core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount, + core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount, $body #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn lanes_1() { - implementation::<1>(); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn lanes_2() { - implementation::<2>(); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - fn lanes_4() { - implementation::<4>(); - } + $crate::test_lanes_helper!( + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + lanes_1 1; + lanes_2 2; + lanes_4 4; + ); - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - fn lanes_8() { - implementation::<8>(); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + $crate::test_lanes_helper!( + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + lanes_8 8; + lanes_16 16; + lanes_32 32; + lanes_64 64; + ); + + #[cfg(feature = "all_lane_counts")] + $crate::test_lanes_helper!( + // test some odd and even non-power-of-2 lengths on miri + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + lanes_3 3; + lanes_5 5; + lanes_6 6; + ); + + #[cfg(feature = "all_lane_counts")] #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - fn lanes_16() { - implementation::<16>(); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - fn lanes_32() { - implementation::<32>(); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] - #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow - fn lanes_64() { - implementation::<64>(); - } + $crate::test_lanes_helper!( + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]; + lanes_7 7; + lanes_9 9; + lanes_10 10; + lanes_11 11; + lanes_12 12; + lanes_13 13; + lanes_14 14; + lanes_15 15; + lanes_17 17; + lanes_18 18; + lanes_19 19; + lanes_20 20; + lanes_21 21; + lanes_22 22; + lanes_23 23; + lanes_24 24; + lanes_25 25; + lanes_26 26; + lanes_27 27; + lanes_28 28; + lanes_29 29; + lanes_30 30; + lanes_31 31; + lanes_33 33; + lanes_34 34; + lanes_35 35; + lanes_36 36; + lanes_37 37; + lanes_38 38; + lanes_39 39; + lanes_40 40; + lanes_41 41; + lanes_42 42; + lanes_43 43; + lanes_44 44; + lanes_45 45; + lanes_46 46; + lanes_47 47; + lanes_48 48; + lanes_49 49; + lanes_50 50; + lanes_51 51; + lanes_52 52; + lanes_53 53; + lanes_54 54; + lanes_55 55; + lanes_56 56; + lanes_57 57; + lanes_58 58; + lanes_59 59; + lanes_60 60; + lanes_61 61; + lanes_62 62; + lanes_63 63; + ); } )* } @@ -413,50 +508,93 @@ macro_rules! test_lanes_panic { fn implementation<const $lanes: usize>() where - core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount, + core_simd::simd::LaneCount<$lanes>: core_simd::simd::SupportedLaneCount, $body - #[test] - #[should_panic] - fn lanes_1() { - implementation::<1>(); - } - - #[test] - #[should_panic] - fn lanes_2() { - implementation::<2>(); - } - - #[test] - #[should_panic] - fn lanes_4() { - implementation::<4>(); - } - - #[test] - #[should_panic] - fn lanes_8() { - implementation::<8>(); - } + $crate::test_lanes_helper!( + #[should_panic]; + lanes_1 1; + lanes_2 2; + lanes_4 4; + ); - #[test] - #[should_panic] - fn lanes_16() { - implementation::<16>(); - } - - #[test] - #[should_panic] - fn lanes_32() { - implementation::<32>(); - } - - #[test] - #[should_panic] - fn lanes_64() { - implementation::<64>(); - } + #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow + $crate::test_lanes_helper!( + #[should_panic]; + lanes_8 8; + lanes_16 16; + lanes_32 32; + lanes_64 64; + ); + + #[cfg(feature = "all_lane_counts")] + $crate::test_lanes_helper!( + // test some odd and even non-power-of-2 lengths on miri + #[should_panic]; + lanes_3 3; + lanes_5 5; + lanes_6 6; + ); + + #[cfg(feature = "all_lane_counts")] + #[cfg(not(miri))] // Miri intrinsic implementations are uniform and larger tests are sloooow + $crate::test_lanes_helper!( + #[should_panic]; + lanes_7 7; + lanes_9 9; + lanes_10 10; + lanes_11 11; + lanes_12 12; + lanes_13 13; + lanes_14 14; + lanes_15 15; + lanes_17 17; + lanes_18 18; + lanes_19 19; + lanes_20 20; + lanes_21 21; + lanes_22 22; + lanes_23 23; + lanes_24 24; + lanes_25 25; + lanes_26 26; + lanes_27 27; + lanes_28 28; + lanes_29 29; + lanes_30 30; + lanes_31 31; + lanes_33 33; + lanes_34 34; + lanes_35 35; + lanes_36 36; + lanes_37 37; + lanes_38 38; + lanes_39 39; + lanes_40 40; + lanes_41 41; + lanes_42 42; + lanes_43 43; + lanes_44 44; + lanes_45 45; + lanes_46 46; + lanes_47 47; + lanes_48 48; + lanes_49 49; + lanes_50 50; + lanes_51 51; + lanes_52 52; + lanes_53 53; + lanes_54 54; + lanes_55 55; + lanes_56 56; + lanes_57 57; + lanes_58 58; + lanes_59 59; + lanes_60 60; + lanes_61 61; + lanes_62 62; + lanes_63 63; + ); } )* } 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 9b77cd8321b..cbf8209a5ad 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -9,7 +9,7 @@ use crate::io; use crate::marker::PhantomData; use crate::mem::forget; use crate::ptr; -use crate::sys::c; +use crate::sys; use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -190,14 +190,14 @@ impl BorrowedHandle<'_> { /// object as the existing `BorrowedHandle` instance. #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedHandle> { - self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS) + self.duplicate(0, false, sys::c::DUPLICATE_SAME_ACCESS) } pub(crate) fn duplicate( &self, - access: c::DWORD, + access: u32, inherit: bool, - options: c::DWORD, + options: u32, ) -> io::Result<OwnedHandle> { let handle = self.as_raw_handle(); @@ -211,14 +211,14 @@ impl BorrowedHandle<'_> { let mut ret = ptr::null_mut(); cvt(unsafe { - let cur_proc = c::GetCurrentProcess(); - c::DuplicateHandle( + let cur_proc = sys::c::GetCurrentProcess(); + sys::c::DuplicateHandle( cur_proc, handle, cur_proc, &mut ret, access, - inherit as c::BOOL, + inherit as sys::c::BOOL, options, ) })?; @@ -233,7 +233,7 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle { #[inline] fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> { let owned_handle = handle_or_invalid.0; - if owned_handle.handle == c::INVALID_HANDLE_VALUE { + if owned_handle.handle == sys::c::INVALID_HANDLE_VALUE { // Don't call `CloseHandle`; it'd be harmless, except that it could // overwrite the `GetLastError` error. forget(owned_handle); @@ -365,7 +365,7 @@ impl Drop for OwnedHandle { #[inline] fn drop(&mut self) { unsafe { - let _ = c::CloseHandle(self.handle); + let _ = sys::c::CloseHandle(self.handle); } } } @@ -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/raw.rs b/library/std/src/os/windows/io/raw.rs index 49e4f304f5d..1759e2e7f3f 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -11,7 +11,6 @@ use crate::os::windows::io::{OwnedHandle, OwnedSocket}; use crate::os::windows::raw; use crate::ptr; use crate::sys; -use crate::sys::c; use crate::sys_common::{self, AsInner, FromInner, IntoInner}; /// Raw HANDLEs. @@ -104,42 +103,42 @@ impl AsRawHandle for fs::File { #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stdin { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle }) } } #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stdout { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle }) } } #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stderr { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle }) } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StdinLock<'a> { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle }) } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StdoutLock<'a> { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle }) } } #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StderrLock<'a> { fn as_raw_handle(&self) -> RawHandle { - stdio_handle(unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle }) + stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle }) } } @@ -152,14 +151,14 @@ fn stdio_handle(raw: RawHandle) -> RawHandle { // console. In that case, return null to the user, which is consistent // with what they'd get in the parent, and which avoids the problem that // `INVALID_HANDLE_VALUE` aliases the current process handle. - if raw == c::INVALID_HANDLE_VALUE { ptr::null_mut() } else { raw } + if raw == sys::c::INVALID_HANDLE_VALUE { ptr::null_mut() } else { raw } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawHandle for fs::File { #[inline] unsafe fn from_raw_handle(handle: RawHandle) -> fs::File { - let handle = handle as c::HANDLE; + let handle = handle as sys::c::HANDLE; fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner( OwnedHandle::from_raw_handle(handle), ))) diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index b6bd0f9e12b..0c90d55c024 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -9,7 +9,6 @@ use crate::marker::PhantomData; use crate::mem; use crate::mem::forget; use crate::sys; -use crate::sys::c; #[cfg(not(target_vendor = "uwp"))] use crate::sys::cvt; @@ -76,7 +75,7 @@ impl BorrowedSocket<'_> { #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(socket: RawSocket) -> Self { - assert!(socket != c::INVALID_SOCKET as RawSocket); + assert!(socket != sys::c::INVALID_SOCKET as RawSocket); Self { socket, _phantom: PhantomData } } } @@ -94,7 +93,11 @@ impl OwnedSocket { #[cfg(not(target_vendor = "uwp"))] pub(crate) fn set_no_inherit(&self) -> io::Result<()> { cvt(unsafe { - c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0) + sys::c::SetHandleInformation( + self.as_raw_socket() as sys::c::HANDLE, + sys::c::HANDLE_FLAG_INHERIT, + 0, + ) }) .map(drop) } @@ -110,43 +113,47 @@ impl BorrowedSocket<'_> { /// object as the existing `BorrowedSocket` instance. #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> { - let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() }; + let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOW>() }; let result = unsafe { - c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info) + sys::c::WSADuplicateSocketW( + self.as_raw_socket(), + sys::c::GetCurrentProcessId(), + &mut info, + ) }; sys::net::cvt(result)?; let socket = unsafe { - c::WSASocketW( + sys::c::WSASocketW( info.iAddressFamily, info.iSocketType, info.iProtocol, &mut info, 0, - c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT, + sys::c::WSA_FLAG_OVERLAPPED | sys::c::WSA_FLAG_NO_HANDLE_INHERIT, ) }; - if socket != c::INVALID_SOCKET { + if socket != sys::c::INVALID_SOCKET { unsafe { Ok(OwnedSocket::from_raw_socket(socket)) } } else { - let error = unsafe { c::WSAGetLastError() }; + let error = unsafe { sys::c::WSAGetLastError() }; - if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL { + if error != sys::c::WSAEPROTOTYPE && error != sys::c::WSAEINVAL { return Err(io::Error::from_raw_os_error(error)); } let socket = unsafe { - c::WSASocketW( + sys::c::WSASocketW( info.iAddressFamily, info.iSocketType, info.iProtocol, &mut info, 0, - c::WSA_FLAG_OVERLAPPED, + sys::c::WSA_FLAG_OVERLAPPED, ) }; - if socket == c::INVALID_SOCKET { + if socket == sys::c::INVALID_SOCKET { return Err(last_error()); } @@ -161,7 +168,7 @@ impl BorrowedSocket<'_> { /// Returns the last error from the Windows socket interface. fn last_error() -> io::Error { - io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() }) + io::Error::from_raw_os_error(unsafe { sys::c::WSAGetLastError() }) } #[stable(feature = "io_safety", since = "1.63.0")] @@ -194,7 +201,7 @@ impl IntoRawSocket for OwnedSocket { impl FromRawSocket for OwnedSocket { #[inline] unsafe fn from_raw_socket(socket: RawSocket) -> Self { - debug_assert_ne!(socket, c::INVALID_SOCKET as RawSocket); + debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket); Self { socket } } } @@ -204,7 +211,7 @@ impl Drop for OwnedSocket { #[inline] fn drop(&mut self) { unsafe { - let _ = c::closesocket(self.socket); + let _ = sys::c::closesocket(self.socket); } } } @@ -247,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/panicking.rs b/library/std/src/panicking.rs index a46a29cbad6..6d59266b6f8 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -541,7 +541,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { // Lazily, the first time this gets called, run the actual string formatting. self.string.get_or_insert_with(|| { let mut s = String::new(); - drop(s.write_fmt(*inner)); + let _err = s.write_fmt(*inner); s }) } diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs index 87585a8fcd0..79624703a4c 100644 --- a/library/std/src/personality/dwarf/eh.rs +++ b/library/std/src/personality/dwarf/eh.rs @@ -47,6 +47,7 @@ pub enum EHAction { None, Cleanup(usize), Catch(usize), + Filter(usize), Terminate, } @@ -142,9 +143,11 @@ unsafe fn interpret_cs_action( let ttype_index = action_reader.read_sleb128(); if ttype_index == 0 { EHAction::Cleanup(lpad) - } else { + } else if ttype_index > 0 { // Stop unwinding Rust panics at catch_unwind. EHAction::Catch(lpad) + } else { + EHAction::Filter(lpad) } } } diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs index 0421b47be02..82edb11cbd1 100644 --- a/library/std/src/personality/gcc.rs +++ b/library/std/src/personality/gcc.rs @@ -135,7 +135,7 @@ cfg_if::cfg_if! { EHAction::None | EHAction::Cleanup(_) => { return continue_unwind(exception_object, context); } - EHAction::Catch(_) => { + EHAction::Catch(_) | EHAction::Filter(_) => { // EHABI requires the personality routine to update the // SP value in the barrier cache of the exception object. (*exception_object).private[5] = @@ -147,7 +147,8 @@ cfg_if::cfg_if! { } else { match eh_action { EHAction::None => return continue_unwind(exception_object, context), - EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => { + EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context), + EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => { uw::_Unwind_SetGR( context, UNWIND_DATA_REG.0, @@ -201,13 +202,15 @@ cfg_if::cfg_if! { if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 { match eh_action { EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND, - EHAction::Catch(_) => uw::_URC_HANDLER_FOUND, + EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND, EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR, } } else { match eh_action { EHAction::None => uw::_URC_CONTINUE_UNWIND, - EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => { + // Forced unwinding hits a terminate action. + EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND, + EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => { uw::_Unwind_SetGR( context, UNWIND_DATA_REG.0, 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/sys/mod.rs b/library/std/src/sys/mod.rs index e767b2866cb..c72be13804d 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -52,31 +52,6 @@ cfg_if::cfg_if! { } } -// Import essential modules from platforms used in `std::os` when documenting. -// -// Note that on some platforms those modules don't compile -// (missing things in `libc` which is empty), so they are not included in `std::os` and can be -// omitted here as well. - -#[cfg(doc)] -#[cfg(not(any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") -)))] -cfg_if::cfg_if! { - if #[cfg(not(windows))] { - // On non-Windows platforms (aka linux/osx/etc) pull in a "minimal" - // amount of windows goop which ends up compiling - - #[macro_use] - #[path = "windows/compat.rs"] - pub mod compat; - - #[path = "windows/c.rs"] - pub mod c; - } -} - cfg_if::cfg_if! { // Fuchsia components default to full backtrace. if #[cfg(target_os = "fuchsia")] { diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs index 61bb11d9a6f..5e1d859ee99 100644 --- a/library/std/src/sys/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/sgx/waitqueue/mod.rs @@ -202,12 +202,18 @@ impl WaitQueue { pub fn notify_one<T>( mut guard: SpinMutexGuard<'_, WaitVariable<T>>, ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> { + // SAFETY: lifetime of the pop() return value is limited to the map + // closure (The closure return value is 'static). The underlying + // stack frame won't be freed until after the WaitGuard created below + // is dropped. unsafe { - if let Some(entry) = guard.queue.inner.pop() { + let tcs = guard.queue.inner.pop().map(|entry| -> Tcs { let mut entry_guard = entry.lock(); - let tcs = entry_guard.tcs; entry_guard.wake = true; - drop(entry); + entry_guard.tcs + }); + + if let Some(tcs) = tcs { Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::Single(tcs) }) } else { Err(guard) @@ -223,6 +229,9 @@ impl WaitQueue { pub fn notify_all<T>( mut guard: SpinMutexGuard<'_, WaitVariable<T>>, ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> { + // SAFETY: lifetime of the pop() return values are limited to the + // while loop body. The underlying stack frames won't be freed until + // after the WaitGuard created below is dropped. unsafe { let mut count = 0; while let Some(entry) = guard.queue.inner.pop() { @@ -230,6 +239,7 @@ impl WaitQueue { let mut entry_guard = entry.lock(); entry_guard.wake = true; } + if let Some(count) = NonZeroUsize::new(count) { Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } }) } else { diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 22d2ae39713..09db5b11dbf 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1210,7 +1210,7 @@ impl File { // Redox doesn't appear to support `UTIME_OMIT`. // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore // the same as for Redox. - drop(times); + let _ = times; Err(io::const_io_error!( io::ErrorKind::Unsupported, "setting file times not supported", diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 1f4092ad738..2bc40c4748a 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -6,33 +6,18 @@ use crate::ffi::CStr; use crate::mem; -use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort}; -use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; +pub use crate::os::raw::c_int; +use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void}; +use crate::os::windows::io::{AsRawHandle, BorrowedHandle}; use crate::ptr; use core::ffi::NonZero_c_ulong; -use libc::{c_void, size_t, wchar_t}; - -pub use crate::os::raw::c_int; - -#[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this -mod errors; -pub use errors::*; +#[path = "c/windows_sys.rs"] // c.rs is included from two places so we need to specify this +mod windows_sys; +pub use windows_sys::*; -pub use self::EXCEPTION_DISPOSITION::*; -pub use self::FILE_INFO_BY_HANDLE_CLASS::*; - -pub type DWORD_PTR = ULONG_PTR; pub type DWORD = c_ulong; pub type NonZeroDWORD = NonZero_c_ulong; -pub type HANDLE = LPVOID; -pub type HINSTANCE = HANDLE; -pub type HMODULE = HINSTANCE; -pub type HRESULT = LONG; -pub type BOOL = c_int; -pub type BYTE = u8; -pub type BOOLEAN = BYTE; -pub type GROUP = c_uint; pub type LARGE_INTEGER = c_longlong; pub type LONG = c_long; pub type UINT = c_uint; @@ -41,218 +26,40 @@ pub type USHORT = c_ushort; pub type SIZE_T = usize; pub type WORD = u16; pub type CHAR = c_char; -pub type CCHAR = c_char; -pub type ULONG_PTR = usize; pub type ULONG = c_ulong; -pub type NTSTATUS = LONG; pub type ACCESS_MASK = DWORD; -pub type LPBOOL = *mut BOOL; -pub type LPBYTE = *mut BYTE; -pub type LPCCH = *const CHAR; -pub type LPCSTR = *const CHAR; -pub type LPCWCH = *const WCHAR; -pub type LPCWSTR = *const WCHAR; pub type LPCVOID = *const c_void; -pub type LPDWORD = *mut DWORD; pub type LPHANDLE = *mut HANDLE; pub type LPOVERLAPPED = *mut OVERLAPPED; -pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION; pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES; -pub type LPSTARTUPINFO = *mut STARTUPINFO; -pub type LPSTR = *mut CHAR; pub type LPVOID = *mut c_void; pub type LPWCH = *mut WCHAR; -pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; -pub type LPWSADATA = *mut WSADATA; -pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; pub type LPWSTR = *mut WCHAR; -pub type LPFILETIME = *mut FILETIME; -pub type LPSYSTEM_INFO = *mut SYSTEM_INFO; -pub type LPWSABUF = *mut WSABUF; -pub type LPWSAOVERLAPPED = *mut c_void; -pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void; -pub type BCRYPT_ALG_HANDLE = LPVOID; -pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE; pub type PLARGE_INTEGER = *mut c_longlong; pub type PSRWLOCK = *mut SRWLOCK; -pub type LPINIT_ONCE = *mut INIT_ONCE; -pub type SOCKET = crate::os::windows::raw::SOCKET; pub type socklen_t = c_int; pub type ADDRESS_FAMILY = USHORT; +pub use FD_SET as fd_set; +pub use LINGER as linger; +pub use TIMEVAL as timeval; -pub const TRUE: BOOL = 1; -pub const FALSE: BOOL = 0; - -pub const CSTR_LESS_THAN: c_int = 1; -pub const CSTR_EQUAL: c_int = 2; -pub const CSTR_GREATER_THAN: c_int = 3; - -pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1; -pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10; -pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400; -pub const INVALID_FILE_ATTRIBUTES: DWORD = DWORD::MAX; - -pub const FILE_SHARE_DELETE: DWORD = 0x4; -pub const FILE_SHARE_READ: DWORD = 0x1; -pub const FILE_SHARE_WRITE: DWORD = 0x2; +pub type CONDITION_VARIABLE = RTL_CONDITION_VARIABLE; +pub type SRWLOCK = RTL_SRWLOCK; +pub type INIT_ONCE = RTL_RUN_ONCE; -pub const FILE_OPEN: ULONG = 0x00000001; -pub const FILE_OPEN_REPARSE_POINT: ULONG = 0x200000; -pub const OBJ_DONT_REPARSE: ULONG = 0x1000; +pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() }; +pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() }; +pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() }; -pub const CREATE_ALWAYS: DWORD = 2; -pub const CREATE_NEW: DWORD = 1; -pub const OPEN_ALWAYS: DWORD = 4; -pub const OPEN_EXISTING: DWORD = 3; -pub const TRUNCATE_EXISTING: DWORD = 5; - -pub const FILE_LIST_DIRECTORY: DWORD = 0x1; -pub const FILE_WRITE_DATA: DWORD = 0x00000002; -pub const FILE_APPEND_DATA: DWORD = 0x00000004; -pub const FILE_WRITE_EA: DWORD = 0x00000010; -pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100; -pub const DELETE: DWORD = 0x10000; -pub const READ_CONTROL: DWORD = 0x00020000; -pub const SYNCHRONIZE: DWORD = 0x00100000; -pub const GENERIC_READ: DWORD = 0x80000000; -pub const GENERIC_WRITE: DWORD = 0x40000000; -pub const STANDARD_RIGHTS_WRITE: DWORD = READ_CONTROL; -pub const FILE_GENERIC_WRITE: DWORD = STANDARD_RIGHTS_WRITE - | FILE_WRITE_DATA - | FILE_WRITE_ATTRIBUTES - | FILE_WRITE_EA - | FILE_APPEND_DATA - | SYNCHRONIZE; - -pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000; -pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000; -pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000; - -pub const FIONBIO: c_ulong = 0x8004667e; - -pub const MAX_PATH: usize = 260; - -pub const FILE_TYPE_PIPE: u32 = 3; - -pub const CP_UTF8: DWORD = 65001; -pub const MB_ERR_INVALID_CHARS: DWORD = 0x08; -pub const WC_ERR_INVALID_CHARS: DWORD = 0x80; - -#[repr(C)] -#[derive(Copy)] -pub struct WIN32_FIND_DATAW { - pub dwFileAttributes: DWORD, - pub ftCreationTime: FILETIME, - pub ftLastAccessTime: FILETIME, - pub ftLastWriteTime: FILETIME, - pub nFileSizeHigh: DWORD, - pub nFileSizeLow: DWORD, - pub dwReserved0: DWORD, - pub dwReserved1: DWORD, - pub cFileName: [wchar_t; 260], // #define MAX_PATH 260 - pub cAlternateFileName: [wchar_t; 14], -} -impl Clone for WIN32_FIND_DATAW { - fn clone(&self) -> Self { - *self - } -} - -pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01; -pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80; - -pub const WSADESCRIPTION_LEN: usize = 256; -pub const WSASYS_STATUS_LEN: usize = 128; -pub const WSAPROTOCOL_LEN: DWORD = 255; -pub const INVALID_SOCKET: SOCKET = !0; - -pub const MAX_PROTOCOL_CHAIN: DWORD = 7; - -pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; -pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; -pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c; -pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003; -pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001; -pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4; - -pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1; -pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2; - -// Note that these are not actually HANDLEs, just values to pass to GetStdHandle -pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; -pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; -pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; - -pub const PROGRESS_CONTINUE: DWORD = 0; - -pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT; - -pub const INVALID_HANDLE_VALUE: HANDLE = ptr::invalid_mut(!0); - -pub const FACILITY_NT_BIT: DWORD = 0x1000_0000; - -pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000; -pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800; -pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200; - -pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; - -pub const DLL_THREAD_DETACH: DWORD = 3; -pub const DLL_PROCESS_DETACH: DWORD = 0; - -pub const INFINITE: DWORD = !0; - -pub const DUPLICATE_SAME_ACCESS: DWORD = 0x00000002; - -pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { ptr: ptr::null_mut() }; -pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() }; -pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { ptr: ptr::null_mut() }; - -pub const INIT_ONCE_INIT_FAILED: DWORD = 0x00000004; - -pub const DETACHED_PROCESS: DWORD = 0x00000008; -pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200; -pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400; -pub const STARTF_USESTDHANDLES: DWORD = 0x00000100; - -pub const AF_INET: c_int = 2; -pub const AF_INET6: c_int = 23; -pub const SD_BOTH: c_int = 2; -pub const SD_RECEIVE: c_int = 0; -pub const SD_SEND: c_int = 1; -pub const SOCK_DGRAM: c_int = 2; -pub const SOCK_STREAM: c_int = 1; -pub const SOCKET_ERROR: c_int = -1; -pub const SOL_SOCKET: c_int = 0xffff; -pub const SO_LINGER: c_int = 0x0080; -pub const SO_RCVTIMEO: c_int = 0x1006; -pub const SO_SNDTIMEO: c_int = 0x1005; -pub const IPPROTO_IP: c_int = 0; -pub const IPPROTO_TCP: c_int = 6; -pub const IPPROTO_IPV6: c_int = 41; -pub const TCP_NODELAY: c_int = 0x0001; -pub const IP_TTL: c_int = 4; -pub const IPV6_V6ONLY: c_int = 27; -pub const SO_ERROR: c_int = 0x1007; -pub const SO_BROADCAST: c_int = 0x0020; -pub const IP_MULTICAST_LOOP: c_int = 11; -pub const IPV6_MULTICAST_LOOP: c_int = 11; -pub const IP_MULTICAST_TTL: c_int = 10; -pub const IP_ADD_MEMBERSHIP: c_int = 12; -pub const IP_DROP_MEMBERSHIP: c_int = 13; -pub const IPV6_ADD_MEMBERSHIP: c_int = 12; -pub const IPV6_DROP_MEMBERSHIP: c_int = 13; -pub const MSG_PEEK: c_int = 0x2; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct linger { - pub l_onoff: c_ushort, - pub l_linger: c_ushort, -} +// Some windows_sys types have different signs than the types we use. +pub const OBJ_DONT_REPARSE: u32 = windows_sys::OBJ_DONT_REPARSE as u32; +pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: u32 = + windows_sys::FRS_ERR_SYSVOL_POPULATE_TIMEOUT as u32; +pub const AF_INET: c_int = windows_sys::AF_INET as c_int; +pub const AF_INET6: c_int = windows_sys::AF_INET6 as c_int; #[repr(C)] pub struct ip_mreq { @@ -266,66 +73,19 @@ pub struct ipv6_mreq { pub ipv6mr_interface: c_uint, } -pub const VOLUME_NAME_DOS: DWORD = 0x0; -pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1; - -pub const FILE_BEGIN: DWORD = 0; -pub const FILE_CURRENT: DWORD = 1; -pub const FILE_END: DWORD = 2; - -pub const WAIT_OBJECT_0: DWORD = 0x00000000; -pub const WAIT_TIMEOUT: DWORD = 258; -pub const WAIT_FAILED: DWORD = 0xFFFFFFFF; - -pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001; -pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002; -pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000; -pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000; -pub const PIPE_WAIT: DWORD = 0x00000000; -pub const PIPE_TYPE_BYTE: DWORD = 0x00000000; -pub const PIPE_REJECT_REMOTE_CLIENTS: DWORD = 0x00000008; -pub const PIPE_READMODE_BYTE: DWORD = 0x00000000; - -pub const FD_SETSIZE: usize = 64; - -pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000; - -pub const STATUS_SUCCESS: NTSTATUS = 0x00000000; -pub const STATUS_DELETE_PENDING: NTSTATUS = 0xc0000056_u32 as _; -pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xc000000d_u32 as _; - -pub const STATUS_PENDING: NTSTATUS = 0x103 as _; -pub const STATUS_END_OF_FILE: NTSTATUS = 0xC0000011_u32 as _; - // Equivalent to the `NT_SUCCESS` C preprocessor macro. // See: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values pub fn nt_success(status: NTSTATUS) -> bool { status >= 0 } -pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002; - -#[repr(C)] -pub struct UNICODE_STRING { - pub Length: u16, - pub MaximumLength: u16, - pub Buffer: *mut u16, -} impl UNICODE_STRING { pub fn from_ref(slice: &[u16]) -> Self { let len = slice.len() * mem::size_of::<u16>(); Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ } } } -#[repr(C)] -pub struct OBJECT_ATTRIBUTES { - pub Length: ULONG, - pub RootDirectory: HANDLE, - pub ObjectName: *const UNICODE_STRING, - pub Attributes: ULONG, - pub SecurityDescriptor: *mut c_void, - pub SecurityQualityOfService: *mut c_void, -} + impl Default for OBJECT_ATTRIBUTES { fn default() -> Self { Self { @@ -338,193 +98,20 @@ impl Default for OBJECT_ATTRIBUTES { } } } -#[repr(C)] -union IO_STATUS_BLOCK_union { - Status: NTSTATUS, - Pointer: *mut c_void, -} -impl Default for IO_STATUS_BLOCK_union { - fn default() -> Self { - let mut this = Self { Pointer: ptr::null_mut() }; - this.Status = STATUS_PENDING; - this - } -} -#[repr(C)] -#[derive(Default)] -pub struct IO_STATUS_BLOCK { - u: IO_STATUS_BLOCK_union, - pub Information: usize, -} + impl IO_STATUS_BLOCK { + pub const PENDING: Self = + IO_STATUS_BLOCK { Anonymous: IO_STATUS_BLOCK_0 { Status: STATUS_PENDING }, Information: 0 }; pub fn status(&self) -> NTSTATUS { - // SAFETY: If `self.u.Status` was set then this is obviously safe. - // If `self.u.Pointer` was set then this is the equivalent to converting + // SAFETY: If `self.Anonymous.Status` was set then this is obviously safe. + // If `self.Anonymous.Pointer` was set then this is the equivalent to converting // the pointer to an integer, which is also safe. // Currently the only safe way to construct `IO_STATUS_BLOCK` outside of // this module is to call the `default` method, which sets the `Status`. - unsafe { self.u.Status } + unsafe { self.Anonymous.Status } } } -pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn( - dwErrorCode: DWORD, - dwNumberOfBytesTransferred: DWORD, - lpOverlapped: *mut OVERLAPPED, -); - -type IO_APC_ROUTINE = unsafe extern "system" fn( - ApcContext: *mut c_void, - IoStatusBlock: *mut IO_STATUS_BLOCK, - Reserved: ULONG, -); - -#[repr(C)] -#[cfg(not(target_pointer_width = "64"))] -pub struct WSADATA { - pub wVersion: WORD, - pub wHighVersion: WORD, - pub szDescription: [u8; WSADESCRIPTION_LEN + 1], - pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1], - pub iMaxSockets: u16, - pub iMaxUdpDg: u16, - pub lpVendorInfo: *mut u8, -} -#[repr(C)] -#[cfg(target_pointer_width = "64")] -pub struct WSADATA { - pub wVersion: WORD, - pub wHighVersion: WORD, - pub iMaxSockets: u16, - pub iMaxUdpDg: u16, - pub lpVendorInfo: *mut u8, - pub szDescription: [u8; WSADESCRIPTION_LEN + 1], - pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1], -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct WSABUF { - pub len: ULONG, - pub buf: *mut CHAR, -} - -#[repr(C)] -pub struct WSAPROTOCOL_INFO { - pub dwServiceFlags1: DWORD, - pub dwServiceFlags2: DWORD, - pub dwServiceFlags3: DWORD, - pub dwServiceFlags4: DWORD, - pub dwProviderFlags: DWORD, - pub ProviderId: GUID, - pub dwCatalogEntryId: DWORD, - pub ProtocolChain: WSAPROTOCOLCHAIN, - pub iVersion: c_int, - pub iAddressFamily: c_int, - pub iMaxSockAddr: c_int, - pub iMinSockAddr: c_int, - pub iSocketType: c_int, - pub iProtocol: c_int, - pub iProtocolMaxOffset: c_int, - pub iNetworkByteOrder: c_int, - pub iSecurityScheme: c_int, - pub dwMessageSize: DWORD, - pub dwProviderReserved: DWORD, - pub szProtocol: [u16; (WSAPROTOCOL_LEN as usize) + 1], -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct WIN32_FILE_ATTRIBUTE_DATA { - pub dwFileAttributes: DWORD, - pub ftCreationTime: FILETIME, - pub ftLastAccessTime: FILETIME, - pub ftLastWriteTime: FILETIME, - pub nFileSizeHigh: DWORD, - pub nFileSizeLow: DWORD, -} - -#[repr(C)] -#[allow(dead_code)] // we only use some variants -pub enum FILE_INFO_BY_HANDLE_CLASS { - FileBasicInfo = 0, - FileStandardInfo = 1, - FileNameInfo = 2, - FileRenameInfo = 3, - FileDispositionInfo = 4, - FileAllocationInfo = 5, - FileEndOfFileInfo = 6, - FileStreamInfo = 7, - FileCompressionInfo = 8, - FileAttributeTagInfo = 9, - FileIdBothDirectoryInfo = 10, // 0xA - FileIdBothDirectoryRestartInfo = 11, // 0xB - FileIoPriorityHintInfo = 12, // 0xC - FileRemoteProtocolInfo = 13, // 0xD - FileFullDirectoryInfo = 14, // 0xE - FileFullDirectoryRestartInfo = 15, // 0xF - FileStorageInfo = 16, // 0x10 - FileAlignmentInfo = 17, // 0x11 - FileIdInfo = 18, // 0x12 - FileIdExtdDirectoryInfo = 19, // 0x13 - FileIdExtdDirectoryRestartInfo = 20, // 0x14 - FileDispositionInfoEx = 21, // 0x15, Windows 10 version 1607 - MaximumFileInfoByHandlesClass, -} - -#[repr(C)] -pub struct FILE_ATTRIBUTE_TAG_INFO { - pub FileAttributes: DWORD, - pub ReparseTag: DWORD, -} - -#[repr(C)] -pub struct FILE_DISPOSITION_INFO { - pub DeleteFile: BOOLEAN, -} - -pub const FILE_DISPOSITION_DELETE: DWORD = 0x1; -pub const FILE_DISPOSITION_POSIX_SEMANTICS: DWORD = 0x2; -pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: DWORD = 0x10; - -#[repr(C)] -pub struct FILE_DISPOSITION_INFO_EX { - pub Flags: DWORD, -} - -#[repr(C)] -#[derive(Default)] -pub struct FILE_ID_BOTH_DIR_INFO { - pub NextEntryOffset: DWORD, - pub FileIndex: DWORD, - pub CreationTime: LARGE_INTEGER, - pub LastAccessTime: LARGE_INTEGER, - pub LastWriteTime: LARGE_INTEGER, - pub ChangeTime: LARGE_INTEGER, - pub EndOfFile: LARGE_INTEGER, - pub AllocationSize: LARGE_INTEGER, - pub FileAttributes: DWORD, - pub FileNameLength: DWORD, - pub EaSize: DWORD, - pub ShortNameLength: CCHAR, - pub ShortName: [WCHAR; 12], - pub FileId: LARGE_INTEGER, - pub FileName: [WCHAR; 1], -} -#[repr(C)] -pub struct FILE_BASIC_INFO { - pub CreationTime: LARGE_INTEGER, - pub LastAccessTime: LARGE_INTEGER, - pub LastWriteTime: LARGE_INTEGER, - pub ChangeTime: LARGE_INTEGER, - pub FileAttributes: DWORD, -} - -#[repr(C)] -pub struct FILE_END_OF_FILE_INFO { - pub EndOfFile: LARGE_INTEGER, -} - /// NB: Use carefully! In general using this as a reference is likely to get the /// provenance wrong for the `rest` field! #[repr(C)] @@ -555,34 +142,6 @@ pub struct MOUNT_POINT_REPARSE_BUFFER { pub PrintNameLength: c_ushort, pub PathBuffer: WCHAR, } - -pub type LPPROGRESS_ROUTINE = crate::option::Option< - unsafe extern "system" fn( - TotalFileSize: LARGE_INTEGER, - TotalBytesTransferred: LARGE_INTEGER, - StreamSize: LARGE_INTEGER, - StreamBytesTransferred: LARGE_INTEGER, - dwStreamNumber: DWORD, - dwCallbackReason: DWORD, - hSourceFile: HANDLE, - hDestinationFile: HANDLE, - lpData: LPVOID, - ) -> DWORD, ->; - -#[repr(C)] -pub struct CONDITION_VARIABLE { - pub ptr: LPVOID, -} -#[repr(C)] -pub struct SRWLOCK { - pub ptr: LPVOID, -} -#[repr(C)] -pub struct INIT_ONCE { - pub ptr: LPVOID, -} - #[repr(C)] pub struct REPARSE_MOUNTPOINT_DATA_BUFFER { pub ReparseTag: DWORD, @@ -595,103 +154,6 @@ pub struct REPARSE_MOUNTPOINT_DATA_BUFFER { } #[repr(C)] -pub struct GUID { - pub Data1: DWORD, - pub Data2: WORD, - pub Data3: WORD, - pub Data4: [BYTE; 8], -} - -#[repr(C)] -pub struct WSAPROTOCOLCHAIN { - pub ChainLen: c_int, - pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize], -} - -#[repr(C)] -pub struct SECURITY_ATTRIBUTES { - pub nLength: DWORD, - pub lpSecurityDescriptor: LPVOID, - pub bInheritHandle: BOOL, -} - -#[repr(C)] -pub struct PROCESS_INFORMATION { - pub hProcess: HANDLE, - pub hThread: HANDLE, - pub dwProcessId: DWORD, - pub dwThreadId: DWORD, -} - -#[repr(C)] -pub struct STARTUPINFO { - pub cb: DWORD, - pub lpReserved: LPWSTR, - pub lpDesktop: LPWSTR, - pub lpTitle: LPWSTR, - pub dwX: DWORD, - pub dwY: DWORD, - pub dwXSize: DWORD, - pub dwYSize: DWORD, - pub dwXCountChars: DWORD, - pub dwYCountCharts: DWORD, - pub dwFillAttribute: DWORD, - pub dwFlags: DWORD, - pub wShowWindow: WORD, - pub cbReserved2: WORD, - pub lpReserved2: LPBYTE, - pub hStdInput: HANDLE, - pub hStdOutput: HANDLE, - pub hStdError: HANDLE, -} - -#[repr(C)] -pub struct SOCKADDR { - pub sa_family: ADDRESS_FAMILY, - pub sa_data: [CHAR; 14], -} - -#[repr(C)] -#[derive(Copy, Clone, Debug, Default)] -pub struct FILETIME { - pub dwLowDateTime: DWORD, - pub dwHighDateTime: DWORD, -} - -#[repr(C)] -pub struct SYSTEM_INFO { - pub wProcessorArchitecture: WORD, - pub wReserved: WORD, - pub dwPageSize: DWORD, - pub lpMinimumApplicationAddress: LPVOID, - pub lpMaximumApplicationAddress: LPVOID, - pub dwActiveProcessorMask: DWORD_PTR, - pub dwNumberOfProcessors: DWORD, - pub dwProcessorType: DWORD, - pub dwAllocationGranularity: DWORD, - pub wProcessorLevel: WORD, - pub wProcessorRevision: WORD, -} - -#[repr(C)] -pub struct OVERLAPPED { - pub Internal: *mut c_ulong, - pub InternalHigh: *mut c_ulong, - pub Offset: DWORD, - pub OffsetHigh: DWORD, - pub hEvent: HANDLE, -} - -#[repr(C)] -#[allow(dead_code)] // we only use some variants -pub enum ADDRESS_MODE { - AddrMode1616, - AddrMode1632, - AddrModeReal, - AddrModeFlat, -} - -#[repr(C)] pub struct SOCKADDR_STORAGE_LH { pub ss_family: ADDRESS_FAMILY, pub __ss_pad1: [CHAR; 6], @@ -700,18 +162,6 @@ pub struct SOCKADDR_STORAGE_LH { } #[repr(C)] -pub struct ADDRINFOA { - pub ai_flags: c_int, - pub ai_family: c_int, - pub ai_socktype: c_int, - pub ai_protocol: c_int, - pub ai_addrlen: size_t, - pub ai_canonname: *mut c_char, - pub ai_addr: *mut SOCKADDR, - pub ai_next: *mut ADDRINFOA, -} - -#[repr(C)] #[derive(Copy, Clone)] pub struct sockaddr_in { pub sin_family: ADDRESS_FAMILY, @@ -742,583 +192,126 @@ pub struct in6_addr { pub s6_addr: [u8; 16], } -#[repr(C)] -#[derive(Copy, Clone)] -#[allow(dead_code)] // we only use some variants -pub enum EXCEPTION_DISPOSITION { - ExceptionContinueExecution, - ExceptionContinueSearch, - ExceptionNestedException, - ExceptionCollidedUnwind, -} - -#[repr(C)] -#[derive(Copy)] -pub struct fd_set { - pub fd_count: c_uint, - pub fd_array: [SOCKET; FD_SETSIZE], -} - -impl Clone for fd_set { - fn clone(&self) -> fd_set { - *self - } -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct timeval { - pub tv_sec: c_long, - pub tv_usec: c_long, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct CONSOLE_READCONSOLE_CONTROL { - pub nLength: ULONG, - pub nInitialChars: ULONG, - pub dwCtrlWakeupMask: ULONG, - pub dwControlKeyState: ULONG, -} -pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL; - // Desktop specific functions & types cfg_if::cfg_if! { if #[cfg(not(target_vendor = "uwp"))] { - pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0; - pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd; - pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15; - - #[repr(C)] - pub struct EXCEPTION_RECORD { - pub ExceptionCode: DWORD, - pub ExceptionFlags: DWORD, - pub ExceptionRecord: *mut EXCEPTION_RECORD, - pub ExceptionAddress: LPVOID, - pub NumberParameters: DWORD, - pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS], - } - - pub enum CONTEXT {} - - #[repr(C)] - pub struct EXCEPTION_POINTERS { - pub ExceptionRecord: *mut EXCEPTION_RECORD, - pub ContextRecord: *mut CONTEXT, - } - - pub type PVECTORED_EXCEPTION_HANDLER = - extern "system" fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG; - - #[repr(C)] - pub struct BY_HANDLE_FILE_INFORMATION { - pub dwFileAttributes: DWORD, - pub ftCreationTime: FILETIME, - pub ftLastAccessTime: FILETIME, - pub ftLastWriteTime: FILETIME, - pub dwVolumeSerialNumber: DWORD, - pub nFileSizeHigh: DWORD, - pub nFileSizeLow: DWORD, - pub nNumberOfLinks: DWORD, - pub nFileIndexHigh: DWORD, - pub nFileIndexLow: DWORD, - } - - pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION; - - pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001; - - pub const TOKEN_READ: DWORD = 0x20008; - - #[link(name = "advapi32")] - extern "system" { - // Forbidden when targeting UWP - #[link_name = "SystemFunction036"] - pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN; - - // Allowed but unused by UWP - pub fn OpenProcessToken( - ProcessHandle: HANDLE, - DesiredAccess: DWORD, - TokenHandle: *mut HANDLE, - ) -> BOOL; - } - - #[link(name = "userenv")] - extern "system" { - // Allowed but unused by UWP - pub fn GetUserProfileDirectoryW( - hToken: HANDLE, - lpProfileDir: LPWSTR, - lpcchSize: *mut DWORD, - ) -> BOOL; - } - - #[link(name = "kernel32")] - extern "system" { - // Allowed but unused by UWP - pub fn GetFileInformationByHandle( - hFile: HANDLE, - lpFileInformation: LPBY_HANDLE_FILE_INFORMATION, - ) -> BOOL; - pub fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL; - pub fn AddVectoredExceptionHandler( - FirstHandler: ULONG, - VectoredHandler: PVECTORED_EXCEPTION_HANDLER, - ) -> LPVOID; - pub fn CreateHardLinkW( - lpSymlinkFileName: LPCWSTR, - lpTargetFileName: LPCWSTR, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - ) -> BOOL; - pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL; - pub fn GetWindowsDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; - } -} -} - -// UWP specific functions & types -cfg_if::cfg_if! { -if #[cfg(target_vendor = "uwp")] { - #[repr(C)] - pub struct FILE_STANDARD_INFO { - pub AllocationSize: LARGE_INTEGER, - pub EndOfFile: LARGE_INTEGER, - pub NumberOfLinks: DWORD, - pub DeletePending: BOOLEAN, - pub Directory: BOOLEAN, - } -} -} - -// Shared between Desktop & UWP - -#[link(name = "kernel32")] -extern "system" { - pub fn GetCurrentProcessId() -> DWORD; - - pub fn ReadConsoleW( - hConsoleInput: HANDLE, - lpBuffer: LPVOID, - nNumberOfCharsToRead: DWORD, - lpNumberOfCharsRead: LPDWORD, - pInputControl: PCONSOLE_READCONSOLE_CONTROL, - ) -> BOOL; - pub fn WriteConsoleW( - hConsoleOutput: HANDLE, - lpBuffer: LPCVOID, - nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: LPDWORD, - lpReserved: LPVOID, - ) -> BOOL; - pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; - - pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; - pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; - pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; - pub fn SetFileTime( - hFile: BorrowedHandle<'_>, - lpCreationTime: Option<&FILETIME>, - lpLastAccessTime: Option<&FILETIME>, - lpLastWriteTime: Option<&FILETIME>, - ) -> BOOL; - pub fn SetLastError(dwErrCode: DWORD); - pub fn GetCommandLineW() -> LPWSTR; - pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; - pub fn GetCurrentProcess() -> HANDLE; - pub fn GetCurrentThread() -> HANDLE; - pub fn GetStdHandle(which: DWORD) -> HANDLE; - pub fn ExitProcess(uExitCode: c_uint) -> !; - pub fn DeviceIoControl( - hDevice: HANDLE, - dwIoControlCode: DWORD, - lpInBuffer: LPVOID, - nInBufferSize: DWORD, - lpOutBuffer: LPVOID, - nOutBufferSize: DWORD, - lpBytesReturned: LPDWORD, - lpOverlapped: LPOVERLAPPED, - ) -> BOOL; - pub fn CreateThread( - lpThreadAttributes: LPSECURITY_ATTRIBUTES, - dwStackSize: SIZE_T, - lpStartAddress: extern "system" fn(*mut c_void) -> DWORD, - lpParameter: LPVOID, - dwCreationFlags: DWORD, - lpThreadId: LPDWORD, - ) -> HandleOrNull; - pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; - pub fn SwitchToThread() -> BOOL; - pub fn Sleep(dwMilliseconds: DWORD); - pub fn SleepEx(dwMilliseconds: DWORD, bAlertable: BOOL) -> DWORD; - pub fn GetProcessId(handle: HANDLE) -> DWORD; - pub fn CopyFileExW( - lpExistingFileName: LPCWSTR, - lpNewFileName: LPCWSTR, - lpProgressRoutine: LPPROGRESS_ROUTINE, - lpData: LPVOID, - pbCancel: LPBOOL, - dwCopyFlags: DWORD, - ) -> BOOL; - pub fn FormatMessageW( - flags: DWORD, - lpSrc: LPVOID, - msgId: DWORD, - langId: DWORD, - buf: LPWSTR, - nsize: DWORD, - args: *const c_void, - ) -> DWORD; - pub fn TlsAlloc() -> DWORD; - pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; - pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL; - pub fn TlsFree(dwTlsIndex: DWORD) -> BOOL; - pub fn GetLastError() -> DWORD; - pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL; - pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL; - pub fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL; - pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL; - pub fn CreateProcessW( - lpApplicationName: LPCWSTR, - lpCommandLine: LPWSTR, - lpProcessAttributes: LPSECURITY_ATTRIBUTES, - lpThreadAttributes: LPSECURITY_ATTRIBUTES, - bInheritHandles: BOOL, - dwCreationFlags: DWORD, - lpEnvironment: LPVOID, - lpCurrentDirectory: LPCWSTR, - lpStartupInfo: LPSTARTUPINFO, - lpProcessInformation: LPPROCESS_INFORMATION, - ) -> BOOL; - pub fn GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD; - pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL; - pub fn GetEnvironmentStringsW() -> LPWCH; - pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL; - pub fn GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD) -> DWORD; - pub fn CreateDirectoryW( - lpPathName: LPCWSTR, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - ) -> BOOL; - pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; - pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; - pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; - pub fn DuplicateHandle( - hSourceProcessHandle: HANDLE, - hSourceHandle: HANDLE, - hTargetProcessHandle: HANDLE, - lpTargetHandle: LPHANDLE, - dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwOptions: DWORD, - ) -> BOOL; - pub fn ReadFile( - hFile: BorrowedHandle<'_>, - lpBuffer: LPVOID, - nNumberOfBytesToRead: DWORD, - lpNumberOfBytesRead: LPDWORD, - lpOverlapped: LPOVERLAPPED, - ) -> BOOL; - pub fn ReadFileEx( - hFile: BorrowedHandle<'_>, - lpBuffer: LPVOID, - nNumberOfBytesToRead: DWORD, - lpOverlapped: LPOVERLAPPED, - lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, - ) -> BOOL; - pub fn WriteFileEx( - hFile: BorrowedHandle<'_>, - lpBuffer: LPVOID, - nNumberOfBytesToWrite: DWORD, - lpOverlapped: LPOVERLAPPED, - lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, - ) -> BOOL; - pub fn CloseHandle(hObject: HANDLE) -> BOOL; - pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD) - -> BOOL; - pub fn SetFilePointerEx( - hFile: HANDLE, - liDistanceToMove: LARGE_INTEGER, - lpNewFilePointer: PLARGE_INTEGER, - dwMoveMethod: DWORD, - ) -> BOOL; - pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL; - pub fn CreateFileW( - lpFileName: LPCWSTR, - dwDesiredAccess: DWORD, - dwShareMode: DWORD, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - dwCreationDisposition: DWORD, - dwFlagsAndAttributes: DWORD, - hTemplateFile: HANDLE, - ) -> HandleOrInvalid; - - pub fn FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE; - pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL; - pub fn FindClose(findFile: HANDLE) -> BOOL; - - pub fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void; - pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE; - pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; - - pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME); - pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO); - - pub fn CreateEventW( - lpEventAttributes: LPSECURITY_ATTRIBUTES, - bManualReset: BOOL, - bInitialState: BOOL, - lpName: LPCWSTR, - ) -> HANDLE; - pub fn WaitForMultipleObjects( - nCount: DWORD, - lpHandles: *const HANDLE, - bWaitAll: BOOL, - dwMilliseconds: DWORD, - ) -> DWORD; - pub fn CreateNamedPipeW( - lpName: LPCWSTR, - dwOpenMode: DWORD, - dwPipeMode: DWORD, - nMaxInstances: DWORD, - nOutBufferSize: DWORD, - nInBufferSize: DWORD, - nDefaultTimeOut: DWORD, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - ) -> HANDLE; - pub fn CancelIo(handle: HANDLE) -> BOOL; - pub fn GetOverlappedResult( - hFile: HANDLE, - lpOverlapped: LPOVERLAPPED, - lpNumberOfBytesTransferred: LPDWORD, - bWait: BOOL, - ) -> BOOL; - pub fn CreateSymbolicLinkW( - lpSymlinkFileName: LPCWSTR, - lpTargetFileName: LPCWSTR, - dwFlags: DWORD, - ) -> BOOLEAN; - pub fn GetFinalPathNameByHandleW( - hFile: HANDLE, - lpszFilePath: LPCWSTR, - cchFilePath: DWORD, - dwFlags: DWORD, - ) -> DWORD; - pub fn GetFileInformationByHandleEx( - hFile: HANDLE, - fileInfoClass: FILE_INFO_BY_HANDLE_CLASS, - lpFileInformation: LPVOID, - dwBufferSize: DWORD, - ) -> BOOL; - pub fn SetFileInformationByHandle( - hFile: HANDLE, - FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, - lpFileInformation: LPVOID, - dwBufferSize: DWORD, - ) -> BOOL; - pub fn GetFileType(hfile: HANDLE) -> DWORD; - pub fn SleepConditionVariableSRW( - ConditionVariable: PCONDITION_VARIABLE, - SRWLock: PSRWLOCK, - dwMilliseconds: DWORD, - Flags: ULONG, - ) -> BOOL; - - pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE); - pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE); - - pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK); - pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK); - pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK); - pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK); - pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN; - pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN; - - pub fn InitOnceBeginInitialize( - lpInitOnce: LPINIT_ONCE, - dwFlags: DWORD, - fPending: LPBOOL, - lpContext: *mut LPVOID, - ) -> BOOL; - pub fn InitOnceComplete(lpInitOnce: LPINIT_ONCE, dwFlags: DWORD, lpContext: LPVOID) -> BOOL; - - pub fn CompareStringOrdinal( - lpString1: LPCWSTR, - cchCount1: c_int, - lpString2: LPCWSTR, - cchCount2: c_int, - bIgnoreCase: BOOL, - ) -> c_int; - pub fn GetFullPathNameW( - lpFileName: LPCWSTR, - nBufferLength: DWORD, - lpBuffer: LPWSTR, - lpFilePart: *mut LPWSTR, - ) -> DWORD; - pub fn GetFileAttributesW(lpFileName: LPCWSTR) -> DWORD; - - pub fn MultiByteToWideChar( - CodePage: UINT, - dwFlags: DWORD, - lpMultiByteStr: LPCCH, - cbMultiByte: c_int, - lpWideCharStr: LPWSTR, - cchWideChar: c_int, - ) -> c_int; - pub fn WideCharToMultiByte( - CodePage: UINT, - dwFlags: DWORD, - lpWideCharStr: LPCWCH, - cchWideChar: c_int, - lpMultiByteStr: LPSTR, - cbMultiByte: c_int, - lpDefaultChar: LPCCH, - lpUsedDefaultChar: LPBOOL, - ) -> c_int; + pub const EXCEPTION_CONTINUE_SEARCH: i32 = 0; } - -#[link(name = "ws2_32")] -extern "system" { - pub fn WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int; - pub fn WSACleanup() -> c_int; - pub fn WSAGetLastError() -> c_int; - pub fn WSADuplicateSocketW( - s: SOCKET, - dwProcessId: DWORD, - lpProtocolInfo: LPWSAPROTOCOL_INFO, - ) -> c_int; - pub fn WSASend( - s: SOCKET, - lpBuffers: LPWSABUF, - dwBufferCount: DWORD, - lpNumberOfBytesSent: LPDWORD, - dwFlags: DWORD, - lpOverlapped: LPWSAOVERLAPPED, - lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, - ) -> c_int; - pub fn WSARecv( - s: SOCKET, - lpBuffers: LPWSABUF, - dwBufferCount: DWORD, - lpNumberOfBytesRecvd: LPDWORD, - lpFlags: LPDWORD, - lpOverlapped: LPWSAOVERLAPPED, - lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, - ) -> c_int; - pub fn WSASocketW( - af: c_int, - kind: c_int, - protocol: c_int, - lpProtocolInfo: LPWSAPROTOCOL_INFO, - g: GROUP, - dwFlags: DWORD, - ) -> SOCKET; - pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int; - pub fn closesocket(socket: SOCKET) -> c_int; - pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int; - pub fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int; - pub fn recvfrom( - socket: SOCKET, - buf: *mut c_void, - len: c_int, - flags: c_int, - addr: *mut SOCKADDR, - addrlen: *mut c_int, - ) -> c_int; - pub fn sendto( - socket: SOCKET, - buf: *const c_void, - len: c_int, - flags: c_int, - addr: *const SOCKADDR, - addrlen: c_int, - ) -> c_int; - pub fn shutdown(socket: SOCKET, how: c_int) -> c_int; - pub fn accept(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> SOCKET; - pub fn getsockopt( - s: SOCKET, - level: c_int, - optname: c_int, - optval: *mut c_char, - optlen: *mut c_int, - ) -> c_int; - pub fn setsockopt( - s: SOCKET, - level: c_int, - optname: c_int, - optval: *const c_void, - optlen: c_int, - ) -> c_int; - pub fn getsockname(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int; - pub fn getpeername(socket: SOCKET, address: *mut SOCKADDR, address_len: *mut c_int) -> c_int; - pub fn bind(socket: SOCKET, address: *const SOCKADDR, address_len: socklen_t) -> c_int; - pub fn listen(socket: SOCKET, backlog: c_int) -> c_int; - pub fn connect(socket: SOCKET, address: *const SOCKADDR, len: c_int) -> c_int; - pub fn getaddrinfo( - node: *const c_char, - service: *const c_char, - hints: *const ADDRINFOA, - res: *mut *mut ADDRINFOA, - ) -> c_int; - pub fn freeaddrinfo(res: *mut ADDRINFOA); - pub fn select( - nfds: c_int, - readfds: *mut fd_set, - writefds: *mut fd_set, - exceptfds: *mut fd_set, - timeout: *const timeval, - ) -> c_int; -} - -#[link(name = "bcrypt")] -extern "system" { - // >= Vista / Server 2008 - // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom - pub fn BCryptGenRandom( - hAlgorithm: BCRYPT_ALG_HANDLE, - pBuffer: *mut u8, - cbBuffer: ULONG, - dwFlags: ULONG, - ) -> NTSTATUS; } -#[link(name = "ntdll")] -extern "system" { - pub fn NtCreateFile( - FileHandle: *mut HANDLE, - DesiredAccess: ACCESS_MASK, - ObjectAttributes: *const OBJECT_ATTRIBUTES, - IoStatusBlock: *mut IO_STATUS_BLOCK, - AllocationSize: *mut i64, - FileAttributes: ULONG, - ShareAccess: ULONG, - CreateDisposition: ULONG, - CreateOptions: ULONG, - EaBuffer: *mut c_void, - EaLength: ULONG, - ) -> NTSTATUS; - pub fn NtReadFile( - FileHandle: BorrowedHandle<'_>, - Event: HANDLE, - ApcRoutine: Option<IO_APC_ROUTINE>, - ApcContext: *mut c_void, - IoStatusBlock: &mut IO_STATUS_BLOCK, - Buffer: *mut crate::mem::MaybeUninit<u8>, - Length: ULONG, - ByteOffset: Option<&LARGE_INTEGER>, - Key: Option<&ULONG>, - ) -> NTSTATUS; - pub fn NtWriteFile( - FileHandle: BorrowedHandle<'_>, - Event: HANDLE, - ApcRoutine: Option<IO_APC_ROUTINE>, - ApcContext: *mut c_void, - IoStatusBlock: &mut IO_STATUS_BLOCK, - Buffer: *const u8, - Length: ULONG, - ByteOffset: Option<&LARGE_INTEGER>, - Key: Option<&ULONG>, - ) -> NTSTATUS; - pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> ULONG; +pub unsafe extern "system" fn WriteFileEx( + hFile: BorrowedHandle<'_>, + lpBuffer: *mut ::core::ffi::c_void, + nNumberOfBytesToWrite: u32, + lpOverlapped: *mut OVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, +) -> BOOL { + windows_sys::WriteFileEx( + hFile.as_raw_handle(), + lpBuffer.cast::<u8>(), + nNumberOfBytesToWrite, + lpOverlapped, + lpCompletionRoutine, + ) +} + +pub unsafe extern "system" fn ReadFileEx( + hFile: BorrowedHandle<'_>, + lpBuffer: *mut ::core::ffi::c_void, + nNumberOfBytesToRead: u32, + lpOverlapped: *mut OVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, +) -> BOOL { + windows_sys::ReadFileEx( + hFile.as_raw_handle(), + lpBuffer, + nNumberOfBytesToRead, + lpOverlapped, + lpCompletionRoutine, + ) +} + +// POSIX compatibility shims. +pub unsafe fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int { + windows_sys::recv(socket, buf.cast::<u8>(), len, flags) +} +pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int { + windows_sys::send(socket, buf.cast::<u8>(), len, flags) +} +pub unsafe fn recvfrom( + socket: SOCKET, + buf: *mut c_void, + len: c_int, + flags: c_int, + addr: *mut SOCKADDR, + addrlen: *mut c_int, +) -> c_int { + windows_sys::recvfrom(socket, buf.cast::<u8>(), len, flags, addr, addrlen) +} +pub unsafe fn sendto( + socket: SOCKET, + buf: *const c_void, + len: c_int, + flags: c_int, + addr: *const SOCKADDR, + addrlen: c_int, +) -> c_int { + windows_sys::sendto(socket, buf.cast::<u8>(), len, flags, addr, addrlen) +} +pub unsafe fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const ADDRINFOA, + res: *mut *mut ADDRINFOA, +) -> c_int { + windows_sys::getaddrinfo(node.cast::<u8>(), service.cast::<u8>(), hints, res) +} + +pub unsafe fn NtReadFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *mut crate::mem::MaybeUninit<u8>, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG>, +) -> NTSTATUS { + windows_sys::NtReadFile( + filehandle.as_raw_handle(), + event, + apcroutine, + apccontext, + iostatusblock, + buffer.cast::<c_void>(), + length, + byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()), + key.map(|k| k as *const u32).unwrap_or(ptr::null()), + ) +} +pub unsafe fn NtWriteFile( + filehandle: BorrowedHandle<'_>, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *mut c_void, + iostatusblock: &mut IO_STATUS_BLOCK, + buffer: *const u8, + length: ULONG, + byteoffset: Option<&LARGE_INTEGER>, + key: Option<&ULONG>, +) -> NTSTATUS { + windows_sys::NtWriteFile( + filehandle.as_raw_handle(), + event, + apcroutine, + apccontext, + iostatusblock, + buffer.cast::<c_void>(), + length, + byteoffset.map(|o| o as *const i64).unwrap_or(ptr::null()), + key.map(|k| k as *const u32).unwrap_or(ptr::null()), + ) } // Functions that aren't available on every version of Windows that we support, @@ -1328,34 +321,32 @@ compat_fn_with_fallback! { // >= Win10 1607 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription - pub fn SetThreadDescription(hThread: HANDLE, - lpThreadDescription: LPCWSTR) -> HRESULT { + pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL } // >= Win8 / Server 2012 // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime - pub fn GetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime: LPFILETIME) - -> () { - GetSystemTimeAsFileTime(lpSystemTimeAsFileTime) + pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () { + GetSystemTimeAsFileTime(lpsystemtimeasfiletime) } // >= Win11 / Server 2022 // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a - pub fn GetTempPath2W(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD { - GetTempPathW(nBufferLength, lpBuffer) + pub fn GetTempPath2W(bufferlength: u32, buffer: PWSTR) -> u32 { + GetTempPathW(bufferlength, buffer) } } compat_fn_optional! { crate::sys::compat::load_synch_functions(); pub fn WaitOnAddress( - Address: LPVOID, - CompareAddress: LPVOID, - AddressSize: SIZE_T, - dwMilliseconds: DWORD - ); - pub fn WakeByAddressSingle(Address: LPVOID); + address: *const ::core::ffi::c_void, + compareaddress: *const ::core::ffi::c_void, + addresssize: usize, + dwmilliseconds: u32 + ) -> BOOL; + pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void); } compat_fn_with_fallback! { diff --git a/library/std/src/sys/windows/c/errors.rs b/library/std/src/sys/windows/c/errors.rs deleted file mode 100644 index ad8da19b6da..00000000000 --- a/library/std/src/sys/windows/c/errors.rs +++ /dev/null @@ -1,1883 +0,0 @@ -// List of Windows system error codes with descriptions: -// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes - -#![allow(dead_code)] - -use super::{c_int, DWORD}; - -pub const ERROR_DIRECTORY_NOT_SUPPORTED: DWORD = 336; -pub const ERROR_DRIVER_CANCEL_TIMEOUT: DWORD = 594; -pub const ERROR_DISK_QUOTA_EXCEEDED: DWORD = 1295; -pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910; -pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014; -pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705; - -// The following list was obtained from -// `/usr/x86_64-w64-mingw32/include/winerror.h` -// in the Debian package -// mingw-w64_6.0.0-3_all.deb -// -// The header of that file says: -// * This file has no copyright assigned and is placed in the Public Domain. -// * This file is part of the mingw-w64 runtime package. -// * No warranty is given; refer to the file DISCLAIMER.PD within this package. -// -// The text here is the result of the following rune: -// grep -P '#define ERROR' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs -// grep -P '#define WSA' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs -// and then using some manually-invented but rather obvious editor search-and-replace -// invocations, plus some straightforward manual fixups, to turn it into Rust syntax -// and remove all the duplicates from the manual table above. - -pub const ERROR_SUCCESS: DWORD = 0; -pub const ERROR_INVALID_FUNCTION: DWORD = 1; -pub const ERROR_FILE_NOT_FOUND: DWORD = 2; -pub const ERROR_PATH_NOT_FOUND: DWORD = 3; -pub const ERROR_TOO_MANY_OPEN_FILES: DWORD = 4; -pub const ERROR_ACCESS_DENIED: DWORD = 5; -pub const ERROR_INVALID_HANDLE: DWORD = 6; -pub const ERROR_ARENA_TRASHED: DWORD = 7; -pub const ERROR_NOT_ENOUGH_MEMORY: DWORD = 8; -pub const ERROR_INVALID_BLOCK: DWORD = 9; -pub const ERROR_BAD_ENVIRONMENT: DWORD = 10; -pub const ERROR_BAD_FORMAT: DWORD = 11; -pub const ERROR_INVALID_ACCESS: DWORD = 12; -pub const ERROR_INVALID_DATA: DWORD = 13; -pub const ERROR_OUTOFMEMORY: DWORD = 14; -pub const ERROR_INVALID_DRIVE: DWORD = 15; -pub const ERROR_CURRENT_DIRECTORY: DWORD = 16; -pub const ERROR_NOT_SAME_DEVICE: DWORD = 17; -pub const ERROR_NO_MORE_FILES: DWORD = 18; -pub const ERROR_WRITE_PROTECT: DWORD = 19; -pub const ERROR_BAD_UNIT: DWORD = 20; -pub const ERROR_NOT_READY: DWORD = 21; -pub const ERROR_BAD_COMMAND: DWORD = 22; -pub const ERROR_CRC: DWORD = 23; -pub const ERROR_BAD_LENGTH: DWORD = 24; -pub const ERROR_SEEK: DWORD = 25; -pub const ERROR_NOT_DOS_DISK: DWORD = 26; -pub const ERROR_SECTOR_NOT_FOUND: DWORD = 27; -pub const ERROR_OUT_OF_PAPER: DWORD = 28; -pub const ERROR_WRITE_FAULT: DWORD = 29; -pub const ERROR_READ_FAULT: DWORD = 30; -pub const ERROR_GEN_FAILURE: DWORD = 31; -pub const ERROR_SHARING_VIOLATION: DWORD = 32; -pub const ERROR_LOCK_VIOLATION: DWORD = 33; -pub const ERROR_WRONG_DISK: DWORD = 34; -pub const ERROR_SHARING_BUFFER_EXCEEDED: DWORD = 36; -pub const ERROR_HANDLE_EOF: DWORD = 38; -pub const ERROR_HANDLE_DISK_FULL: DWORD = 39; -pub const ERROR_NOT_SUPPORTED: DWORD = 50; -pub const ERROR_REM_NOT_LIST: DWORD = 51; -pub const ERROR_DUP_NAME: DWORD = 52; -pub const ERROR_BAD_NETPATH: DWORD = 53; -pub const ERROR_NETWORK_BUSY: DWORD = 54; -pub const ERROR_DEV_NOT_EXIST: DWORD = 55; -pub const ERROR_TOO_MANY_CMDS: DWORD = 56; -pub const ERROR_ADAP_HDW_ERR: DWORD = 57; -pub const ERROR_BAD_NET_RESP: DWORD = 58; -pub const ERROR_UNEXP_NET_ERR: DWORD = 59; -pub const ERROR_BAD_REM_ADAP: DWORD = 60; -pub const ERROR_PRINTQ_FULL: DWORD = 61; -pub const ERROR_NO_SPOOL_SPACE: DWORD = 62; -pub const ERROR_PRINT_CANCELLED: DWORD = 63; -pub const ERROR_NETNAME_DELETED: DWORD = 64; -pub const ERROR_NETWORK_ACCESS_DENIED: DWORD = 65; -pub const ERROR_BAD_DEV_TYPE: DWORD = 66; -pub const ERROR_BAD_NET_NAME: DWORD = 67; -pub const ERROR_TOO_MANY_NAMES: DWORD = 68; -pub const ERROR_TOO_MANY_SESS: DWORD = 69; -pub const ERROR_SHARING_PAUSED: DWORD = 70; -pub const ERROR_REQ_NOT_ACCEP: DWORD = 71; -pub const ERROR_REDIR_PAUSED: DWORD = 72; -pub const ERROR_FILE_EXISTS: DWORD = 80; -pub const ERROR_CANNOT_MAKE: DWORD = 82; -pub const ERROR_FAIL_I24: DWORD = 83; -pub const ERROR_OUT_OF_STRUCTURES: DWORD = 84; -pub const ERROR_ALREADY_ASSIGNED: DWORD = 85; -pub const ERROR_INVALID_PASSWORD: DWORD = 86; -pub const ERROR_INVALID_PARAMETER: DWORD = 87; -pub const ERROR_NET_WRITE_FAULT: DWORD = 88; -pub const ERROR_NO_PROC_SLOTS: DWORD = 89; -pub const ERROR_TOO_MANY_SEMAPHORES: DWORD = 100; -pub const ERROR_EXCL_SEM_ALREADY_OWNED: DWORD = 101; -pub const ERROR_SEM_IS_SET: DWORD = 102; -pub const ERROR_TOO_MANY_SEM_REQUESTS: DWORD = 103; -pub const ERROR_INVALID_AT_INTERRUPT_TIME: DWORD = 104; -pub const ERROR_SEM_OWNER_DIED: DWORD = 105; -pub const ERROR_SEM_USER_LIMIT: DWORD = 106; -pub const ERROR_DISK_CHANGE: DWORD = 107; -pub const ERROR_DRIVE_LOCKED: DWORD = 108; -pub const ERROR_BROKEN_PIPE: DWORD = 109; -pub const ERROR_OPEN_FAILED: DWORD = 110; -pub const ERROR_BUFFER_OVERFLOW: DWORD = 111; -pub const ERROR_DISK_FULL: DWORD = 112; -pub const ERROR_NO_MORE_SEARCH_HANDLES: DWORD = 113; -pub const ERROR_INVALID_TARGET_HANDLE: DWORD = 114; -pub const ERROR_INVALID_CATEGORY: DWORD = 117; -pub const ERROR_INVALID_VERIFY_SWITCH: DWORD = 118; -pub const ERROR_BAD_DRIVER_LEVEL: DWORD = 119; -pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120; -pub const ERROR_SEM_TIMEOUT: DWORD = 121; -pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122; -pub const ERROR_INVALID_NAME: DWORD = 123; -pub const ERROR_INVALID_LEVEL: DWORD = 124; -pub const ERROR_NO_VOLUME_LABEL: DWORD = 125; -pub const ERROR_MOD_NOT_FOUND: DWORD = 126; -pub const ERROR_PROC_NOT_FOUND: DWORD = 127; -pub const ERROR_WAIT_NO_CHILDREN: DWORD = 128; -pub const ERROR_CHILD_NOT_COMPLETE: DWORD = 129; -pub const ERROR_DIRECT_ACCESS_HANDLE: DWORD = 130; -pub const ERROR_NEGATIVE_SEEK: DWORD = 131; -pub const ERROR_SEEK_ON_DEVICE: DWORD = 132; -pub const ERROR_IS_JOIN_TARGET: DWORD = 133; -pub const ERROR_IS_JOINED: DWORD = 134; -pub const ERROR_IS_SUBSTED: DWORD = 135; -pub const ERROR_NOT_JOINED: DWORD = 136; -pub const ERROR_NOT_SUBSTED: DWORD = 137; -pub const ERROR_JOIN_TO_JOIN: DWORD = 138; -pub const ERROR_SUBST_TO_SUBST: DWORD = 139; -pub const ERROR_JOIN_TO_SUBST: DWORD = 140; -pub const ERROR_SUBST_TO_JOIN: DWORD = 141; -pub const ERROR_BUSY_DRIVE: DWORD = 142; -pub const ERROR_SAME_DRIVE: DWORD = 143; -pub const ERROR_DIR_NOT_ROOT: DWORD = 144; -pub const ERROR_DIR_NOT_EMPTY: DWORD = 145; -pub const ERROR_IS_SUBST_PATH: DWORD = 146; -pub const ERROR_IS_JOIN_PATH: DWORD = 147; -pub const ERROR_PATH_BUSY: DWORD = 148; -pub const ERROR_IS_SUBST_TARGET: DWORD = 149; -pub const ERROR_SYSTEM_TRACE: DWORD = 150; -pub const ERROR_INVALID_EVENT_COUNT: DWORD = 151; -pub const ERROR_TOO_MANY_MUXWAITERS: DWORD = 152; -pub const ERROR_INVALID_LIST_FORMAT: DWORD = 153; -pub const ERROR_LABEL_TOO_LONG: DWORD = 154; -pub const ERROR_TOO_MANY_TCBS: DWORD = 155; -pub const ERROR_SIGNAL_REFUSED: DWORD = 156; -pub const ERROR_DISCARDED: DWORD = 157; -pub const ERROR_NOT_LOCKED: DWORD = 158; -pub const ERROR_BAD_THREADID_ADDR: DWORD = 159; -pub const ERROR_BAD_ARGUMENTS: DWORD = 160; -pub const ERROR_BAD_PATHNAME: DWORD = 161; -pub const ERROR_SIGNAL_PENDING: DWORD = 162; -pub const ERROR_MAX_THRDS_REACHED: DWORD = 164; -pub const ERROR_LOCK_FAILED: DWORD = 167; -pub const ERROR_BUSY: DWORD = 170; -pub const ERROR_CANCEL_VIOLATION: DWORD = 173; -pub const ERROR_ATOMIC_LOCKS_NOT_SUPPORTED: DWORD = 174; -pub const ERROR_INVALID_SEGMENT_NUMBER: DWORD = 180; -pub const ERROR_INVALID_ORDINAL: DWORD = 182; -pub const ERROR_ALREADY_EXISTS: DWORD = 183; -pub const ERROR_INVALID_FLAG_NUMBER: DWORD = 186; -pub const ERROR_SEM_NOT_FOUND: DWORD = 187; -pub const ERROR_INVALID_STARTING_CODESEG: DWORD = 188; -pub const ERROR_INVALID_STACKSEG: DWORD = 189; -pub const ERROR_INVALID_MODULETYPE: DWORD = 190; -pub const ERROR_INVALID_EXE_SIGNATURE: DWORD = 191; -pub const ERROR_EXE_MARKED_INVALID: DWORD = 192; -pub const ERROR_BAD_EXE_FORMAT: DWORD = 193; -pub const ERROR_ITERATED_DATA_EXCEEDS_64k: DWORD = 194; -pub const ERROR_INVALID_MINALLOCSIZE: DWORD = 195; -pub const ERROR_DYNLINK_FROM_INVALID_RING: DWORD = 196; -pub const ERROR_IOPL_NOT_ENABLED: DWORD = 197; -pub const ERROR_INVALID_SEGDPL: DWORD = 198; -pub const ERROR_AUTODATASEG_EXCEEDS_64k: DWORD = 199; -pub const ERROR_RING2SEG_MUST_BE_MOVABLE: DWORD = 200; -pub const ERROR_RELOC_CHAIN_XEEDS_SEGLIM: DWORD = 201; -pub const ERROR_INFLOOP_IN_RELOC_CHAIN: DWORD = 202; -pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203; -pub const ERROR_NO_SIGNAL_SENT: DWORD = 205; -pub const ERROR_FILENAME_EXCED_RANGE: DWORD = 206; -pub const ERROR_RING2_STACK_IN_USE: DWORD = 207; -pub const ERROR_META_EXPANSION_TOO_LONG: DWORD = 208; -pub const ERROR_INVALID_SIGNAL_NUMBER: DWORD = 209; -pub const ERROR_THREAD_1_INACTIVE: DWORD = 210; -pub const ERROR_LOCKED: DWORD = 212; -pub const ERROR_TOO_MANY_MODULES: DWORD = 214; -pub const ERROR_NESTING_NOT_ALLOWED: DWORD = 215; -pub const ERROR_EXE_MACHINE_TYPE_MISMATCH: DWORD = 216; -pub const ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY: DWORD = 217; -pub const ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY: DWORD = 218; -pub const ERROR_FILE_CHECKED_OUT: DWORD = 220; -pub const ERROR_CHECKOUT_REQUIRED: DWORD = 221; -pub const ERROR_BAD_FILE_TYPE: DWORD = 222; -pub const ERROR_FILE_TOO_LARGE: DWORD = 223; -pub const ERROR_FORMS_AUTH_REQUIRED: DWORD = 224; -pub const ERROR_PIPE_LOCAL: DWORD = 229; -pub const ERROR_BAD_PIPE: DWORD = 230; -pub const ERROR_PIPE_BUSY: DWORD = 231; -pub const ERROR_NO_DATA: DWORD = 232; -pub const ERROR_PIPE_NOT_CONNECTED: DWORD = 233; -pub const ERROR_MORE_DATA: DWORD = 234; -pub const ERROR_VC_DISCONNECTED: DWORD = 240; -pub const ERROR_INVALID_EA_NAME: DWORD = 254; -pub const ERROR_EA_LIST_INCONSISTENT: DWORD = 255; -pub const ERROR_NO_MORE_ITEMS: DWORD = 259; -pub const ERROR_CANNOT_COPY: DWORD = 266; -pub const ERROR_DIRECTORY: DWORD = 267; -pub const ERROR_EAS_DIDNT_FIT: DWORD = 275; -pub const ERROR_EA_FILE_CORRUPT: DWORD = 276; -pub const ERROR_EA_TABLE_FULL: DWORD = 277; -pub const ERROR_INVALID_EA_HANDLE: DWORD = 278; -pub const ERROR_EAS_NOT_SUPPORTED: DWORD = 282; -pub const ERROR_NOT_OWNER: DWORD = 288; -pub const ERROR_TOO_MANY_POSTS: DWORD = 298; -pub const ERROR_PARTIAL_COPY: DWORD = 299; -pub const ERROR_OPLOCK_NOT_GRANTED: DWORD = 300; -pub const ERROR_INVALID_OPLOCK_PROTOCOL: DWORD = 301; -pub const ERROR_DISK_TOO_FRAGMENTED: DWORD = 302; -pub const ERROR_DELETE_PENDING: DWORD = 303; -pub const ERROR_INVALID_TOKEN: DWORD = 315; -pub const ERROR_MR_MID_NOT_FOUND: DWORD = 317; -pub const ERROR_SCOPE_NOT_FOUND: DWORD = 318; -pub const ERROR_INVALID_ADDRESS: DWORD = 487; -pub const ERROR_ARITHMETIC_OVERFLOW: DWORD = 534; -pub const ERROR_PIPE_CONNECTED: DWORD = 535; -pub const ERROR_PIPE_LISTENING: DWORD = 536; -pub const ERROR_WAKE_SYSTEM: DWORD = 730; -pub const ERROR_WAIT_1: DWORD = 731; -pub const ERROR_WAIT_2: DWORD = 732; -pub const ERROR_WAIT_3: DWORD = 733; -pub const ERROR_WAIT_63: DWORD = 734; -pub const ERROR_ABANDONED_WAIT_0: DWORD = 735; -pub const ERROR_ABANDONED_WAIT_63: DWORD = 736; -pub const ERROR_USER_APC: DWORD = 737; -pub const ERROR_KERNEL_APC: DWORD = 738; -pub const ERROR_ALERTED: DWORD = 739; -pub const ERROR_EA_ACCESS_DENIED: DWORD = 994; -pub const ERROR_OPERATION_ABORTED: DWORD = 995; -pub const ERROR_IO_INCOMPLETE: DWORD = 996; -pub const ERROR_IO_PENDING: DWORD = 997; -pub const ERROR_NOACCESS: DWORD = 998; -pub const ERROR_SWAPERROR: DWORD = 999; -pub const ERROR_STACK_OVERFLOW: DWORD = 1001; -pub const ERROR_INVALID_MESSAGE: DWORD = 1002; -pub const ERROR_CAN_NOT_COMPLETE: DWORD = 1003; -pub const ERROR_INVALID_FLAGS: DWORD = 1004; -pub const ERROR_UNRECOGNIZED_VOLUME: DWORD = 1005; -pub const ERROR_FILE_INVALID: DWORD = 1006; -pub const ERROR_FULLSCREEN_MODE: DWORD = 1007; -pub const ERROR_NO_TOKEN: DWORD = 1008; -pub const ERROR_BADDB: DWORD = 1009; -pub const ERROR_BADKEY: DWORD = 1010; -pub const ERROR_CANTOPEN: DWORD = 1011; -pub const ERROR_CANTREAD: DWORD = 1012; -pub const ERROR_CANTWRITE: DWORD = 1013; -pub const ERROR_REGISTRY_RECOVERED: DWORD = 1014; -pub const ERROR_REGISTRY_CORRUPT: DWORD = 1015; -pub const ERROR_REGISTRY_IO_FAILED: DWORD = 1016; -pub const ERROR_NOT_REGISTRY_FILE: DWORD = 1017; -pub const ERROR_KEY_DELETED: DWORD = 1018; -pub const ERROR_NO_LOG_SPACE: DWORD = 1019; -pub const ERROR_KEY_HAS_CHILDREN: DWORD = 1020; -pub const ERROR_CHILD_MUST_BE_VOLATILE: DWORD = 1021; -pub const ERROR_NOTIFY_ENUM_DIR: DWORD = 1022; -pub const ERROR_DEPENDENT_SERVICES_RUNNING: DWORD = 1051; -pub const ERROR_INVALID_SERVICE_CONTROL: DWORD = 1052; -pub const ERROR_SERVICE_REQUEST_TIMEOUT: DWORD = 1053; -pub const ERROR_SERVICE_NO_THREAD: DWORD = 1054; -pub const ERROR_SERVICE_DATABASE_LOCKED: DWORD = 1055; -pub const ERROR_SERVICE_ALREADY_RUNNING: DWORD = 1056; -pub const ERROR_INVALID_SERVICE_ACCOUNT: DWORD = 1057; -pub const ERROR_SERVICE_DISABLED: DWORD = 1058; -pub const ERROR_CIRCULAR_DEPENDENCY: DWORD = 1059; -pub const ERROR_SERVICE_DOES_NOT_EXIST: DWORD = 1060; -pub const ERROR_SERVICE_CANNOT_ACCEPT_CTRL: DWORD = 1061; -pub const ERROR_SERVICE_NOT_ACTIVE: DWORD = 1062; -pub const ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: DWORD = 1063; -pub const ERROR_EXCEPTION_IN_SERVICE: DWORD = 1064; -pub const ERROR_DATABASE_DOES_NOT_EXIST: DWORD = 1065; -pub const ERROR_SERVICE_SPECIFIC_ERROR: DWORD = 1066; -pub const ERROR_PROCESS_ABORTED: DWORD = 1067; -pub const ERROR_SERVICE_DEPENDENCY_FAIL: DWORD = 1068; -pub const ERROR_SERVICE_LOGON_FAILED: DWORD = 1069; -pub const ERROR_SERVICE_START_HANG: DWORD = 1070; -pub const ERROR_INVALID_SERVICE_LOCK: DWORD = 1071; -pub const ERROR_SERVICE_MARKED_FOR_DELETE: DWORD = 1072; -pub const ERROR_SERVICE_EXISTS: DWORD = 1073; -pub const ERROR_ALREADY_RUNNING_LKG: DWORD = 1074; -pub const ERROR_SERVICE_DEPENDENCY_DELETED: DWORD = 1075; -pub const ERROR_BOOT_ALREADY_ACCEPTED: DWORD = 1076; -pub const ERROR_SERVICE_NEVER_STARTED: DWORD = 1077; -pub const ERROR_DUPLICATE_SERVICE_NAME: DWORD = 1078; -pub const ERROR_DIFFERENT_SERVICE_ACCOUNT: DWORD = 1079; -pub const ERROR_CANNOT_DETECT_DRIVER_FAILURE: DWORD = 1080; -pub const ERROR_CANNOT_DETECT_PROCESS_ABORT: DWORD = 1081; -pub const ERROR_NO_RECOVERY_PROGRAM: DWORD = 1082; -pub const ERROR_SERVICE_NOT_IN_EXE: DWORD = 1083; -pub const ERROR_NOT_SAFEBOOT_SERVICE: DWORD = 1084; -pub const ERROR_END_OF_MEDIA: DWORD = 1100; -pub const ERROR_FILEMARK_DETECTED: DWORD = 1101; -pub const ERROR_BEGINNING_OF_MEDIA: DWORD = 1102; -pub const ERROR_SETMARK_DETECTED: DWORD = 1103; -pub const ERROR_NO_DATA_DETECTED: DWORD = 1104; -pub const ERROR_PARTITION_FAILURE: DWORD = 1105; -pub const ERROR_INVALID_BLOCK_LENGTH: DWORD = 1106; -pub const ERROR_DEVICE_NOT_PARTITIONED: DWORD = 1107; -pub const ERROR_UNABLE_TO_LOCK_MEDIA: DWORD = 1108; -pub const ERROR_UNABLE_TO_UNLOAD_MEDIA: DWORD = 1109; -pub const ERROR_MEDIA_CHANGED: DWORD = 1110; -pub const ERROR_BUS_RESET: DWORD = 1111; -pub const ERROR_NO_MEDIA_IN_DRIVE: DWORD = 1112; -pub const ERROR_NO_UNICODE_TRANSLATION: DWORD = 1113; -pub const ERROR_DLL_INIT_FAILED: DWORD = 1114; -pub const ERROR_SHUTDOWN_IN_PROGRESS: DWORD = 1115; -pub const ERROR_NO_SHUTDOWN_IN_PROGRESS: DWORD = 1116; -pub const ERROR_IO_DEVICE: DWORD = 1117; -pub const ERROR_SERIAL_NO_DEVICE: DWORD = 1118; -pub const ERROR_IRQ_BUSY: DWORD = 1119; -pub const ERROR_MORE_WRITES: DWORD = 1120; -pub const ERROR_COUNTER_TIMEOUT: DWORD = 1121; -pub const ERROR_FLOPPY_ID_MARK_NOT_FOUND: DWORD = 1122; -pub const ERROR_FLOPPY_WRONG_CYLINDER: DWORD = 1123; -pub const ERROR_FLOPPY_UNKNOWN_ERROR: DWORD = 1124; -pub const ERROR_FLOPPY_BAD_REGISTERS: DWORD = 1125; -pub const ERROR_DISK_RECALIBRATE_FAILED: DWORD = 1126; -pub const ERROR_DISK_OPERATION_FAILED: DWORD = 1127; -pub const ERROR_DISK_RESET_FAILED: DWORD = 1128; -pub const ERROR_EOM_OVERFLOW: DWORD = 1129; -pub const ERROR_NOT_ENOUGH_SERVER_MEMORY: DWORD = 1130; -pub const ERROR_POSSIBLE_DEADLOCK: DWORD = 1131; -pub const ERROR_MAPPED_ALIGNMENT: DWORD = 1132; -pub const ERROR_SET_POWER_STATE_VETOED: DWORD = 1140; -pub const ERROR_SET_POWER_STATE_FAILED: DWORD = 1141; -pub const ERROR_TOO_MANY_LINKS: DWORD = 1142; -pub const ERROR_OLD_WIN_VERSION: DWORD = 1150; -pub const ERROR_APP_WRONG_OS: DWORD = 1151; -pub const ERROR_SINGLE_INSTANCE_APP: DWORD = 1152; -pub const ERROR_RMODE_APP: DWORD = 1153; -pub const ERROR_INVALID_DLL: DWORD = 1154; -pub const ERROR_NO_ASSOCIATION: DWORD = 1155; -pub const ERROR_DDE_FAIL: DWORD = 1156; -pub const ERROR_DLL_NOT_FOUND: DWORD = 1157; -pub const ERROR_NO_MORE_USER_HANDLES: DWORD = 1158; -pub const ERROR_MESSAGE_SYNC_ONLY: DWORD = 1159; -pub const ERROR_SOURCE_ELEMENT_EMPTY: DWORD = 1160; -pub const ERROR_DESTINATION_ELEMENT_FULL: DWORD = 1161; -pub const ERROR_ILLEGAL_ELEMENT_ADDRESS: DWORD = 1162; -pub const ERROR_MAGAZINE_NOT_PRESENT: DWORD = 1163; -pub const ERROR_DEVICE_REINITIALIZATION_NEEDED: DWORD = 1164; -pub const ERROR_DEVICE_REQUIRES_CLEANING: DWORD = 1165; -pub const ERROR_DEVICE_DOOR_OPEN: DWORD = 1166; -pub const ERROR_DEVICE_NOT_CONNECTED: DWORD = 1167; -pub const ERROR_NOT_FOUND: DWORD = 1168; -pub const ERROR_NO_MATCH: DWORD = 1169; -pub const ERROR_SET_NOT_FOUND: DWORD = 1170; -pub const ERROR_POINT_NOT_FOUND: DWORD = 1171; -pub const ERROR_NO_TRACKING_SERVICE: DWORD = 1172; -pub const ERROR_NO_VOLUME_ID: DWORD = 1173; -pub const ERROR_UNABLE_TO_REMOVE_REPLACED: DWORD = 1175; -pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT: DWORD = 1176; -pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT_2: DWORD = 1177; -pub const ERROR_JOURNAL_DELETE_IN_PROGRESS: DWORD = 1178; -pub const ERROR_JOURNAL_NOT_ACTIVE: DWORD = 1179; -pub const ERROR_POTENTIAL_FILE_FOUND: DWORD = 1180; -pub const ERROR_JOURNAL_ENTRY_DELETED: DWORD = 1181; -pub const ERROR_BAD_DEVICE: DWORD = 1200; -pub const ERROR_CONNECTION_UNAVAIL: DWORD = 1201; -pub const ERROR_DEVICE_ALREADY_REMEMBERED: DWORD = 1202; -pub const ERROR_NO_NET_OR_BAD_PATH: DWORD = 1203; -pub const ERROR_BAD_PROVIDER: DWORD = 1204; -pub const ERROR_CANNOT_OPEN_PROFILE: DWORD = 1205; -pub const ERROR_BAD_PROFILE: DWORD = 1206; -pub const ERROR_NOT_CONTAINER: DWORD = 1207; -pub const ERROR_EXTENDED_ERROR: DWORD = 1208; -pub const ERROR_INVALID_GROUPNAME: DWORD = 1209; -pub const ERROR_INVALID_COMPUTERNAME: DWORD = 1210; -pub const ERROR_INVALID_EVENTNAME: DWORD = 1211; -pub const ERROR_INVALID_DOMAINNAME: DWORD = 1212; -pub const ERROR_INVALID_SERVICENAME: DWORD = 1213; -pub const ERROR_INVALID_NETNAME: DWORD = 1214; -pub const ERROR_INVALID_SHARENAME: DWORD = 1215; -pub const ERROR_INVALID_PASSWORDNAME: DWORD = 1216; -pub const ERROR_INVALID_MESSAGENAME: DWORD = 1217; -pub const ERROR_INVALID_MESSAGEDEST: DWORD = 1218; -pub const ERROR_SESSION_CREDENTIAL_CONFLICT: DWORD = 1219; -pub const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: DWORD = 1220; -pub const ERROR_DUP_DOMAINNAME: DWORD = 1221; -pub const ERROR_NO_NETWORK: DWORD = 1222; -pub const ERROR_CANCELLED: DWORD = 1223; -pub const ERROR_USER_MAPPED_FILE: DWORD = 1224; -pub const ERROR_CONNECTION_REFUSED: DWORD = 1225; -pub const ERROR_GRACEFUL_DISCONNECT: DWORD = 1226; -pub const ERROR_ADDRESS_ALREADY_ASSOCIATED: DWORD = 1227; -pub const ERROR_ADDRESS_NOT_ASSOCIATED: DWORD = 1228; -pub const ERROR_CONNECTION_INVALID: DWORD = 1229; -pub const ERROR_CONNECTION_ACTIVE: DWORD = 1230; -pub const ERROR_NETWORK_UNREACHABLE: DWORD = 1231; -pub const ERROR_HOST_UNREACHABLE: DWORD = 1232; -pub const ERROR_PROTOCOL_UNREACHABLE: DWORD = 1233; -pub const ERROR_PORT_UNREACHABLE: DWORD = 1234; -pub const ERROR_REQUEST_ABORTED: DWORD = 1235; -pub const ERROR_CONNECTION_ABORTED: DWORD = 1236; -pub const ERROR_RETRY: DWORD = 1237; -pub const ERROR_CONNECTION_COUNT_LIMIT: DWORD = 1238; -pub const ERROR_LOGIN_TIME_RESTRICTION: DWORD = 1239; -pub const ERROR_LOGIN_WKSTA_RESTRICTION: DWORD = 1240; -pub const ERROR_INCORRECT_ADDRESS: DWORD = 1241; -pub const ERROR_ALREADY_REGISTERED: DWORD = 1242; -pub const ERROR_SERVICE_NOT_FOUND: DWORD = 1243; -pub const ERROR_NOT_AUTHENTICATED: DWORD = 1244; -pub const ERROR_NOT_LOGGED_ON: DWORD = 1245; -pub const ERROR_CONTINUE: DWORD = 1246; -pub const ERROR_ALREADY_INITIALIZED: DWORD = 1247; -pub const ERROR_NO_MORE_DEVICES: DWORD = 1248; -pub const ERROR_NO_SUCH_SITE: DWORD = 1249; -pub const ERROR_DOMAIN_CONTROLLER_EXISTS: DWORD = 1250; -pub const ERROR_ONLY_IF_CONNECTED: DWORD = 1251; -pub const ERROR_OVERRIDE_NOCHANGES: DWORD = 1252; -pub const ERROR_BAD_USER_PROFILE: DWORD = 1253; -pub const ERROR_NOT_SUPPORTED_ON_SBS: DWORD = 1254; -pub const ERROR_SERVER_SHUTDOWN_IN_PROGRESS: DWORD = 1255; -pub const ERROR_HOST_DOWN: DWORD = 1256; -pub const ERROR_NON_ACCOUNT_SID: DWORD = 1257; -pub const ERROR_NON_DOMAIN_SID: DWORD = 1258; -pub const ERROR_APPHELP_BLOCK: DWORD = 1259; -pub const ERROR_ACCESS_DISABLED_BY_POLICY: DWORD = 1260; -pub const ERROR_REG_NAT_CONSUMPTION: DWORD = 1261; -pub const ERROR_CSCSHARE_OFFLINE: DWORD = 1262; -pub const ERROR_PKINIT_FAILURE: DWORD = 1263; -pub const ERROR_SMARTCARD_SUBSYSTEM_FAILURE: DWORD = 1264; -pub const ERROR_DOWNGRADE_DETECTED: DWORD = 1265; -pub const ERROR_MACHINE_LOCKED: DWORD = 1271; -pub const ERROR_CALLBACK_SUPPLIED_INVALID_DATA: DWORD = 1273; -pub const ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED: DWORD = 1274; -pub const ERROR_DRIVER_BLOCKED: DWORD = 1275; -pub const ERROR_INVALID_IMPORT_OF_NON_DLL: DWORD = 1276; -pub const ERROR_ACCESS_DISABLED_WEBBLADE: DWORD = 1277; -pub const ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER: DWORD = 1278; -pub const ERROR_RECOVERY_FAILURE: DWORD = 1279; -pub const ERROR_ALREADY_FIBER: DWORD = 1280; -pub const ERROR_ALREADY_THREAD: DWORD = 1281; -pub const ERROR_STACK_BUFFER_OVERRUN: DWORD = 1282; -pub const ERROR_PARAMETER_QUOTA_EXCEEDED: DWORD = 1283; -pub const ERROR_DEBUGGER_INACTIVE: DWORD = 1284; -pub const ERROR_DELAY_LOAD_FAILED: DWORD = 1285; -pub const ERROR_VDM_DISALLOWED: DWORD = 1286; -pub const ERROR_UNIDENTIFIED_ERROR: DWORD = 1287; -pub const ERROR_NOT_ALL_ASSIGNED: DWORD = 1300; -pub const ERROR_SOME_NOT_MAPPED: DWORD = 1301; -pub const ERROR_NO_QUOTAS_FOR_ACCOUNT: DWORD = 1302; -pub const ERROR_LOCAL_USER_SESSION_KEY: DWORD = 1303; -pub const ERROR_NULL_LM_PASSWORD: DWORD = 1304; -pub const ERROR_UNKNOWN_REVISION: DWORD = 1305; -pub const ERROR_REVISION_MISMATCH: DWORD = 1306; -pub const ERROR_INVALID_OWNER: DWORD = 1307; -pub const ERROR_INVALID_PRIMARY_GROUP: DWORD = 1308; -pub const ERROR_NO_IMPERSONATION_TOKEN: DWORD = 1309; -pub const ERROR_CANT_DISABLE_MANDATORY: DWORD = 1310; -pub const ERROR_NO_LOGON_SERVERS: DWORD = 1311; -pub const ERROR_NO_SUCH_LOGON_SESSION: DWORD = 1312; -pub const ERROR_NO_SUCH_PRIVILEGE: DWORD = 1313; -pub const ERROR_PRIVILEGE_NOT_HELD: DWORD = 1314; -pub const ERROR_INVALID_ACCOUNT_NAME: DWORD = 1315; -pub const ERROR_USER_EXISTS: DWORD = 1316; -pub const ERROR_NO_SUCH_USER: DWORD = 1317; -pub const ERROR_GROUP_EXISTS: DWORD = 1318; -pub const ERROR_NO_SUCH_GROUP: DWORD = 1319; -pub const ERROR_MEMBER_IN_GROUP: DWORD = 1320; -pub const ERROR_MEMBER_NOT_IN_GROUP: DWORD = 1321; -pub const ERROR_LAST_ADMIN: DWORD = 1322; -pub const ERROR_WRONG_PASSWORD: DWORD = 1323; -pub const ERROR_ILL_FORMED_PASSWORD: DWORD = 1324; -pub const ERROR_PASSWORD_RESTRICTION: DWORD = 1325; -pub const ERROR_LOGON_FAILURE: DWORD = 1326; -pub const ERROR_ACCOUNT_RESTRICTION: DWORD = 1327; -pub const ERROR_INVALID_LOGON_HOURS: DWORD = 1328; -pub const ERROR_INVALID_WORKSTATION: DWORD = 1329; -pub const ERROR_PASSWORD_EXPIRED: DWORD = 1330; -pub const ERROR_ACCOUNT_DISABLED: DWORD = 1331; -pub const ERROR_NONE_MAPPED: DWORD = 1332; -pub const ERROR_TOO_MANY_LUIDS_REQUESTED: DWORD = 1333; -pub const ERROR_LUIDS_EXHAUSTED: DWORD = 1334; -pub const ERROR_INVALID_SUB_AUTHORITY: DWORD = 1335; -pub const ERROR_INVALID_ACL: DWORD = 1336; -pub const ERROR_INVALID_SID: DWORD = 1337; -pub const ERROR_INVALID_SECURITY_DESCR: DWORD = 1338; -pub const ERROR_BAD_INHERITANCE_ACL: DWORD = 1340; -pub const ERROR_SERVER_DISABLED: DWORD = 1341; -pub const ERROR_SERVER_NOT_DISABLED: DWORD = 1342; -pub const ERROR_INVALID_ID_AUTHORITY: DWORD = 1343; -pub const ERROR_ALLOTTED_SPACE_EXCEEDED: DWORD = 1344; -pub const ERROR_INVALID_GROUP_ATTRIBUTES: DWORD = 1345; -pub const ERROR_BAD_IMPERSONATION_LEVEL: DWORD = 1346; -pub const ERROR_CANT_OPEN_ANONYMOUS: DWORD = 1347; -pub const ERROR_BAD_VALIDATION_CLASS: DWORD = 1348; -pub const ERROR_BAD_TOKEN_TYPE: DWORD = 1349; -pub const ERROR_NO_SECURITY_ON_OBJECT: DWORD = 1350; -pub const ERROR_CANT_ACCESS_DOMAIN_INFO: DWORD = 1351; -pub const ERROR_INVALID_SERVER_STATE: DWORD = 1352; -pub const ERROR_INVALID_DOMAIN_STATE: DWORD = 1353; -pub const ERROR_INVALID_DOMAIN_ROLE: DWORD = 1354; -pub const ERROR_NO_SUCH_DOMAIN: DWORD = 1355; -pub const ERROR_DOMAIN_EXISTS: DWORD = 1356; -pub const ERROR_DOMAIN_LIMIT_EXCEEDED: DWORD = 1357; -pub const ERROR_INTERNAL_DB_CORRUPTION: DWORD = 1358; -pub const ERROR_INTERNAL_ERROR: DWORD = 1359; -pub const ERROR_GENERIC_NOT_MAPPED: DWORD = 1360; -pub const ERROR_BAD_DESCRIPTOR_FORMAT: DWORD = 1361; -pub const ERROR_NOT_LOGON_PROCESS: DWORD = 1362; -pub const ERROR_LOGON_SESSION_EXISTS: DWORD = 1363; -pub const ERROR_NO_SUCH_PACKAGE: DWORD = 1364; -pub const ERROR_BAD_LOGON_SESSION_STATE: DWORD = 1365; -pub const ERROR_LOGON_SESSION_COLLISION: DWORD = 1366; -pub const ERROR_INVALID_LOGON_TYPE: DWORD = 1367; -pub const ERROR_CANNOT_IMPERSONATE: DWORD = 1368; -pub const ERROR_RXACT_INVALID_STATE: DWORD = 1369; -pub const ERROR_RXACT_COMMIT_FAILURE: DWORD = 1370; -pub const ERROR_SPECIAL_ACCOUNT: DWORD = 1371; -pub const ERROR_SPECIAL_GROUP: DWORD = 1372; -pub const ERROR_SPECIAL_USER: DWORD = 1373; -pub const ERROR_MEMBERS_PRIMARY_GROUP: DWORD = 1374; -pub const ERROR_TOKEN_ALREADY_IN_USE: DWORD = 1375; -pub const ERROR_NO_SUCH_ALIAS: DWORD = 1376; -pub const ERROR_MEMBER_NOT_IN_ALIAS: DWORD = 1377; -pub const ERROR_MEMBER_IN_ALIAS: DWORD = 1378; -pub const ERROR_ALIAS_EXISTS: DWORD = 1379; -pub const ERROR_LOGON_NOT_GRANTED: DWORD = 1380; -pub const ERROR_TOO_MANY_SECRETS: DWORD = 1381; -pub const ERROR_SECRET_TOO_LONG: DWORD = 1382; -pub const ERROR_INTERNAL_DB_ERROR: DWORD = 1383; -pub const ERROR_TOO_MANY_CONTEXT_IDS: DWORD = 1384; -pub const ERROR_LOGON_TYPE_NOT_GRANTED: DWORD = 1385; -pub const ERROR_NT_CROSS_ENCRYPTION_REQUIRED: DWORD = 1386; -pub const ERROR_NO_SUCH_MEMBER: DWORD = 1387; -pub const ERROR_INVALID_MEMBER: DWORD = 1388; -pub const ERROR_TOO_MANY_SIDS: DWORD = 1389; -pub const ERROR_LM_CROSS_ENCRYPTION_REQUIRED: DWORD = 1390; -pub const ERROR_NO_INHERITANCE: DWORD = 1391; -pub const ERROR_FILE_CORRUPT: DWORD = 1392; -pub const ERROR_DISK_CORRUPT: DWORD = 1393; -pub const ERROR_NO_USER_SESSION_KEY: DWORD = 1394; -pub const ERROR_LICENSE_QUOTA_EXCEEDED: DWORD = 1395; -pub const ERROR_WRONG_TARGET_NAME: DWORD = 1396; -pub const ERROR_MUTUAL_AUTH_FAILED: DWORD = 1397; -pub const ERROR_TIME_SKEW: DWORD = 1398; -pub const ERROR_CURRENT_DOMAIN_NOT_ALLOWED: DWORD = 1399; -pub const ERROR_INVALID_WINDOW_HANDLE: DWORD = 1400; -pub const ERROR_INVALID_MENU_HANDLE: DWORD = 1401; -pub const ERROR_INVALID_CURSOR_HANDLE: DWORD = 1402; -pub const ERROR_INVALID_ACCEL_HANDLE: DWORD = 1403; -pub const ERROR_INVALID_HOOK_HANDLE: DWORD = 1404; -pub const ERROR_INVALID_DWP_HANDLE: DWORD = 1405; -pub const ERROR_TLW_WITH_WSCHILD: DWORD = 1406; -pub const ERROR_CANNOT_FIND_WND_CLASS: DWORD = 1407; -pub const ERROR_WINDOW_OF_OTHER_THREAD: DWORD = 1408; -pub const ERROR_HOTKEY_ALREADY_REGISTERED: DWORD = 1409; -pub const ERROR_CLASS_ALREADY_EXISTS: DWORD = 1410; -pub const ERROR_CLASS_DOES_NOT_EXIST: DWORD = 1411; -pub const ERROR_CLASS_HAS_WINDOWS: DWORD = 1412; -pub const ERROR_INVALID_INDEX: DWORD = 1413; -pub const ERROR_INVALID_ICON_HANDLE: DWORD = 1414; -pub const ERROR_PRIVATE_DIALOG_INDEX: DWORD = 1415; -pub const ERROR_LISTBOX_ID_NOT_FOUND: DWORD = 1416; -pub const ERROR_NO_WILDCARD_CHARACTERS: DWORD = 1417; -pub const ERROR_CLIPBOARD_NOT_OPEN: DWORD = 1418; -pub const ERROR_HOTKEY_NOT_REGISTERED: DWORD = 1419; -pub const ERROR_WINDOW_NOT_DIALOG: DWORD = 1420; -pub const ERROR_CONTROL_ID_NOT_FOUND: DWORD = 1421; -pub const ERROR_INVALID_COMBOBOX_MESSAGE: DWORD = 1422; -pub const ERROR_WINDOW_NOT_COMBOBOX: DWORD = 1423; -pub const ERROR_INVALID_EDIT_HEIGHT: DWORD = 1424; -pub const ERROR_DC_NOT_FOUND: DWORD = 1425; -pub const ERROR_INVALID_HOOK_FILTER: DWORD = 1426; -pub const ERROR_INVALID_FILTER_PROC: DWORD = 1427; -pub const ERROR_HOOK_NEEDS_HMOD: DWORD = 1428; -pub const ERROR_GLOBAL_ONLY_HOOK: DWORD = 1429; -pub const ERROR_JOURNAL_HOOK_SET: DWORD = 1430; -pub const ERROR_HOOK_NOT_INSTALLED: DWORD = 1431; -pub const ERROR_INVALID_LB_MESSAGE: DWORD = 1432; -pub const ERROR_SETCOUNT_ON_BAD_LB: DWORD = 1433; -pub const ERROR_LB_WITHOUT_TABSTOPS: DWORD = 1434; -pub const ERROR_DESTROY_OBJECT_OF_OTHER_THREAD: DWORD = 1435; -pub const ERROR_CHILD_WINDOW_MENU: DWORD = 1436; -pub const ERROR_NO_SYSTEM_MENU: DWORD = 1437; -pub const ERROR_INVALID_MSGBOX_STYLE: DWORD = 1438; -pub const ERROR_INVALID_SPI_VALUE: DWORD = 1439; -pub const ERROR_SCREEN_ALREADY_LOCKED: DWORD = 1440; -pub const ERROR_HWNDS_HAVE_DIFF_PARENT: DWORD = 1441; -pub const ERROR_NOT_CHILD_WINDOW: DWORD = 1442; -pub const ERROR_INVALID_GW_COMMAND: DWORD = 1443; -pub const ERROR_INVALID_THREAD_ID: DWORD = 1444; -pub const ERROR_NON_MDICHILD_WINDOW: DWORD = 1445; -pub const ERROR_POPUP_ALREADY_ACTIVE: DWORD = 1446; -pub const ERROR_NO_SCROLLBARS: DWORD = 1447; -pub const ERROR_INVALID_SCROLLBAR_RANGE: DWORD = 1448; -pub const ERROR_INVALID_SHOWWIN_COMMAND: DWORD = 1449; -pub const ERROR_NO_SYSTEM_RESOURCES: DWORD = 1450; -pub const ERROR_NONPAGED_SYSTEM_RESOURCES: DWORD = 1451; -pub const ERROR_PAGED_SYSTEM_RESOURCES: DWORD = 1452; -pub const ERROR_WORKING_SET_QUOTA: DWORD = 1453; -pub const ERROR_PAGEFILE_QUOTA: DWORD = 1454; -pub const ERROR_COMMITMENT_LIMIT: DWORD = 1455; -pub const ERROR_MENU_ITEM_NOT_FOUND: DWORD = 1456; -pub const ERROR_INVALID_KEYBOARD_HANDLE: DWORD = 1457; -pub const ERROR_HOOK_TYPE_NOT_ALLOWED: DWORD = 1458; -pub const ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION: DWORD = 1459; -pub const ERROR_TIMEOUT: DWORD = 1460; -pub const ERROR_INVALID_MONITOR_HANDLE: DWORD = 1461; -pub const ERROR_INCORRECT_SIZE: DWORD = 1462; -pub const ERROR_SYMLINK_CLASS_DISABLED: DWORD = 1463; -pub const ERROR_SYMLINK_NOT_SUPPORTED: DWORD = 1464; -pub const ERROR_XML_PARSE_ERROR: DWORD = 1465; -pub const ERROR_XMLDSIG_ERROR: DWORD = 1466; -pub const ERROR_RESTART_APPLICATION: DWORD = 1467; -pub const ERROR_WRONG_COMPARTMENT: DWORD = 1468; -pub const ERROR_AUTHIP_FAILURE: DWORD = 1469; -pub const ERROR_NO_NVRAM_RESOURCES: DWORD = 1470; -pub const ERROR_NOT_GUI_PROCESS: DWORD = 1471; -pub const ERROR_EVENTLOG_FILE_CORRUPT: DWORD = 1500; -pub const ERROR_EVENTLOG_CANT_START: DWORD = 1501; -pub const ERROR_LOG_FILE_FULL: DWORD = 1502; -pub const ERROR_EVENTLOG_FILE_CHANGED: DWORD = 1503; -pub const ERROR_INSTALL_SERVICE_FAILURE: DWORD = 1601; -pub const ERROR_INSTALL_USEREXIT: DWORD = 1602; -pub const ERROR_INSTALL_FAILURE: DWORD = 1603; -pub const ERROR_INSTALL_SUSPEND: DWORD = 1604; -pub const ERROR_UNKNOWN_PRODUCT: DWORD = 1605; -pub const ERROR_UNKNOWN_FEATURE: DWORD = 1606; -pub const ERROR_UNKNOWN_COMPONENT: DWORD = 1607; -pub const ERROR_UNKNOWN_PROPERTY: DWORD = 1608; -pub const ERROR_INVALID_HANDLE_STATE: DWORD = 1609; -pub const ERROR_BAD_CONFIGURATION: DWORD = 1610; -pub const ERROR_INDEX_ABSENT: DWORD = 1611; -pub const ERROR_INSTALL_SOURCE_ABSENT: DWORD = 1612; -pub const ERROR_INSTALL_PACKAGE_VERSION: DWORD = 1613; -pub const ERROR_PRODUCT_UNINSTALLED: DWORD = 1614; -pub const ERROR_BAD_QUERY_SYNTAX: DWORD = 1615; -pub const ERROR_INVALID_FIELD: DWORD = 1616; -pub const ERROR_DEVICE_REMOVED: DWORD = 1617; -pub const ERROR_INSTALL_ALREADY_RUNNING: DWORD = 1618; -pub const ERROR_INSTALL_PACKAGE_OPEN_FAILED: DWORD = 1619; -pub const ERROR_INSTALL_PACKAGE_INVALID: DWORD = 1620; -pub const ERROR_INSTALL_UI_FAILURE: DWORD = 1621; -pub const ERROR_INSTALL_LOG_FAILURE: DWORD = 1622; -pub const ERROR_INSTALL_LANGUAGE_UNSUPPORTED: DWORD = 1623; -pub const ERROR_INSTALL_TRANSFORM_FAILURE: DWORD = 1624; -pub const ERROR_INSTALL_PACKAGE_REJECTED: DWORD = 1625; -pub const ERROR_FUNCTION_NOT_CALLED: DWORD = 1626; -pub const ERROR_FUNCTION_FAILED: DWORD = 1627; -pub const ERROR_INVALID_TABLE: DWORD = 1628; -pub const ERROR_DATATYPE_MISMATCH: DWORD = 1629; -pub const ERROR_UNSUPPORTED_TYPE: DWORD = 1630; -pub const ERROR_CREATE_FAILED: DWORD = 1631; -pub const ERROR_INSTALL_TEMP_UNWRITABLE: DWORD = 1632; -pub const ERROR_INSTALL_PLATFORM_UNSUPPORTED: DWORD = 1633; -pub const ERROR_INSTALL_NOTUSED: DWORD = 1634; -pub const ERROR_PATCH_PACKAGE_OPEN_FAILED: DWORD = 1635; -pub const ERROR_PATCH_PACKAGE_INVALID: DWORD = 1636; -pub const ERROR_PATCH_PACKAGE_UNSUPPORTED: DWORD = 1637; -pub const ERROR_PRODUCT_VERSION: DWORD = 1638; -pub const ERROR_INVALID_COMMAND_LINE: DWORD = 1639; -pub const ERROR_INSTALL_REMOTE_DISALLOWED: DWORD = 1640; -pub const ERROR_SUCCESS_REBOOT_INITIATED: DWORD = 1641; -pub const ERROR_PATCH_TARGET_NOT_FOUND: DWORD = 1642; -pub const ERROR_PATCH_PACKAGE_REJECTED: DWORD = 1643; -pub const ERROR_INSTALL_TRANSFORM_REJECTED: DWORD = 1644; -pub const ERROR_INSTALL_REMOTE_PROHIBITED: DWORD = 1645; -pub const ERROR_INVALID_USER_BUFFER: DWORD = 1784; -pub const ERROR_UNRECOGNIZED_MEDIA: DWORD = 1785; -pub const ERROR_NO_TRUST_LSA_SECRET: DWORD = 1786; -pub const ERROR_NO_TRUST_SAM_ACCOUNT: DWORD = 1787; -pub const ERROR_TRUSTED_DOMAIN_FAILURE: DWORD = 1788; -pub const ERROR_TRUSTED_RELATIONSHIP_FAILURE: DWORD = 1789; -pub const ERROR_TRUST_FAILURE: DWORD = 1790; -pub const ERROR_NETLOGON_NOT_STARTED: DWORD = 1792; -pub const ERROR_ACCOUNT_EXPIRED: DWORD = 1793; -pub const ERROR_REDIRECTOR_HAS_OPEN_HANDLES: DWORD = 1794; -pub const ERROR_PRINTER_DRIVER_ALREADY_INSTALLED: DWORD = 1795; -pub const ERROR_UNKNOWN_PORT: DWORD = 1796; -pub const ERROR_UNKNOWN_PRINTER_DRIVER: DWORD = 1797; -pub const ERROR_UNKNOWN_PRINTPROCESSOR: DWORD = 1798; -pub const ERROR_INVALID_SEPARATOR_FILE: DWORD = 1799; -pub const ERROR_INVALID_PRIORITY: DWORD = 1800; -pub const ERROR_INVALID_PRINTER_NAME: DWORD = 1801; -pub const ERROR_PRINTER_ALREADY_EXISTS: DWORD = 1802; -pub const ERROR_INVALID_PRINTER_COMMAND: DWORD = 1803; -pub const ERROR_INVALID_DATATYPE: DWORD = 1804; -pub const ERROR_INVALID_ENVIRONMENT: DWORD = 1805; -pub const ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: DWORD = 1807; -pub const ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT: DWORD = 1808; -pub const ERROR_NOLOGON_SERVER_TRUST_ACCOUNT: DWORD = 1809; -pub const ERROR_DOMAIN_TRUST_INCONSISTENT: DWORD = 1810; -pub const ERROR_SERVER_HAS_OPEN_HANDLES: DWORD = 1811; -pub const ERROR_RESOURCE_DATA_NOT_FOUND: DWORD = 1812; -pub const ERROR_RESOURCE_TYPE_NOT_FOUND: DWORD = 1813; -pub const ERROR_RESOURCE_NAME_NOT_FOUND: DWORD = 1814; -pub const ERROR_RESOURCE_LANG_NOT_FOUND: DWORD = 1815; -pub const ERROR_NOT_ENOUGH_QUOTA: DWORD = 1816; -pub const ERROR_INVALID_TIME: DWORD = 1901; -pub const ERROR_INVALID_FORM_NAME: DWORD = 1902; -pub const ERROR_INVALID_FORM_SIZE: DWORD = 1903; -pub const ERROR_ALREADY_WAITING: DWORD = 1904; -pub const ERROR_PRINTER_DELETED: DWORD = 1905; -pub const ERROR_INVALID_PRINTER_STATE: DWORD = 1906; -pub const ERROR_PASSWORD_MUST_CHANGE: DWORD = 1907; -pub const ERROR_DOMAIN_CONTROLLER_NOT_FOUND: DWORD = 1908; -pub const ERROR_ACCOUNT_LOCKED_OUT: DWORD = 1909; -pub const ERROR_NO_SITENAME: DWORD = 1919; -pub const ERROR_CANT_ACCESS_FILE: DWORD = 1920; -pub const ERROR_CANT_RESOLVE_FILENAME: DWORD = 1921; -pub const ERROR_KM_DRIVER_BLOCKED: DWORD = 1930; -pub const ERROR_CONTEXT_EXPIRED: DWORD = 1931; -pub const ERROR_PER_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1932; -pub const ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1933; -pub const ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED: DWORD = 1934; -pub const ERROR_AUTHENTICATION_FIREWALL_FAILED: DWORD = 1935; -pub const ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED: DWORD = 1936; -pub const ERROR_INVALID_PIXEL_FORMAT: DWORD = 2000; -pub const ERROR_BAD_DRIVER: DWORD = 2001; -pub const ERROR_INVALID_WINDOW_STYLE: DWORD = 2002; -pub const ERROR_METAFILE_NOT_SUPPORTED: DWORD = 2003; -pub const ERROR_TRANSFORM_NOT_SUPPORTED: DWORD = 2004; -pub const ERROR_CLIPPING_NOT_SUPPORTED: DWORD = 2005; -pub const ERROR_INVALID_CMM: DWORD = 2010; -pub const ERROR_INVALID_PROFILE: DWORD = 2011; -pub const ERROR_TAG_NOT_FOUND: DWORD = 2012; -pub const ERROR_TAG_NOT_PRESENT: DWORD = 2013; -pub const ERROR_DUPLICATE_TAG: DWORD = 2014; -pub const ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE: DWORD = 2015; -pub const ERROR_PROFILE_NOT_FOUND: DWORD = 2016; -pub const ERROR_INVALID_COLORSPACE: DWORD = 2017; -pub const ERROR_ICM_NOT_ENABLED: DWORD = 2018; -pub const ERROR_DELETING_ICM_XFORM: DWORD = 2019; -pub const ERROR_INVALID_TRANSFORM: DWORD = 2020; -pub const ERROR_COLORSPACE_MISMATCH: DWORD = 2021; -pub const ERROR_INVALID_COLORINDEX: DWORD = 2022; -pub const ERROR_CONNECTED_OTHER_PASSWORD: DWORD = 2108; -pub const ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT: DWORD = 2109; -pub const ERROR_BAD_USERNAME: DWORD = 2202; -pub const ERROR_NOT_CONNECTED: DWORD = 2250; -pub const ERROR_OPEN_FILES: DWORD = 2401; -pub const ERROR_ACTIVE_CONNECTIONS: DWORD = 2402; -pub const ERROR_DEVICE_IN_USE: DWORD = 2404; -pub const ERROR_UNKNOWN_PRINT_MONITOR: DWORD = 3000; -pub const ERROR_PRINTER_DRIVER_IN_USE: DWORD = 3001; -pub const ERROR_SPOOL_FILE_NOT_FOUND: DWORD = 3002; -pub const ERROR_SPL_NO_STARTDOC: DWORD = 3003; -pub const ERROR_SPL_NO_ADDJOB: DWORD = 3004; -pub const ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED: DWORD = 3005; -pub const ERROR_PRINT_MONITOR_ALREADY_INSTALLED: DWORD = 3006; -pub const ERROR_INVALID_PRINT_MONITOR: DWORD = 3007; -pub const ERROR_PRINT_MONITOR_IN_USE: DWORD = 3008; -pub const ERROR_PRINTER_HAS_JOBS_QUEUED: DWORD = 3009; -pub const ERROR_SUCCESS_REBOOT_REQUIRED: DWORD = 3010; -pub const ERROR_SUCCESS_RESTART_REQUIRED: DWORD = 3011; -pub const ERROR_PRINTER_NOT_FOUND: DWORD = 3012; -pub const ERROR_PRINTER_DRIVER_WARNED: DWORD = 3013; -pub const ERROR_PRINTER_DRIVER_BLOCKED: DWORD = 3014; -pub const ERROR_WINS_INTERNAL: DWORD = 4000; -pub const ERROR_CAN_NOT_DEL_LOCAL_WINS: DWORD = 4001; -pub const ERROR_STATIC_INIT: DWORD = 4002; -pub const ERROR_INC_BACKUP: DWORD = 4003; -pub const ERROR_FULL_BACKUP: DWORD = 4004; -pub const ERROR_REC_NON_EXISTENT: DWORD = 4005; -pub const ERROR_RPL_NOT_ALLOWED: DWORD = 4006; -pub const ERROR_DHCP_ADDRESS_CONFLICT: DWORD = 4100; -pub const ERROR_WMI_GUID_NOT_FOUND: DWORD = 4200; -pub const ERROR_WMI_INSTANCE_NOT_FOUND: DWORD = 4201; -pub const ERROR_WMI_ITEMID_NOT_FOUND: DWORD = 4202; -pub const ERROR_WMI_TRY_AGAIN: DWORD = 4203; -pub const ERROR_WMI_DP_NOT_FOUND: DWORD = 4204; -pub const ERROR_WMI_UNRESOLVED_INSTANCE_REF: DWORD = 4205; -pub const ERROR_WMI_ALREADY_ENABLED: DWORD = 4206; -pub const ERROR_WMI_GUID_DISCONNECTED: DWORD = 4207; -pub const ERROR_WMI_SERVER_UNAVAILABLE: DWORD = 4208; -pub const ERROR_WMI_DP_FAILED: DWORD = 4209; -pub const ERROR_WMI_INVALID_MOF: DWORD = 4210; -pub const ERROR_WMI_INVALID_REGINFO: DWORD = 4211; -pub const ERROR_WMI_ALREADY_DISABLED: DWORD = 4212; -pub const ERROR_WMI_READ_ONLY: DWORD = 4213; -pub const ERROR_WMI_SET_FAILURE: DWORD = 4214; -pub const ERROR_INVALID_MEDIA: DWORD = 4300; -pub const ERROR_INVALID_LIBRARY: DWORD = 4301; -pub const ERROR_INVALID_MEDIA_POOL: DWORD = 4302; -pub const ERROR_DRIVE_MEDIA_MISMATCH: DWORD = 4303; -pub const ERROR_MEDIA_OFFLINE: DWORD = 4304; -pub const ERROR_LIBRARY_OFFLINE: DWORD = 4305; -pub const ERROR_EMPTY: DWORD = 4306; -pub const ERROR_NOT_EMPTY: DWORD = 4307; -pub const ERROR_MEDIA_UNAVAILABLE: DWORD = 4308; -pub const ERROR_RESOURCE_DISABLED: DWORD = 4309; -pub const ERROR_INVALID_CLEANER: DWORD = 4310; -pub const ERROR_UNABLE_TO_CLEAN: DWORD = 4311; -pub const ERROR_OBJECT_NOT_FOUND: DWORD = 4312; -pub const ERROR_DATABASE_FAILURE: DWORD = 4313; -pub const ERROR_DATABASE_FULL: DWORD = 4314; -pub const ERROR_MEDIA_INCOMPATIBLE: DWORD = 4315; -pub const ERROR_RESOURCE_NOT_PRESENT: DWORD = 4316; -pub const ERROR_INVALID_OPERATION: DWORD = 4317; -pub const ERROR_MEDIA_NOT_AVAILABLE: DWORD = 4318; -pub const ERROR_DEVICE_NOT_AVAILABLE: DWORD = 4319; -pub const ERROR_REQUEST_REFUSED: DWORD = 4320; -pub const ERROR_INVALID_DRIVE_OBJECT: DWORD = 4321; -pub const ERROR_LIBRARY_FULL: DWORD = 4322; -pub const ERROR_MEDIUM_NOT_ACCESSIBLE: DWORD = 4323; -pub const ERROR_UNABLE_TO_LOAD_MEDIUM: DWORD = 4324; -pub const ERROR_UNABLE_TO_INVENTORY_DRIVE: DWORD = 4325; -pub const ERROR_UNABLE_TO_INVENTORY_SLOT: DWORD = 4326; -pub const ERROR_UNABLE_TO_INVENTORY_TRANSPORT: DWORD = 4327; -pub const ERROR_TRANSPORT_FULL: DWORD = 4328; -pub const ERROR_CONTROLLING_IEPORT: DWORD = 4329; -pub const ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA: DWORD = 4330; -pub const ERROR_CLEANER_SLOT_SET: DWORD = 4331; -pub const ERROR_CLEANER_SLOT_NOT_SET: DWORD = 4332; -pub const ERROR_CLEANER_CARTRIDGE_SPENT: DWORD = 4333; -pub const ERROR_UNEXPECTED_OMID: DWORD = 4334; -pub const ERROR_CANT_DELETE_LAST_ITEM: DWORD = 4335; -pub const ERROR_MESSAGE_EXCEEDS_MAX_SIZE: DWORD = 4336; -pub const ERROR_VOLUME_CONTAINS_SYS_FILES: DWORD = 4337; -pub const ERROR_INDIGENOUS_TYPE: DWORD = 4338; -pub const ERROR_NO_SUPPORTING_DRIVES: DWORD = 4339; -pub const ERROR_CLEANER_CARTRIDGE_INSTALLED: DWORD = 4340; -pub const ERROR_IEPORT_FULL: DWORD = 4341; -pub const ERROR_FILE_OFFLINE: DWORD = 4350; -pub const ERROR_REMOTE_STORAGE_NOT_ACTIVE: DWORD = 4351; -pub const ERROR_REMOTE_STORAGE_MEDIA_ERROR: DWORD = 4352; -pub const ERROR_NOT_A_REPARSE_POINT: DWORD = 4390; -pub const ERROR_REPARSE_ATTRIBUTE_CONFLICT: DWORD = 4391; -pub const ERROR_INVALID_REPARSE_DATA: DWORD = 4392; -pub const ERROR_REPARSE_TAG_INVALID: DWORD = 4393; -pub const ERROR_REPARSE_TAG_MISMATCH: DWORD = 4394; -pub const ERROR_VOLUME_NOT_SIS_ENABLED: DWORD = 4500; -pub const ERROR_DEPENDENT_RESOURCE_EXISTS: DWORD = 5001; -pub const ERROR_DEPENDENCY_NOT_FOUND: DWORD = 5002; -pub const ERROR_DEPENDENCY_ALREADY_EXISTS: DWORD = 5003; -pub const ERROR_RESOURCE_NOT_ONLINE: DWORD = 5004; -pub const ERROR_HOST_NODE_NOT_AVAILABLE: DWORD = 5005; -pub const ERROR_RESOURCE_NOT_AVAILABLE: DWORD = 5006; -pub const ERROR_RESOURCE_NOT_FOUND: DWORD = 5007; -pub const ERROR_SHUTDOWN_CLUSTER: DWORD = 5008; -pub const ERROR_CANT_EVICT_ACTIVE_NODE: DWORD = 5009; -pub const ERROR_OBJECT_ALREADY_EXISTS: DWORD = 5010; -pub const ERROR_OBJECT_IN_LIST: DWORD = 5011; -pub const ERROR_GROUP_NOT_AVAILABLE: DWORD = 5012; -pub const ERROR_GROUP_NOT_FOUND: DWORD = 5013; -pub const ERROR_GROUP_NOT_ONLINE: DWORD = 5014; -pub const ERROR_HOST_NODE_NOT_RESOURCE_OWNER: DWORD = 5015; -pub const ERROR_HOST_NODE_NOT_GROUP_OWNER: DWORD = 5016; -pub const ERROR_RESMON_CREATE_FAILED: DWORD = 5017; -pub const ERROR_RESMON_ONLINE_FAILED: DWORD = 5018; -pub const ERROR_RESOURCE_ONLINE: DWORD = 5019; -pub const ERROR_QUORUM_RESOURCE: DWORD = 5020; -pub const ERROR_NOT_QUORUM_CAPABLE: DWORD = 5021; -pub const ERROR_CLUSTER_SHUTTING_DOWN: DWORD = 5022; -pub const ERROR_INVALID_STATE: DWORD = 5023; -pub const ERROR_RESOURCE_PROPERTIES_STORED: DWORD = 5024; -pub const ERROR_NOT_QUORUM_CLASS: DWORD = 5025; -pub const ERROR_CORE_RESOURCE: DWORD = 5026; -pub const ERROR_QUORUM_RESOURCE_ONLINE_FAILED: DWORD = 5027; -pub const ERROR_QUORUMLOG_OPEN_FAILED: DWORD = 5028; -pub const ERROR_CLUSTERLOG_CORRUPT: DWORD = 5029; -pub const ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE: DWORD = 5030; -pub const ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE: DWORD = 5031; -pub const ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND: DWORD = 5032; -pub const ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE: DWORD = 5033; -pub const ERROR_QUORUM_OWNER_ALIVE: DWORD = 5034; -pub const ERROR_NETWORK_NOT_AVAILABLE: DWORD = 5035; -pub const ERROR_NODE_NOT_AVAILABLE: DWORD = 5036; -pub const ERROR_ALL_NODES_NOT_AVAILABLE: DWORD = 5037; -pub const ERROR_RESOURCE_FAILED: DWORD = 5038; -pub const ERROR_CLUSTER_INVALID_NODE: DWORD = 5039; -pub const ERROR_CLUSTER_NODE_EXISTS: DWORD = 5040; -pub const ERROR_CLUSTER_JOIN_IN_PROGRESS: DWORD = 5041; -pub const ERROR_CLUSTER_NODE_NOT_FOUND: DWORD = 5042; -pub const ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND: DWORD = 5043; -pub const ERROR_CLUSTER_NETWORK_EXISTS: DWORD = 5044; -pub const ERROR_CLUSTER_NETWORK_NOT_FOUND: DWORD = 5045; -pub const ERROR_CLUSTER_NETINTERFACE_EXISTS: DWORD = 5046; -pub const ERROR_CLUSTER_NETINTERFACE_NOT_FOUND: DWORD = 5047; -pub const ERROR_CLUSTER_INVALID_REQUEST: DWORD = 5048; -pub const ERROR_CLUSTER_INVALID_NETWORK_PROVIDER: DWORD = 5049; -pub const ERROR_CLUSTER_NODE_DOWN: DWORD = 5050; -pub const ERROR_CLUSTER_NODE_UNREACHABLE: DWORD = 5051; -pub const ERROR_CLUSTER_NODE_NOT_MEMBER: DWORD = 5052; -pub const ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS: DWORD = 5053; -pub const ERROR_CLUSTER_INVALID_NETWORK: DWORD = 5054; -pub const ERROR_CLUSTER_NODE_UP: DWORD = 5056; -pub const ERROR_CLUSTER_IPADDR_IN_USE: DWORD = 5057; -pub const ERROR_CLUSTER_NODE_NOT_PAUSED: DWORD = 5058; -pub const ERROR_CLUSTER_NO_SECURITY_CONTEXT: DWORD = 5059; -pub const ERROR_CLUSTER_NETWORK_NOT_INTERNAL: DWORD = 5060; -pub const ERROR_CLUSTER_NODE_ALREADY_UP: DWORD = 5061; -pub const ERROR_CLUSTER_NODE_ALREADY_DOWN: DWORD = 5062; -pub const ERROR_CLUSTER_NETWORK_ALREADY_ONLINE: DWORD = 5063; -pub const ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE: DWORD = 5064; -pub const ERROR_CLUSTER_NODE_ALREADY_MEMBER: DWORD = 5065; -pub const ERROR_CLUSTER_LAST_INTERNAL_NETWORK: DWORD = 5066; -pub const ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS: DWORD = 5067; -pub const ERROR_INVALID_OPERATION_ON_QUORUM: DWORD = 5068; -pub const ERROR_DEPENDENCY_NOT_ALLOWED: DWORD = 5069; -pub const ERROR_CLUSTER_NODE_PAUSED: DWORD = 5070; -pub const ERROR_NODE_CANT_HOST_RESOURCE: DWORD = 5071; -pub const ERROR_CLUSTER_NODE_NOT_READY: DWORD = 5072; -pub const ERROR_CLUSTER_NODE_SHUTTING_DOWN: DWORD = 5073; -pub const ERROR_CLUSTER_JOIN_ABORTED: DWORD = 5074; -pub const ERROR_CLUSTER_INCOMPATIBLE_VERSIONS: DWORD = 5075; -pub const ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED: DWORD = 5076; -pub const ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED: DWORD = 5077; -pub const ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND: DWORD = 5078; -pub const ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED: DWORD = 5079; -pub const ERROR_CLUSTER_RESNAME_NOT_FOUND: DWORD = 5080; -pub const ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED: DWORD = 5081; -pub const ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST: DWORD = 5082; -pub const ERROR_CLUSTER_DATABASE_SEQMISMATCH: DWORD = 5083; -pub const ERROR_RESMON_INVALID_STATE: DWORD = 5084; -pub const ERROR_CLUSTER_GUM_NOT_LOCKER: DWORD = 5085; -pub const ERROR_QUORUM_DISK_NOT_FOUND: DWORD = 5086; -pub const ERROR_DATABASE_BACKUP_CORRUPT: DWORD = 5087; -pub const ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT: DWORD = 5088; -pub const ERROR_RESOURCE_PROPERTY_UNCHANGEABLE: DWORD = 5089; -pub const ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE: DWORD = 5890; -pub const ERROR_CLUSTER_QUORUMLOG_NOT_FOUND: DWORD = 5891; -pub const ERROR_CLUSTER_MEMBERSHIP_HALT: DWORD = 5892; -pub const ERROR_CLUSTER_INSTANCE_ID_MISMATCH: DWORD = 5893; -pub const ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP: DWORD = 5894; -pub const ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH: DWORD = 5895; -pub const ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP: DWORD = 5896; -pub const ERROR_CLUSTER_PARAMETER_MISMATCH: DWORD = 5897; -pub const ERROR_NODE_CANNOT_BE_CLUSTERED: DWORD = 5898; -pub const ERROR_CLUSTER_WRONG_OS_VERSION: DWORD = 5899; -pub const ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME: DWORD = 5900; -pub const ERROR_CLUSCFG_ALREADY_COMMITTED: DWORD = 5901; -pub const ERROR_CLUSCFG_ROLLBACK_FAILED: DWORD = 5902; -pub const ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT: DWORD = 5903; -pub const ERROR_CLUSTER_OLD_VERSION: DWORD = 5904; -pub const ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME: DWORD = 5905; -pub const ERROR_ENCRYPTION_FAILED: DWORD = 6000; -pub const ERROR_DECRYPTION_FAILED: DWORD = 6001; -pub const ERROR_FILE_ENCRYPTED: DWORD = 6002; -pub const ERROR_NO_RECOVERY_POLICY: DWORD = 6003; -pub const ERROR_NO_EFS: DWORD = 6004; -pub const ERROR_WRONG_EFS: DWORD = 6005; -pub const ERROR_NO_USER_KEYS: DWORD = 6006; -pub const ERROR_FILE_NOT_ENCRYPTED: DWORD = 6007; -pub const ERROR_NOT_EXPORT_FORMAT: DWORD = 6008; -pub const ERROR_FILE_READ_ONLY: DWORD = 6009; -pub const ERROR_DIR_EFS_DISALLOWED: DWORD = 6010; -pub const ERROR_EFS_SERVER_NOT_TRUSTED: DWORD = 6011; -pub const ERROR_BAD_RECOVERY_POLICY: DWORD = 6012; -pub const ERROR_EFS_ALG_BLOB_TOO_BIG: DWORD = 6013; -pub const ERROR_VOLUME_NOT_SUPPORT_EFS: DWORD = 6014; -pub const ERROR_EFS_DISABLED: DWORD = 6015; -pub const ERROR_EFS_VERSION_NOT_SUPPORT: DWORD = 6016; -pub const ERROR_NO_BROWSER_SERVERS_FOUND: DWORD = 6118; -pub const ERROR_CTX_WINSTATION_NAME_INVALID: DWORD = 7001; -pub const ERROR_CTX_INVALID_PD: DWORD = 7002; -pub const ERROR_CTX_PD_NOT_FOUND: DWORD = 7003; -pub const ERROR_CTX_WD_NOT_FOUND: DWORD = 7004; -pub const ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY: DWORD = 7005; -pub const ERROR_CTX_SERVICE_NAME_COLLISION: DWORD = 7006; -pub const ERROR_CTX_CLOSE_PENDING: DWORD = 7007; -pub const ERROR_CTX_NO_OUTBUF: DWORD = 7008; -pub const ERROR_CTX_MODEM_INF_NOT_FOUND: DWORD = 7009; -pub const ERROR_CTX_INVALID_MODEMNAME: DWORD = 7010; -pub const ERROR_CTX_MODEM_RESPONSE_ERROR: DWORD = 7011; -pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: DWORD = 7012; -pub const ERROR_CTX_MODEM_RESPONSE_NO_CARRIER: DWORD = 7013; -pub const ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE: DWORD = 7014; -pub const ERROR_CTX_MODEM_RESPONSE_BUSY: DWORD = 7015; -pub const ERROR_CTX_MODEM_RESPONSE_VOICE: DWORD = 7016; -pub const ERROR_CTX_TD_ERROR: DWORD = 7017; -pub const ERROR_CTX_WINSTATION_NOT_FOUND: DWORD = 7022; -pub const ERROR_CTX_WINSTATION_ALREADY_EXISTS: DWORD = 7023; -pub const ERROR_CTX_WINSTATION_BUSY: DWORD = 7024; -pub const ERROR_CTX_BAD_VIDEO_MODE: DWORD = 7025; -pub const ERROR_CTX_GRAPHICS_INVALID: DWORD = 7035; -pub const ERROR_CTX_LOGON_DISABLED: DWORD = 7037; -pub const ERROR_CTX_NOT_CONSOLE: DWORD = 7038; -pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: DWORD = 7040; -pub const ERROR_CTX_CONSOLE_DISCONNECT: DWORD = 7041; -pub const ERROR_CTX_CONSOLE_CONNECT: DWORD = 7042; -pub const ERROR_CTX_SHADOW_DENIED: DWORD = 7044; -pub const ERROR_CTX_WINSTATION_ACCESS_DENIED: DWORD = 7045; -pub const ERROR_CTX_INVALID_WD: DWORD = 7049; -pub const ERROR_CTX_SHADOW_INVALID: DWORD = 7050; -pub const ERROR_CTX_SHADOW_DISABLED: DWORD = 7051; -pub const ERROR_CTX_CLIENT_LICENSE_IN_USE: DWORD = 7052; -pub const ERROR_CTX_CLIENT_LICENSE_NOT_SET: DWORD = 7053; -pub const ERROR_CTX_LICENSE_NOT_AVAILABLE: DWORD = 7054; -pub const ERROR_CTX_LICENSE_CLIENT_INVALID: DWORD = 7055; -pub const ERROR_CTX_LICENSE_EXPIRED: DWORD = 7056; -pub const ERROR_CTX_SHADOW_NOT_RUNNING: DWORD = 7057; -pub const ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE: DWORD = 7058; -pub const ERROR_ACTIVATION_COUNT_EXCEEDED: DWORD = 7059; -pub const ERROR_DS_NOT_INSTALLED: DWORD = 8200; -pub const ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY: DWORD = 8201; -pub const ERROR_DS_NO_ATTRIBUTE_OR_VALUE: DWORD = 8202; -pub const ERROR_DS_INVALID_ATTRIBUTE_SYNTAX: DWORD = 8203; -pub const ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED: DWORD = 8204; -pub const ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS: DWORD = 8205; -pub const ERROR_DS_BUSY: DWORD = 8206; -pub const ERROR_DS_UNAVAILABLE: DWORD = 8207; -pub const ERROR_DS_NO_RIDS_ALLOCATED: DWORD = 8208; -pub const ERROR_DS_NO_MORE_RIDS: DWORD = 8209; -pub const ERROR_DS_INCORRECT_ROLE_OWNER: DWORD = 8210; -pub const ERROR_DS_RIDMGR_INIT_ERROR: DWORD = 8211; -pub const ERROR_DS_OBJ_CLASS_VIOLATION: DWORD = 8212; -pub const ERROR_DS_CANT_ON_NON_LEAF: DWORD = 8213; -pub const ERROR_DS_CANT_ON_RDN: DWORD = 8214; -pub const ERROR_DS_CANT_MOD_OBJ_CLASS: DWORD = 8215; -pub const ERROR_DS_CROSS_DOM_MOVE_ERROR: DWORD = 8216; -pub const ERROR_DS_GC_NOT_AVAILABLE: DWORD = 8217; -pub const ERROR_SHARED_POLICY: DWORD = 8218; -pub const ERROR_POLICY_OBJECT_NOT_FOUND: DWORD = 8219; -pub const ERROR_POLICY_ONLY_IN_DS: DWORD = 8220; -pub const ERROR_PROMOTION_ACTIVE: DWORD = 8221; -pub const ERROR_NO_PROMOTION_ACTIVE: DWORD = 8222; -pub const ERROR_DS_OPERATIONS_ERROR: DWORD = 8224; -pub const ERROR_DS_PROTOCOL_ERROR: DWORD = 8225; -pub const ERROR_DS_TIMELIMIT_EXCEEDED: DWORD = 8226; -pub const ERROR_DS_SIZELIMIT_EXCEEDED: DWORD = 8227; -pub const ERROR_DS_ADMIN_LIMIT_EXCEEDED: DWORD = 8228; -pub const ERROR_DS_COMPARE_FALSE: DWORD = 8229; -pub const ERROR_DS_COMPARE_TRUE: DWORD = 8230; -pub const ERROR_DS_AUTH_METHOD_NOT_SUPPORTED: DWORD = 8231; -pub const ERROR_DS_STRONG_AUTH_REQUIRED: DWORD = 8232; -pub const ERROR_DS_INAPPROPRIATE_AUTH: DWORD = 8233; -pub const ERROR_DS_AUTH_UNKNOWN: DWORD = 8234; -pub const ERROR_DS_REFERRAL: DWORD = 8235; -pub const ERROR_DS_UNAVAILABLE_CRIT_EXTENSION: DWORD = 8236; -pub const ERROR_DS_CONFIDENTIALITY_REQUIRED: DWORD = 8237; -pub const ERROR_DS_INAPPROPRIATE_MATCHING: DWORD = 8238; -pub const ERROR_DS_CONSTRAINT_VIOLATION: DWORD = 8239; -pub const ERROR_DS_NO_SUCH_OBJECT: DWORD = 8240; -pub const ERROR_DS_ALIAS_PROBLEM: DWORD = 8241; -pub const ERROR_DS_INVALID_DN_SYNTAX: DWORD = 8242; -pub const ERROR_DS_IS_LEAF: DWORD = 8243; -pub const ERROR_DS_ALIAS_DEREF_PROBLEM: DWORD = 8244; -pub const ERROR_DS_UNWILLING_TO_PERFORM: DWORD = 8245; -pub const ERROR_DS_LOOP_DETECT: DWORD = 8246; -pub const ERROR_DS_NAMING_VIOLATION: DWORD = 8247; -pub const ERROR_DS_OBJECT_RESULTS_TOO_LARGE: DWORD = 8248; -pub const ERROR_DS_AFFECTS_MULTIPLE_DSAS: DWORD = 8249; -pub const ERROR_DS_SERVER_DOWN: DWORD = 8250; -pub const ERROR_DS_LOCAL_ERROR: DWORD = 8251; -pub const ERROR_DS_ENCODING_ERROR: DWORD = 8252; -pub const ERROR_DS_DECODING_ERROR: DWORD = 8253; -pub const ERROR_DS_FILTER_UNKNOWN: DWORD = 8254; -pub const ERROR_DS_PARAM_ERROR: DWORD = 8255; -pub const ERROR_DS_NOT_SUPPORTED: DWORD = 8256; -pub const ERROR_DS_NO_RESULTS_RETURNED: DWORD = 8257; -pub const ERROR_DS_CONTROL_NOT_FOUND: DWORD = 8258; -pub const ERROR_DS_CLIENT_LOOP: DWORD = 8259; -pub const ERROR_DS_REFERRAL_LIMIT_EXCEEDED: DWORD = 8260; -pub const ERROR_DS_SORT_CONTROL_MISSING: DWORD = 8261; -pub const ERROR_DS_OFFSET_RANGE_ERROR: DWORD = 8262; -pub const ERROR_DS_ROOT_MUST_BE_NC: DWORD = 8301; -pub const ERROR_DS_ADD_REPLICA_INHIBITED: DWORD = 8302; -pub const ERROR_DS_ATT_NOT_DEF_IN_SCHEMA: DWORD = 8303; -pub const ERROR_DS_MAX_OBJ_SIZE_EXCEEDED: DWORD = 8304; -pub const ERROR_DS_OBJ_STRING_NAME_EXISTS: DWORD = 8305; -pub const ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA: DWORD = 8306; -pub const ERROR_DS_RDN_DOESNT_MATCH_SCHEMA: DWORD = 8307; -pub const ERROR_DS_NO_REQUESTED_ATTS_FOUND: DWORD = 8308; -pub const ERROR_DS_USER_BUFFER_TO_SMALL: DWORD = 8309; -pub const ERROR_DS_ATT_IS_NOT_ON_OBJ: DWORD = 8310; -pub const ERROR_DS_ILLEGAL_MOD_OPERATION: DWORD = 8311; -pub const ERROR_DS_OBJ_TOO_LARGE: DWORD = 8312; -pub const ERROR_DS_BAD_INSTANCE_TYPE: DWORD = 8313; -pub const ERROR_DS_MASTERDSA_REQUIRED: DWORD = 8314; -pub const ERROR_DS_OBJECT_CLASS_REQUIRED: DWORD = 8315; -pub const ERROR_DS_MISSING_REQUIRED_ATT: DWORD = 8316; -pub const ERROR_DS_ATT_NOT_DEF_FOR_CLASS: DWORD = 8317; -pub const ERROR_DS_ATT_ALREADY_EXISTS: DWORD = 8318; -pub const ERROR_DS_CANT_ADD_ATT_VALUES: DWORD = 8320; -pub const ERROR_DS_SINGLE_VALUE_CONSTRAINT: DWORD = 8321; -pub const ERROR_DS_RANGE_CONSTRAINT: DWORD = 8322; -pub const ERROR_DS_ATT_VAL_ALREADY_EXISTS: DWORD = 8323; -pub const ERROR_DS_CANT_REM_MISSING_ATT: DWORD = 8324; -pub const ERROR_DS_CANT_REM_MISSING_ATT_VAL: DWORD = 8325; -pub const ERROR_DS_ROOT_CANT_BE_SUBREF: DWORD = 8326; -pub const ERROR_DS_NO_CHAINING: DWORD = 8327; -pub const ERROR_DS_NO_CHAINED_EVAL: DWORD = 8328; -pub const ERROR_DS_NO_PARENT_OBJECT: DWORD = 8329; -pub const ERROR_DS_PARENT_IS_AN_ALIAS: DWORD = 8330; -pub const ERROR_DS_CANT_MIX_MASTER_AND_REPS: DWORD = 8331; -pub const ERROR_DS_CHILDREN_EXIST: DWORD = 8332; -pub const ERROR_DS_OBJ_NOT_FOUND: DWORD = 8333; -pub const ERROR_DS_ALIASED_OBJ_MISSING: DWORD = 8334; -pub const ERROR_DS_BAD_NAME_SYNTAX: DWORD = 8335; -pub const ERROR_DS_ALIAS_POINTS_TO_ALIAS: DWORD = 8336; -pub const ERROR_DS_CANT_DEREF_ALIAS: DWORD = 8337; -pub const ERROR_DS_OUT_OF_SCOPE: DWORD = 8338; -pub const ERROR_DS_OBJECT_BEING_REMOVED: DWORD = 8339; -pub const ERROR_DS_CANT_DELETE_DSA_OBJ: DWORD = 8340; -pub const ERROR_DS_GENERIC_ERROR: DWORD = 8341; -pub const ERROR_DS_DSA_MUST_BE_INT_MASTER: DWORD = 8342; -pub const ERROR_DS_CLASS_NOT_DSA: DWORD = 8343; -pub const ERROR_DS_INSUFF_ACCESS_RIGHTS: DWORD = 8344; -pub const ERROR_DS_ILLEGAL_SUPERIOR: DWORD = 8345; -pub const ERROR_DS_ATTRIBUTE_OWNED_BY_SAM: DWORD = 8346; -pub const ERROR_DS_NAME_TOO_MANY_PARTS: DWORD = 8347; -pub const ERROR_DS_NAME_TOO_LONG: DWORD = 8348; -pub const ERROR_DS_NAME_VALUE_TOO_LONG: DWORD = 8349; -pub const ERROR_DS_NAME_UNPARSEABLE: DWORD = 8350; -pub const ERROR_DS_NAME_TYPE_UNKNOWN: DWORD = 8351; -pub const ERROR_DS_NOT_AN_OBJECT: DWORD = 8352; -pub const ERROR_DS_SEC_DESC_TOO_SHORT: DWORD = 8353; -pub const ERROR_DS_SEC_DESC_INVALID: DWORD = 8354; -pub const ERROR_DS_NO_DELETED_NAME: DWORD = 8355; -pub const ERROR_DS_SUBREF_MUST_HAVE_PARENT: DWORD = 8356; -pub const ERROR_DS_NCNAME_MUST_BE_NC: DWORD = 8357; -pub const ERROR_DS_CANT_ADD_SYSTEM_ONLY: DWORD = 8358; -pub const ERROR_DS_CLASS_MUST_BE_CONCRETE: DWORD = 8359; -pub const ERROR_DS_INVALID_DMD: DWORD = 8360; -pub const ERROR_DS_OBJ_GUID_EXISTS: DWORD = 8361; -pub const ERROR_DS_NOT_ON_BACKLINK: DWORD = 8362; -pub const ERROR_DS_NO_CROSSREF_FOR_NC: DWORD = 8363; -pub const ERROR_DS_SHUTTING_DOWN: DWORD = 8364; -pub const ERROR_DS_UNKNOWN_OPERATION: DWORD = 8365; -pub const ERROR_DS_INVALID_ROLE_OWNER: DWORD = 8366; -pub const ERROR_DS_COULDNT_CONTACT_FSMO: DWORD = 8367; -pub const ERROR_DS_CROSS_NC_DN_RENAME: DWORD = 8368; -pub const ERROR_DS_CANT_MOD_SYSTEM_ONLY: DWORD = 8369; -pub const ERROR_DS_REPLICATOR_ONLY: DWORD = 8370; -pub const ERROR_DS_OBJ_CLASS_NOT_DEFINED: DWORD = 8371; -pub const ERROR_DS_OBJ_CLASS_NOT_SUBCLASS: DWORD = 8372; -pub const ERROR_DS_NAME_REFERENCE_INVALID: DWORD = 8373; -pub const ERROR_DS_CROSS_REF_EXISTS: DWORD = 8374; -pub const ERROR_DS_CANT_DEL_MASTER_CROSSREF: DWORD = 8375; -pub const ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD: DWORD = 8376; -pub const ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX: DWORD = 8377; -pub const ERROR_DS_DUP_RDN: DWORD = 8378; -pub const ERROR_DS_DUP_OID: DWORD = 8379; -pub const ERROR_DS_DUP_MAPI_ID: DWORD = 8380; -pub const ERROR_DS_DUP_SCHEMA_ID_GUID: DWORD = 8381; -pub const ERROR_DS_DUP_LDAP_DISPLAY_NAME: DWORD = 8382; -pub const ERROR_DS_SEMANTIC_ATT_TEST: DWORD = 8383; -pub const ERROR_DS_SYNTAX_MISMATCH: DWORD = 8384; -pub const ERROR_DS_EXISTS_IN_MUST_HAVE: DWORD = 8385; -pub const ERROR_DS_EXISTS_IN_MAY_HAVE: DWORD = 8386; -pub const ERROR_DS_NONEXISTENT_MAY_HAVE: DWORD = 8387; -pub const ERROR_DS_NONEXISTENT_MUST_HAVE: DWORD = 8388; -pub const ERROR_DS_AUX_CLS_TEST_FAIL: DWORD = 8389; -pub const ERROR_DS_NONEXISTENT_POSS_SUP: DWORD = 8390; -pub const ERROR_DS_SUB_CLS_TEST_FAIL: DWORD = 8391; -pub const ERROR_DS_BAD_RDN_ATT_ID_SYNTAX: DWORD = 8392; -pub const ERROR_DS_EXISTS_IN_AUX_CLS: DWORD = 8393; -pub const ERROR_DS_EXISTS_IN_SUB_CLS: DWORD = 8394; -pub const ERROR_DS_EXISTS_IN_POSS_SUP: DWORD = 8395; -pub const ERROR_DS_RECALCSCHEMA_FAILED: DWORD = 8396; -pub const ERROR_DS_TREE_DELETE_NOT_FINISHED: DWORD = 8397; -pub const ERROR_DS_CANT_DELETE: DWORD = 8398; -pub const ERROR_DS_ATT_SCHEMA_REQ_ID: DWORD = 8399; -pub const ERROR_DS_BAD_ATT_SCHEMA_SYNTAX: DWORD = 8400; -pub const ERROR_DS_CANT_CACHE_ATT: DWORD = 8401; -pub const ERROR_DS_CANT_CACHE_CLASS: DWORD = 8402; -pub const ERROR_DS_CANT_REMOVE_ATT_CACHE: DWORD = 8403; -pub const ERROR_DS_CANT_REMOVE_CLASS_CACHE: DWORD = 8404; -pub const ERROR_DS_CANT_RETRIEVE_DN: DWORD = 8405; -pub const ERROR_DS_MISSING_SUPREF: DWORD = 8406; -pub const ERROR_DS_CANT_RETRIEVE_INSTANCE: DWORD = 8407; -pub const ERROR_DS_CODE_INCONSISTENCY: DWORD = 8408; -pub const ERROR_DS_DATABASE_ERROR: DWORD = 8409; -pub const ERROR_DS_GOVERNSID_MISSING: DWORD = 8410; -pub const ERROR_DS_MISSING_EXPECTED_ATT: DWORD = 8411; -pub const ERROR_DS_NCNAME_MISSING_CR_REF: DWORD = 8412; -pub const ERROR_DS_SECURITY_CHECKING_ERROR: DWORD = 8413; -pub const ERROR_DS_SCHEMA_NOT_LOADED: DWORD = 8414; -pub const ERROR_DS_SCHEMA_ALLOC_FAILED: DWORD = 8415; -pub const ERROR_DS_ATT_SCHEMA_REQ_SYNTAX: DWORD = 8416; -pub const ERROR_DS_GCVERIFY_ERROR: DWORD = 8417; -pub const ERROR_DS_DRA_SCHEMA_MISMATCH: DWORD = 8418; -pub const ERROR_DS_CANT_FIND_DSA_OBJ: DWORD = 8419; -pub const ERROR_DS_CANT_FIND_EXPECTED_NC: DWORD = 8420; -pub const ERROR_DS_CANT_FIND_NC_IN_CACHE: DWORD = 8421; -pub const ERROR_DS_CANT_RETRIEVE_CHILD: DWORD = 8422; -pub const ERROR_DS_SECURITY_ILLEGAL_MODIFY: DWORD = 8423; -pub const ERROR_DS_CANT_REPLACE_HIDDEN_REC: DWORD = 8424; -pub const ERROR_DS_BAD_HIERARCHY_FILE: DWORD = 8425; -pub const ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED: DWORD = 8426; -pub const ERROR_DS_CONFIG_PARAM_MISSING: DWORD = 8427; -pub const ERROR_DS_COUNTING_AB_INDICES_FAILED: DWORD = 8428; -pub const ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED: DWORD = 8429; -pub const ERROR_DS_INTERNAL_FAILURE: DWORD = 8430; -pub const ERROR_DS_UNKNOWN_ERROR: DWORD = 8431; -pub const ERROR_DS_ROOT_REQUIRES_CLASS_TOP: DWORD = 8432; -pub const ERROR_DS_REFUSING_FSMO_ROLES: DWORD = 8433; -pub const ERROR_DS_MISSING_FSMO_SETTINGS: DWORD = 8434; -pub const ERROR_DS_UNABLE_TO_SURRENDER_ROLES: DWORD = 8435; -pub const ERROR_DS_DRA_GENERIC: DWORD = 8436; -pub const ERROR_DS_DRA_INVALID_PARAMETER: DWORD = 8437; -pub const ERROR_DS_DRA_BUSY: DWORD = 8438; -pub const ERROR_DS_DRA_BAD_DN: DWORD = 8439; -pub const ERROR_DS_DRA_BAD_NC: DWORD = 8440; -pub const ERROR_DS_DRA_DN_EXISTS: DWORD = 8441; -pub const ERROR_DS_DRA_INTERNAL_ERROR: DWORD = 8442; -pub const ERROR_DS_DRA_INCONSISTENT_DIT: DWORD = 8443; -pub const ERROR_DS_DRA_CONNECTION_FAILED: DWORD = 8444; -pub const ERROR_DS_DRA_BAD_INSTANCE_TYPE: DWORD = 8445; -pub const ERROR_DS_DRA_OUT_OF_MEM: DWORD = 8446; -pub const ERROR_DS_DRA_MAIL_PROBLEM: DWORD = 8447; -pub const ERROR_DS_DRA_REF_ALREADY_EXISTS: DWORD = 8448; -pub const ERROR_DS_DRA_REF_NOT_FOUND: DWORD = 8449; -pub const ERROR_DS_DRA_OBJ_IS_REP_SOURCE: DWORD = 8450; -pub const ERROR_DS_DRA_DB_ERROR: DWORD = 8451; -pub const ERROR_DS_DRA_NO_REPLICA: DWORD = 8452; -pub const ERROR_DS_DRA_ACCESS_DENIED: DWORD = 8453; -pub const ERROR_DS_DRA_NOT_SUPPORTED: DWORD = 8454; -pub const ERROR_DS_DRA_RPC_CANCELLED: DWORD = 8455; -pub const ERROR_DS_DRA_SOURCE_DISABLED: DWORD = 8456; -pub const ERROR_DS_DRA_SINK_DISABLED: DWORD = 8457; -pub const ERROR_DS_DRA_NAME_COLLISION: DWORD = 8458; -pub const ERROR_DS_DRA_SOURCE_REINSTALLED: DWORD = 8459; -pub const ERROR_DS_DRA_MISSING_PARENT: DWORD = 8460; -pub const ERROR_DS_DRA_PREEMPTED: DWORD = 8461; -pub const ERROR_DS_DRA_ABANDON_SYNC: DWORD = 8462; -pub const ERROR_DS_DRA_SHUTDOWN: DWORD = 8463; -pub const ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET: DWORD = 8464; -pub const ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA: DWORD = 8465; -pub const ERROR_DS_DRA_EXTN_CONNECTION_FAILED: DWORD = 8466; -pub const ERROR_DS_INSTALL_SCHEMA_MISMATCH: DWORD = 8467; -pub const ERROR_DS_DUP_LINK_ID: DWORD = 8468; -pub const ERROR_DS_NAME_ERROR_RESOLVING: DWORD = 8469; -pub const ERROR_DS_NAME_ERROR_NOT_FOUND: DWORD = 8470; -pub const ERROR_DS_NAME_ERROR_NOT_UNIQUE: DWORD = 8471; -pub const ERROR_DS_NAME_ERROR_NO_MAPPING: DWORD = 8472; -pub const ERROR_DS_NAME_ERROR_DOMAIN_ONLY: DWORD = 8473; -pub const ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING: DWORD = 8474; -pub const ERROR_DS_CONSTRUCTED_ATT_MOD: DWORD = 8475; -pub const ERROR_DS_WRONG_OM_OBJ_CLASS: DWORD = 8476; -pub const ERROR_DS_DRA_REPL_PENDING: DWORD = 8477; -pub const ERROR_DS_DS_REQUIRED: DWORD = 8478; -pub const ERROR_DS_INVALID_LDAP_DISPLAY_NAME: DWORD = 8479; -pub const ERROR_DS_NON_BASE_SEARCH: DWORD = 8480; -pub const ERROR_DS_CANT_RETRIEVE_ATTS: DWORD = 8481; -pub const ERROR_DS_BACKLINK_WITHOUT_LINK: DWORD = 8482; -pub const ERROR_DS_EPOCH_MISMATCH: DWORD = 8483; -pub const ERROR_DS_SRC_NAME_MISMATCH: DWORD = 8484; -pub const ERROR_DS_SRC_AND_DST_NC_IDENTICAL: DWORD = 8485; -pub const ERROR_DS_DST_NC_MISMATCH: DWORD = 8486; -pub const ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC: DWORD = 8487; -pub const ERROR_DS_SRC_GUID_MISMATCH: DWORD = 8488; -pub const ERROR_DS_CANT_MOVE_DELETED_OBJECT: DWORD = 8489; -pub const ERROR_DS_PDC_OPERATION_IN_PROGRESS: DWORD = 8490; -pub const ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD: DWORD = 8491; -pub const ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION: DWORD = 8492; -pub const ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS: DWORD = 8493; -pub const ERROR_DS_NC_MUST_HAVE_NC_PARENT: DWORD = 8494; -pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE: DWORD = 8495; -pub const ERROR_DS_DST_DOMAIN_NOT_NATIVE: DWORD = 8496; -pub const ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER: DWORD = 8497; -pub const ERROR_DS_CANT_MOVE_ACCOUNT_GROUP: DWORD = 8498; -pub const ERROR_DS_CANT_MOVE_RESOURCE_GROUP: DWORD = 8499; -pub const ERROR_DS_INVALID_SEARCH_FLAG: DWORD = 8500; -pub const ERROR_DS_NO_TREE_DELETE_ABOVE_NC: DWORD = 8501; -pub const ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE: DWORD = 8502; -pub const ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE: DWORD = 8503; -pub const ERROR_DS_SAM_INIT_FAILURE: DWORD = 8504; -pub const ERROR_DS_SENSITIVE_GROUP_VIOLATION: DWORD = 8505; -pub const ERROR_DS_CANT_MOD_PRIMARYGROUPID: DWORD = 8506; -pub const ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD: DWORD = 8507; -pub const ERROR_DS_NONSAFE_SCHEMA_CHANGE: DWORD = 8508; -pub const ERROR_DS_SCHEMA_UPDATE_DISALLOWED: DWORD = 8509; -pub const ERROR_DS_CANT_CREATE_UNDER_SCHEMA: DWORD = 8510; -pub const ERROR_DS_INSTALL_NO_SRC_SCH_VERSION: DWORD = 8511; -pub const ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE: DWORD = 8512; -pub const ERROR_DS_INVALID_GROUP_TYPE: DWORD = 8513; -pub const ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: DWORD = 8514; -pub const ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: DWORD = 8515; -pub const ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8516; -pub const ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8517; -pub const ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8518; -pub const ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: DWORD = 8519; -pub const ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: DWORD = 8520; -pub const ERROR_DS_HAVE_PRIMARY_MEMBERS: DWORD = 8521; -pub const ERROR_DS_STRING_SD_CONVERSION_FAILED: DWORD = 8522; -pub const ERROR_DS_NAMING_MASTER_GC: DWORD = 8523; -pub const ERROR_DS_DNS_LOOKUP_FAILURE: DWORD = 8524; -pub const ERROR_DS_COULDNT_UPDATE_SPNS: DWORD = 8525; -pub const ERROR_DS_CANT_RETRIEVE_SD: DWORD = 8526; -pub const ERROR_DS_KEY_NOT_UNIQUE: DWORD = 8527; -pub const ERROR_DS_WRONG_LINKED_ATT_SYNTAX: DWORD = 8528; -pub const ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD: DWORD = 8529; -pub const ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY: DWORD = 8530; -pub const ERROR_DS_CANT_START: DWORD = 8531; -pub const ERROR_DS_INIT_FAILURE: DWORD = 8532; -pub const ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION: DWORD = 8533; -pub const ERROR_DS_SOURCE_DOMAIN_IN_FOREST: DWORD = 8534; -pub const ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST: DWORD = 8535; -pub const ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED: DWORD = 8536; -pub const ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN: DWORD = 8537; -pub const ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER: DWORD = 8538; -pub const ERROR_DS_SRC_SID_EXISTS_IN_FOREST: DWORD = 8539; -pub const ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH: DWORD = 8540; -pub const ERROR_SAM_INIT_FAILURE: DWORD = 8541; -pub const ERROR_DS_DRA_SCHEMA_INFO_SHIP: DWORD = 8542; -pub const ERROR_DS_DRA_SCHEMA_CONFLICT: DWORD = 8543; -pub const ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT: DWORD = 8544; -pub const ERROR_DS_DRA_OBJ_NC_MISMATCH: DWORD = 8545; -pub const ERROR_DS_NC_STILL_HAS_DSAS: DWORD = 8546; -pub const ERROR_DS_GC_REQUIRED: DWORD = 8547; -pub const ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: DWORD = 8548; -pub const ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS: DWORD = 8549; -pub const ERROR_DS_CANT_ADD_TO_GC: DWORD = 8550; -pub const ERROR_DS_NO_CHECKPOINT_WITH_PDC: DWORD = 8551; -pub const ERROR_DS_SOURCE_AUDITING_NOT_ENABLED: DWORD = 8552; -pub const ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC: DWORD = 8553; -pub const ERROR_DS_INVALID_NAME_FOR_SPN: DWORD = 8554; -pub const ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS: DWORD = 8555; -pub const ERROR_DS_UNICODEPWD_NOT_IN_QUOTES: DWORD = 8556; -pub const ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: DWORD = 8557; -pub const ERROR_DS_MUST_BE_RUN_ON_DST_DC: DWORD = 8558; -pub const ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER: DWORD = 8559; -pub const ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ: DWORD = 8560; -pub const ERROR_DS_INIT_FAILURE_CONSOLE: DWORD = 8561; -pub const ERROR_DS_SAM_INIT_FAILURE_CONSOLE: DWORD = 8562; -pub const ERROR_DS_FOREST_VERSION_TOO_HIGH: DWORD = 8563; -pub const ERROR_DS_DOMAIN_VERSION_TOO_HIGH: DWORD = 8564; -pub const ERROR_DS_FOREST_VERSION_TOO_LOW: DWORD = 8565; -pub const ERROR_DS_DOMAIN_VERSION_TOO_LOW: DWORD = 8566; -pub const ERROR_DS_INCOMPATIBLE_VERSION: DWORD = 8567; -pub const ERROR_DS_LOW_DSA_VERSION: DWORD = 8568; -pub const ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN: DWORD = 8569; -pub const ERROR_DS_NOT_SUPPORTED_SORT_ORDER: DWORD = 8570; -pub const ERROR_DS_NAME_NOT_UNIQUE: DWORD = 8571; -pub const ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4: DWORD = 8572; -pub const ERROR_DS_OUT_OF_VERSION_STORE: DWORD = 8573; -pub const ERROR_DS_INCOMPATIBLE_CONTROLS_USED: DWORD = 8574; -pub const ERROR_DS_NO_REF_DOMAIN: DWORD = 8575; -pub const ERROR_DS_RESERVED_LINK_ID: DWORD = 8576; -pub const ERROR_DS_LINK_ID_NOT_AVAILABLE: DWORD = 8577; -pub const ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8578; -pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE: DWORD = 8579; -pub const ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC: DWORD = 8580; -pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG: DWORD = 8581; -pub const ERROR_DS_MODIFYDN_WRONG_GRANDPARENT: DWORD = 8582; -pub const ERROR_DS_NAME_ERROR_TRUST_REFERRAL: DWORD = 8583; -pub const ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER: DWORD = 8584; -pub const ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD: DWORD = 8585; -pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2: DWORD = 8586; -pub const ERROR_DS_THREAD_LIMIT_EXCEEDED: DWORD = 8587; -pub const ERROR_DS_NOT_CLOSEST: DWORD = 8588; -pub const ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF: DWORD = 8589; -pub const ERROR_DS_SINGLE_USER_MODE_FAILED: DWORD = 8590; -pub const ERROR_DS_NTDSCRIPT_SYNTAX_ERROR: DWORD = 8591; -pub const ERROR_DS_NTDSCRIPT_PROCESS_ERROR: DWORD = 8592; -pub const ERROR_DS_DIFFERENT_REPL_EPOCHS: DWORD = 8593; -pub const ERROR_DS_DRS_EXTENSIONS_CHANGED: DWORD = 8594; -pub const ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR: DWORD = 8595; -pub const ERROR_DS_NO_MSDS_INTID: DWORD = 8596; -pub const ERROR_DS_DUP_MSDS_INTID: DWORD = 8597; -pub const ERROR_DS_EXISTS_IN_RDNATTID: DWORD = 8598; -pub const ERROR_DS_AUTHORIZATION_FAILED: DWORD = 8599; -pub const ERROR_DS_INVALID_SCRIPT: DWORD = 8600; -pub const ERROR_DS_REMOTE_CROSSREF_OP_FAILED: DWORD = 8601; -pub const ERROR_DS_CROSS_REF_BUSY: DWORD = 8602; -pub const ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN: DWORD = 8603; -pub const ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC: DWORD = 8604; -pub const ERROR_DS_DUPLICATE_ID_FOUND: DWORD = 8605; -pub const ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT: DWORD = 8606; -pub const ERROR_DS_GROUP_CONVERSION_ERROR: DWORD = 8607; -pub const ERROR_DS_CANT_MOVE_APP_BASIC_GROUP: DWORD = 8608; -pub const ERROR_DS_CANT_MOVE_APP_QUERY_GROUP: DWORD = 8609; -pub const ERROR_DS_ROLE_NOT_VERIFIED: DWORD = 8610; -pub const ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL: DWORD = 8611; -pub const ERROR_DS_DOMAIN_RENAME_IN_PROGRESS: DWORD = 8612; -pub const ERROR_DS_EXISTING_AD_CHILD_NC: DWORD = 8613; -pub const ERROR_DS_REPL_LIFETIME_EXCEEDED: DWORD = 8614; -pub const ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER: DWORD = 8615; -pub const ERROR_DS_LDAP_SEND_QUEUE_FULL: DWORD = 8616; -pub const ERROR_DS_DRA_OUT_SCHEDULE_WINDOW: DWORD = 8617; -pub const ERROR_SXS_SECTION_NOT_FOUND: DWORD = 14000; -pub const ERROR_SXS_CANT_GEN_ACTCTX: DWORD = 14001; -pub const ERROR_SXS_INVALID_ACTCTXDATA_FORMAT: DWORD = 14002; -pub const ERROR_SXS_ASSEMBLY_NOT_FOUND: DWORD = 14003; -pub const ERROR_SXS_MANIFEST_FORMAT_ERROR: DWORD = 14004; -pub const ERROR_SXS_MANIFEST_PARSE_ERROR: DWORD = 14005; -pub const ERROR_SXS_ACTIVATION_CONTEXT_DISABLED: DWORD = 14006; -pub const ERROR_SXS_KEY_NOT_FOUND: DWORD = 14007; -pub const ERROR_SXS_VERSION_CONFLICT: DWORD = 14008; -pub const ERROR_SXS_WRONG_SECTION_TYPE: DWORD = 14009; -pub const ERROR_SXS_THREAD_QUERIES_DISABLED: DWORD = 14010; -pub const ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET: DWORD = 14011; -pub const ERROR_SXS_UNKNOWN_ENCODING_GROUP: DWORD = 14012; -pub const ERROR_SXS_UNKNOWN_ENCODING: DWORD = 14013; -pub const ERROR_SXS_INVALID_XML_NAMESPACE_URI: DWORD = 14014; -pub const ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14015; -pub const ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14016; -pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14017; -pub const ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14018; -pub const ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14019; -pub const ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT: DWORD = 14020; -pub const ERROR_SXS_DUPLICATE_DLL_NAME: DWORD = 14021; -pub const ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME: DWORD = 14022; -pub const ERROR_SXS_DUPLICATE_CLSID: DWORD = 14023; -pub const ERROR_SXS_DUPLICATE_IID: DWORD = 14024; -pub const ERROR_SXS_DUPLICATE_TLBID: DWORD = 14025; -pub const ERROR_SXS_DUPLICATE_PROGID: DWORD = 14026; -pub const ERROR_SXS_DUPLICATE_ASSEMBLY_NAME: DWORD = 14027; -pub const ERROR_SXS_FILE_HASH_MISMATCH: DWORD = 14028; -pub const ERROR_SXS_POLICY_PARSE_ERROR: DWORD = 14029; -pub const ERROR_SXS_XML_E_MISSINGQUOTE: DWORD = 14030; -pub const ERROR_SXS_XML_E_COMMENTSYNTAX: DWORD = 14031; -pub const ERROR_SXS_XML_E_BADSTARTNAMECHAR: DWORD = 14032; -pub const ERROR_SXS_XML_E_BADNAMECHAR: DWORD = 14033; -pub const ERROR_SXS_XML_E_BADCHARINSTRING: DWORD = 14034; -pub const ERROR_SXS_XML_E_XMLDECLSYNTAX: DWORD = 14035; -pub const ERROR_SXS_XML_E_BADCHARDATA: DWORD = 14036; -pub const ERROR_SXS_XML_E_MISSINGWHITESPACE: DWORD = 14037; -pub const ERROR_SXS_XML_E_EXPECTINGTAGEND: DWORD = 14038; -pub const ERROR_SXS_XML_E_MISSINGSEMICOLON: DWORD = 14039; -pub const ERROR_SXS_XML_E_UNBALANCEDPAREN: DWORD = 14040; -pub const ERROR_SXS_XML_E_INTERNALERROR: DWORD = 14041; -pub const ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE: DWORD = 14042; -pub const ERROR_SXS_XML_E_INCOMPLETE_ENCODING: DWORD = 14043; -pub const ERROR_SXS_XML_E_MISSING_PAREN: DWORD = 14044; -pub const ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE: DWORD = 14045; -pub const ERROR_SXS_XML_E_MULTIPLE_COLONS: DWORD = 14046; -pub const ERROR_SXS_XML_E_INVALID_DECIMAL: DWORD = 14047; -pub const ERROR_SXS_XML_E_INVALID_HEXIDECIMAL: DWORD = 14048; -pub const ERROR_SXS_XML_E_INVALID_UNICODE: DWORD = 14049; -pub const ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK: DWORD = 14050; -pub const ERROR_SXS_XML_E_UNEXPECTEDENDTAG: DWORD = 14051; -pub const ERROR_SXS_XML_E_UNCLOSEDTAG: DWORD = 14052; -pub const ERROR_SXS_XML_E_DUPLICATEATTRIBUTE: DWORD = 14053; -pub const ERROR_SXS_XML_E_MULTIPLEROOTS: DWORD = 14054; -pub const ERROR_SXS_XML_E_INVALIDATROOTLEVEL: DWORD = 14055; -pub const ERROR_SXS_XML_E_BADXMLDECL: DWORD = 14056; -pub const ERROR_SXS_XML_E_MISSINGROOT: DWORD = 14057; -pub const ERROR_SXS_XML_E_UNEXPECTEDEOF: DWORD = 14058; -pub const ERROR_SXS_XML_E_BADPEREFINSUBSET: DWORD = 14059; -pub const ERROR_SXS_XML_E_UNCLOSEDSTARTTAG: DWORD = 14060; -pub const ERROR_SXS_XML_E_UNCLOSEDENDTAG: DWORD = 14061; -pub const ERROR_SXS_XML_E_UNCLOSEDSTRING: DWORD = 14062; -pub const ERROR_SXS_XML_E_UNCLOSEDCOMMENT: DWORD = 14063; -pub const ERROR_SXS_XML_E_UNCLOSEDDECL: DWORD = 14064; -pub const ERROR_SXS_XML_E_UNCLOSEDCDATA: DWORD = 14065; -pub const ERROR_SXS_XML_E_RESERVEDNAMESPACE: DWORD = 14066; -pub const ERROR_SXS_XML_E_INVALIDENCODING: DWORD = 14067; -pub const ERROR_SXS_XML_E_INVALIDSWITCH: DWORD = 14068; -pub const ERROR_SXS_XML_E_BADXMLCASE: DWORD = 14069; -pub const ERROR_SXS_XML_E_INVALID_STANDALONE: DWORD = 14070; -pub const ERROR_SXS_XML_E_UNEXPECTED_STANDALONE: DWORD = 14071; -pub const ERROR_SXS_XML_E_INVALID_VERSION: DWORD = 14072; -pub const ERROR_SXS_XML_E_MISSINGEQUALS: DWORD = 14073; -pub const ERROR_SXS_PROTECTION_RECOVERY_FAILED: DWORD = 14074; -pub const ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT: DWORD = 14075; -pub const ERROR_SXS_PROTECTION_CATALOG_NOT_VALID: DWORD = 14076; -pub const ERROR_SXS_UNTRANSLATABLE_HRESULT: DWORD = 14077; -pub const ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING: DWORD = 14078; -pub const ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14079; -pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME: DWORD = 14080; -pub const ERROR_SXS_ASSEMBLY_MISSING: DWORD = 14081; -pub const ERROR_SXS_CORRUPT_ACTIVATION_STACK: DWORD = 14082; -pub const ERROR_SXS_CORRUPTION: DWORD = 14083; -pub const ERROR_SXS_EARLY_DEACTIVATION: DWORD = 14084; -pub const ERROR_SXS_INVALID_DEACTIVATION: DWORD = 14085; -pub const ERROR_SXS_MULTIPLE_DEACTIVATION: DWORD = 14086; -pub const ERROR_SXS_PROCESS_TERMINATION_REQUESTED: DWORD = 14087; -pub const ERROR_SXS_RELEASE_ACTIVATION_CONTEXT: DWORD = 14088; -pub const ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY: DWORD = 14089; -pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE: DWORD = 14090; -pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME: DWORD = 14091; -pub const ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE: DWORD = 14092; -pub const ERROR_SXS_IDENTITY_PARSE_ERROR: DWORD = 14093; -pub const ERROR_MALFORMED_SUBSTITUTION_STRING: DWORD = 14094; -pub const ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN: DWORD = 14095; -pub const ERROR_UNMAPPED_SUBSTITUTION_STRING: DWORD = 14096; -pub const ERROR_SXS_ASSEMBLY_NOT_LOCKED: DWORD = 14097; -pub const ERROR_SXS_COMPONENT_STORE_CORRUPT: DWORD = 14098; -pub const ERROR_ADVANCED_INSTALLER_FAILED: DWORD = 14099; -pub const ERROR_XML_ENCODING_MISMATCH: DWORD = 14100; -pub const ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT: DWORD = 14101; -pub const ERROR_SXS_IDENTITIES_DIFFERENT: DWORD = 14102; -pub const ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT: DWORD = 14103; -pub const ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY: DWORD = 14104; -pub const ERROR_SXS_MANIFEST_TOO_BIG: DWORD = 14105; -pub const ERROR_SXS_SETTING_NOT_REGISTERED: DWORD = 14106; -pub const ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE: DWORD = 14107; -pub const ERROR_SMI_PRIMITIVE_INSTALLER_FAILED: DWORD = 14108; -pub const ERROR_GENERIC_COMMAND_FAILED: DWORD = 14109; -pub const ERROR_SXS_FILE_HASH_MISSING: DWORD = 14110; -pub const ERROR_IPSEC_QM_POLICY_EXISTS: DWORD = 13000; -pub const ERROR_IPSEC_QM_POLICY_NOT_FOUND: DWORD = 13001; -pub const ERROR_IPSEC_QM_POLICY_IN_USE: DWORD = 13002; -pub const ERROR_IPSEC_MM_POLICY_EXISTS: DWORD = 13003; -pub const ERROR_IPSEC_MM_POLICY_NOT_FOUND: DWORD = 13004; -pub const ERROR_IPSEC_MM_POLICY_IN_USE: DWORD = 13005; -pub const ERROR_IPSEC_MM_FILTER_EXISTS: DWORD = 13006; -pub const ERROR_IPSEC_MM_FILTER_NOT_FOUND: DWORD = 13007; -pub const ERROR_IPSEC_TRANSPORT_FILTER_EXISTS: DWORD = 13008; -pub const ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND: DWORD = 13009; -pub const ERROR_IPSEC_MM_AUTH_EXISTS: DWORD = 13010; -pub const ERROR_IPSEC_MM_AUTH_NOT_FOUND: DWORD = 13011; -pub const ERROR_IPSEC_MM_AUTH_IN_USE: DWORD = 13012; -pub const ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND: DWORD = 13013; -pub const ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND: DWORD = 13014; -pub const ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND: DWORD = 13015; -pub const ERROR_IPSEC_TUNNEL_FILTER_EXISTS: DWORD = 13016; -pub const ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND: DWORD = 13017; -pub const ERROR_IPSEC_MM_FILTER_PENDING_DELETION: DWORD = 13018; -pub const ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION: DWORD = 13019; -pub const ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION: DWORD = 13020; -pub const ERROR_IPSEC_MM_POLICY_PENDING_DELETION: DWORD = 13021; -pub const ERROR_IPSEC_MM_AUTH_PENDING_DELETION: DWORD = 13022; -pub const ERROR_IPSEC_QM_POLICY_PENDING_DELETION: DWORD = 13023; -pub const ERROR_IPSEC_IKE_NEG_STATUS_BEGIN: DWORD = 13800; -pub const ERROR_IPSEC_IKE_AUTH_FAIL: DWORD = 13801; -pub const ERROR_IPSEC_IKE_ATTRIB_FAIL: DWORD = 13802; -pub const ERROR_IPSEC_IKE_NEGOTIATION_PENDING: DWORD = 13803; -pub const ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR: DWORD = 13804; -pub const ERROR_IPSEC_IKE_TIMED_OUT: DWORD = 13805; -pub const ERROR_IPSEC_IKE_NO_CERT: DWORD = 13806; -pub const ERROR_IPSEC_IKE_SA_DELETED: DWORD = 13807; -pub const ERROR_IPSEC_IKE_SA_REAPED: DWORD = 13808; -pub const ERROR_IPSEC_IKE_MM_ACQUIRE_DROP: DWORD = 13809; -pub const ERROR_IPSEC_IKE_QM_ACQUIRE_DROP: DWORD = 13810; -pub const ERROR_IPSEC_IKE_QUEUE_DROP_MM: DWORD = 13811; -pub const ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM: DWORD = 13812; -pub const ERROR_IPSEC_IKE_DROP_NO_RESPONSE: DWORD = 13813; -pub const ERROR_IPSEC_IKE_MM_DELAY_DROP: DWORD = 13814; -pub const ERROR_IPSEC_IKE_QM_DELAY_DROP: DWORD = 13815; -pub const ERROR_IPSEC_IKE_ERROR: DWORD = 13816; -pub const ERROR_IPSEC_IKE_CRL_FAILED: DWORD = 13817; -pub const ERROR_IPSEC_IKE_INVALID_KEY_USAGE: DWORD = 13818; -pub const ERROR_IPSEC_IKE_INVALID_CERT_TYPE: DWORD = 13819; -pub const ERROR_IPSEC_IKE_NO_PRIVATE_KEY: DWORD = 13820; -pub const ERROR_IPSEC_IKE_DH_FAIL: DWORD = 13822; -pub const ERROR_IPSEC_IKE_INVALID_HEADER: DWORD = 13824; -pub const ERROR_IPSEC_IKE_NO_POLICY: DWORD = 13825; -pub const ERROR_IPSEC_IKE_INVALID_SIGNATURE: DWORD = 13826; -pub const ERROR_IPSEC_IKE_KERBEROS_ERROR: DWORD = 13827; -pub const ERROR_IPSEC_IKE_NO_PUBLIC_KEY: DWORD = 13828; -pub const ERROR_IPSEC_IKE_PROCESS_ERR: DWORD = 13829; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_SA: DWORD = 13830; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_PROP: DWORD = 13831; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_TRANS: DWORD = 13832; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_KE: DWORD = 13833; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_ID: DWORD = 13834; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT: DWORD = 13835; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ: DWORD = 13836; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_HASH: DWORD = 13837; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_SIG: DWORD = 13838; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_NONCE: DWORD = 13839; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY: DWORD = 13840; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_DELETE: DWORD = 13841; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR: DWORD = 13842; -pub const ERROR_IPSEC_IKE_INVALID_PAYLOAD: DWORD = 13843; -pub const ERROR_IPSEC_IKE_LOAD_SOFT_SA: DWORD = 13844; -pub const ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN: DWORD = 13845; -pub const ERROR_IPSEC_IKE_INVALID_COOKIE: DWORD = 13846; -pub const ERROR_IPSEC_IKE_NO_PEER_CERT: DWORD = 13847; -pub const ERROR_IPSEC_IKE_PEER_CRL_FAILED: DWORD = 13848; -pub const ERROR_IPSEC_IKE_POLICY_CHANGE: DWORD = 13849; -pub const ERROR_IPSEC_IKE_NO_MM_POLICY: DWORD = 13850; -pub const ERROR_IPSEC_IKE_NOTCBPRIV: DWORD = 13851; -pub const ERROR_IPSEC_IKE_SECLOADFAIL: DWORD = 13852; -pub const ERROR_IPSEC_IKE_FAILSSPINIT: DWORD = 13853; -pub const ERROR_IPSEC_IKE_FAILQUERYSSP: DWORD = 13854; -pub const ERROR_IPSEC_IKE_SRVACQFAIL: DWORD = 13855; -pub const ERROR_IPSEC_IKE_SRVQUERYCRED: DWORD = 13856; -pub const ERROR_IPSEC_IKE_GETSPIFAIL: DWORD = 13857; -pub const ERROR_IPSEC_IKE_INVALID_FILTER: DWORD = 13858; -pub const ERROR_IPSEC_IKE_OUT_OF_MEMORY: DWORD = 13859; -pub const ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED: DWORD = 13860; -pub const ERROR_IPSEC_IKE_INVALID_POLICY: DWORD = 13861; -pub const ERROR_IPSEC_IKE_UNKNOWN_DOI: DWORD = 13862; -pub const ERROR_IPSEC_IKE_INVALID_SITUATION: DWORD = 13863; -pub const ERROR_IPSEC_IKE_DH_FAILURE: DWORD = 13864; -pub const ERROR_IPSEC_IKE_INVALID_GROUP: DWORD = 13865; -pub const ERROR_IPSEC_IKE_ENCRYPT: DWORD = 13866; -pub const ERROR_IPSEC_IKE_DECRYPT: DWORD = 13867; -pub const ERROR_IPSEC_IKE_POLICY_MATCH: DWORD = 13868; -pub const ERROR_IPSEC_IKE_UNSUPPORTED_ID: DWORD = 13869; -pub const ERROR_IPSEC_IKE_INVALID_HASH: DWORD = 13870; -pub const ERROR_IPSEC_IKE_INVALID_HASH_ALG: DWORD = 13871; -pub const ERROR_IPSEC_IKE_INVALID_HASH_SIZE: DWORD = 13872; -pub const ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG: DWORD = 13873; -pub const ERROR_IPSEC_IKE_INVALID_AUTH_ALG: DWORD = 13874; -pub const ERROR_IPSEC_IKE_INVALID_SIG: DWORD = 13875; -pub const ERROR_IPSEC_IKE_LOAD_FAILED: DWORD = 13876; -pub const ERROR_IPSEC_IKE_RPC_DELETE: DWORD = 13877; -pub const ERROR_IPSEC_IKE_BENIGN_REINIT: DWORD = 13878; -pub const ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY: DWORD = 13879; -pub const ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN: DWORD = 13881; -pub const ERROR_IPSEC_IKE_MM_LIMIT: DWORD = 13882; -pub const ERROR_IPSEC_IKE_NEGOTIATION_DISABLED: DWORD = 13883; -/*pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13884)*/ -pub const ERROR_IPSEC_IKE_QM_LIMIT: DWORD = 13884; -pub const ERROR_IPSEC_IKE_MM_EXPIRED: DWORD = 13885; -pub const ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID: DWORD = 13886; -pub const ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH: DWORD = 13887; -pub const ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID: DWORD = 13888; -pub const ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD: DWORD = 13889; -pub const ERROR_IPSEC_IKE_DOS_COOKIE_SENT: DWORD = 13890; -pub const ERROR_IPSEC_IKE_SHUTTING_DOWN: DWORD = 13891; -pub const ERROR_IPSEC_IKE_CGA_AUTH_FAILED: DWORD = 13892; -pub const ERROR_IPSEC_IKE_PROCESS_ERR_NATOA: DWORD = 13893; -pub const ERROR_IPSEC_IKE_INVALID_MM_FOR_QM: DWORD = 13894; -pub const ERROR_IPSEC_IKE_QM_EXPIRED: DWORD = 13895; -pub const ERROR_IPSEC_IKE_TOO_MANY_FILTERS: DWORD = 13896; -pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13897; -pub const ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL: DWORD = 13898; -pub const ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE: DWORD = 13899; -pub const ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING: DWORD = 13900; -pub const ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING: DWORD = 13901; -pub const ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS: DWORD = 13902; -pub const ERROR_IPSEC_IKE_RATELIMIT_DROP: DWORD = 13903; -pub const ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE: DWORD = 13904; -pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE: DWORD = 13905; -pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE: DWORD = 13906; -pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY: DWORD = 13907; -pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE: DWORD = 13908; -pub const ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END: DWORD = 13909; -pub const ERROR_IPSEC_BAD_SPI: DWORD = 13910; -pub const ERROR_IPSEC_SA_LIFETIME_EXPIRED: DWORD = 13911; -pub const ERROR_IPSEC_WRONG_SA: DWORD = 13912; -pub const ERROR_IPSEC_REPLAY_CHECK_FAILED: DWORD = 13913; -pub const ERROR_IPSEC_INVALID_PACKET: DWORD = 13914; -pub const ERROR_IPSEC_INTEGRITY_CHECK_FAILED: DWORD = 13915; -pub const ERROR_IPSEC_CLEAR_TEXT_DROP: DWORD = 13916; -pub const ERROR_IPSEC_AUTH_FIREWALL_DROP: DWORD = 13917; -pub const ERROR_IPSEC_THROTTLE_DROP: DWORD = 13918; -pub const ERROR_IPSEC_DOSP_BLOCK: DWORD = 13925; -pub const ERROR_IPSEC_DOSP_RECEIVED_MULTICAST: DWORD = 13926; -pub const ERROR_IPSEC_DOSP_INVALID_PACKET: DWORD = 13927; -pub const ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED: DWORD = 13928; -pub const ERROR_IPSEC_DOSP_MAX_ENTRIES: DWORD = 13929; -pub const ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED: DWORD = 13930; -pub const ERROR_IPSEC_DOSP_NOT_INSTALLED: DWORD = 13931; -pub const ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES: DWORD = 13932; -pub const ERROR_EVT_INVALID_CHANNEL_PATH: DWORD = 15000; -pub const ERROR_EVT_INVALID_QUERY: DWORD = 15001; -pub const ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND: DWORD = 15002; -pub const ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND: DWORD = 15003; -pub const ERROR_EVT_INVALID_PUBLISHER_NAME: DWORD = 15004; -pub const ERROR_EVT_INVALID_EVENT_DATA: DWORD = 15005; -pub const ERROR_EVT_CHANNEL_NOT_FOUND: DWORD = 15007; -pub const ERROR_EVT_MALFORMED_XML_TEXT: DWORD = 15008; -pub const ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL: DWORD = 15009; -pub const ERROR_EVT_CONFIGURATION_ERROR: DWORD = 15010; -pub const ERROR_EVT_QUERY_RESULT_STALE: DWORD = 15011; -pub const ERROR_EVT_QUERY_RESULT_INVALID_POSITION: DWORD = 15012; -pub const ERROR_EVT_NON_VALIDATING_MSXML: DWORD = 15013; -pub const ERROR_EVT_FILTER_ALREADYSCOPED: DWORD = 15014; -pub const ERROR_EVT_FILTER_NOTELTSET: DWORD = 15015; -pub const ERROR_EVT_FILTER_INVARG: DWORD = 15016; -pub const ERROR_EVT_FILTER_INVTEST: DWORD = 15017; -pub const ERROR_EVT_FILTER_INVTYPE: DWORD = 15018; -pub const ERROR_EVT_FILTER_PARSEERR: DWORD = 15019; -pub const ERROR_EVT_FILTER_UNSUPPORTEDOP: DWORD = 15020; -pub const ERROR_EVT_FILTER_UNEXPECTEDTOKEN: DWORD = 15021; -pub const ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL: DWORD = 15022; -pub const ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE: DWORD = 15023; -pub const ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE: DWORD = 15024; -pub const ERROR_EVT_CHANNEL_CANNOT_ACTIVATE: DWORD = 15025; -pub const ERROR_EVT_FILTER_TOO_COMPLEX: DWORD = 15026; -pub const ERROR_EVT_MESSAGE_NOT_FOUND: DWORD = 15027; -pub const ERROR_EVT_MESSAGE_ID_NOT_FOUND: DWORD = 15028; -pub const ERROR_EVT_UNRESOLVED_VALUE_INSERT: DWORD = 15029; -pub const ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: DWORD = 15030; -pub const ERROR_EVT_MAX_INSERTS_REACHED: DWORD = 15031; -pub const ERROR_EVT_EVENT_DEFINITION_NOT_FOUND: DWORD = 15032; -pub const ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: DWORD = 15033; -pub const ERROR_EVT_VERSION_TOO_OLD: DWORD = 15034; -pub const ERROR_EVT_VERSION_TOO_NEW: DWORD = 15035; -pub const ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY: DWORD = 15036; -pub const ERROR_EVT_PUBLISHER_DISABLED: DWORD = 15037; -pub const ERROR_EVT_FILTER_OUT_OF_RANGE: DWORD = 15038; -pub const ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE: DWORD = 15080; -pub const ERROR_EC_LOG_DISABLED: DWORD = 15081; -pub const ERROR_EC_CIRCULAR_FORWARDING: DWORD = 15082; -pub const ERROR_EC_CREDSTORE_FULL: DWORD = 15083; -pub const ERROR_EC_CRED_NOT_FOUND: DWORD = 15084; -pub const ERROR_EC_NO_ACTIVE_CHANNEL: DWORD = 15085; -pub const ERROR_MUI_FILE_NOT_FOUND: DWORD = 15100; -pub const ERROR_MUI_INVALID_FILE: DWORD = 15101; -pub const ERROR_MUI_INVALID_RC_CONFIG: DWORD = 15102; -pub const ERROR_MUI_INVALID_LOCALE_NAME: DWORD = 15103; -pub const ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME: DWORD = 15104; -pub const ERROR_MUI_FILE_NOT_LOADED: DWORD = 15105; -pub const ERROR_RESOURCE_ENUM_USER_STOP: DWORD = 15106; -pub const ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED: DWORD = 15107; -pub const ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME: DWORD = 15108; -pub const ERROR_MRM_RUNTIME_NO_DEFAULT_OR_NEUTRAL_RESOURCE: DWORD = 15110; -pub const ERROR_MRM_INVALID_PRICONFIG: DWORD = 15111; -pub const ERROR_MRM_INVALID_FILE_TYPE: DWORD = 15112; -pub const ERROR_MRM_UNKNOWN_QUALIFIER: DWORD = 15113; -pub const ERROR_MRM_INVALID_QUALIFIER_VALUE: DWORD = 15114; -pub const ERROR_MRM_NO_CANDIDATE: DWORD = 15115; -pub const ERROR_MRM_NO_MATCH_OR_DEFAULT_CANDIDATE: DWORD = 15116; -pub const ERROR_MRM_RESOURCE_TYPE_MISMATCH: DWORD = 15117; -pub const ERROR_MRM_DUPLICATE_MAP_NAME: DWORD = 15118; -pub const ERROR_MRM_DUPLICATE_ENTRY: DWORD = 15119; -pub const ERROR_MRM_INVALID_RESOURCE_IDENTIFIER: DWORD = 15120; -pub const ERROR_MRM_FILEPATH_TOO_LONG: DWORD = 15121; -pub const ERROR_MRM_UNSUPPORTED_DIRECTORY_TYPE: DWORD = 15122; -pub const ERROR_MRM_INVALID_PRI_FILE: DWORD = 15126; -pub const ERROR_MRM_NAMED_RESOURCE_NOT_FOUND: DWORD = 15127; -pub const ERROR_MRM_MAP_NOT_FOUND: DWORD = 15135; -pub const ERROR_MRM_UNSUPPORTED_PROFILE_TYPE: DWORD = 15136; -pub const ERROR_MRM_INVALID_QUALIFIER_OPERATOR: DWORD = 15137; -pub const ERROR_MRM_INDETERMINATE_QUALIFIER_VALUE: DWORD = 15138; -pub const ERROR_MRM_AUTOMERGE_ENABLED: DWORD = 15139; -pub const ERROR_MRM_TOO_MANY_RESOURCES: DWORD = 15140; -pub const ERROR_MCA_INVALID_CAPABILITIES_STRING: DWORD = 15200; -pub const ERROR_MCA_INVALID_VCP_VERSION: DWORD = 15201; -pub const ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION: DWORD = 15202; -pub const ERROR_MCA_MCCS_VERSION_MISMATCH: DWORD = 15203; -pub const ERROR_MCA_UNSUPPORTED_MCCS_VERSION: DWORD = 15204; -pub const ERROR_MCA_INTERNAL_ERROR: DWORD = 15205; -pub const ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED: DWORD = 15206; -pub const ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE: DWORD = 15207; -pub const ERROR_AMBIGUOUS_SYSTEM_DEVICE: DWORD = 15250; -pub const ERROR_SYSTEM_DEVICE_NOT_FOUND: DWORD = 15299; -pub const ERROR_HASH_NOT_SUPPORTED: DWORD = 15300; -pub const ERROR_HASH_NOT_PRESENT: DWORD = 15301; -pub const ERROR_SECONDARY_IC_PROVIDER_NOT_REGISTERED: DWORD = 15321; -pub const ERROR_GPIO_CLIENT_INFORMATION_INVALID: DWORD = 15322; -pub const ERROR_GPIO_VERSION_NOT_SUPPORTED: DWORD = 15323; -pub const ERROR_GPIO_INVALID_REGISTRATION_PACKET: DWORD = 15324; -pub const ERROR_GPIO_OPERATION_DENIED: DWORD = 15325; -pub const ERROR_GPIO_INCOMPATIBLE_CONNECT_MODE: DWORD = 15326; -pub const ERROR_GPIO_INTERRUPT_ALREADY_UNMASKED: DWORD = 15327; -pub const ERROR_CANNOT_SWITCH_RUNLEVEL: DWORD = 15400; -pub const ERROR_INVALID_RUNLEVEL_SETTING: DWORD = 15401; -pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: DWORD = 15402; -pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: DWORD = 15403; -pub const ERROR_RUNLEVEL_SWITCH_IN_PROGRESS: DWORD = 15404; -pub const ERROR_SERVICES_FAILED_AUTOSTART: DWORD = 15405; -pub const ERROR_COM_TASK_STOP_PENDING: DWORD = 15501; -pub const ERROR_INSTALL_OPEN_PACKAGE_FAILED: DWORD = 15600; -pub const ERROR_INSTALL_PACKAGE_NOT_FOUND: DWORD = 15601; -pub const ERROR_INSTALL_INVALID_PACKAGE: DWORD = 15602; -pub const ERROR_INSTALL_RESOLVE_DEPENDENCY_FAILED: DWORD = 15603; -pub const ERROR_INSTALL_OUT_OF_DISK_SPACE: DWORD = 15604; -pub const ERROR_INSTALL_NETWORK_FAILURE: DWORD = 15605; -pub const ERROR_INSTALL_REGISTRATION_FAILURE: DWORD = 15606; -pub const ERROR_INSTALL_DEREGISTRATION_FAILURE: DWORD = 15607; -pub const ERROR_INSTALL_CANCEL: DWORD = 15608; -pub const ERROR_INSTALL_FAILED: DWORD = 15609; -pub const ERROR_REMOVE_FAILED: DWORD = 15610; -pub const ERROR_PACKAGE_ALREADY_EXISTS: DWORD = 15611; -pub const ERROR_NEEDS_REMEDIATION: DWORD = 15612; -pub const ERROR_INSTALL_PREREQUISITE_FAILED: DWORD = 15613; -pub const ERROR_PACKAGE_REPOSITORY_CORRUPTED: DWORD = 15614; -pub const ERROR_INSTALL_POLICY_FAILURE: DWORD = 15615; -pub const ERROR_PACKAGE_UPDATING: DWORD = 15616; -pub const ERROR_DEPLOYMENT_BLOCKED_BY_POLICY: DWORD = 15617; -pub const ERROR_PACKAGES_IN_USE: DWORD = 15618; -pub const ERROR_RECOVERY_FILE_CORRUPT: DWORD = 15619; -pub const ERROR_INVALID_STAGED_SIGNATURE: DWORD = 15620; -pub const ERROR_DELETING_EXISTING_APPLICATIONDATA_STORE_FAILED: DWORD = 15621; -pub const ERROR_INSTALL_PACKAGE_DOWNGRADE: DWORD = 15622; -pub const ERROR_SYSTEM_NEEDS_REMEDIATION: DWORD = 15623; -pub const ERROR_APPX_INTEGRITY_FAILURE_CLR_NGEN: DWORD = 15624; -pub const ERROR_RESILIENCY_FILE_CORRUPT: DWORD = 15625; -pub const ERROR_INSTALL_FIREWALL_SERVICE_NOT_RUNNING: DWORD = 15626; -pub const ERROR_STATE_LOAD_STORE_FAILED: DWORD = 15800; -pub const ERROR_STATE_GET_VERSION_FAILED: DWORD = 15801; -pub const ERROR_STATE_SET_VERSION_FAILED: DWORD = 15802; -pub const ERROR_STATE_STRUCTURED_RESET_FAILED: DWORD = 15803; -pub const ERROR_STATE_OPEN_CONTAINER_FAILED: DWORD = 15804; -pub const ERROR_STATE_CREATE_CONTAINER_FAILED: DWORD = 15805; -pub const ERROR_STATE_DELETE_CONTAINER_FAILED: DWORD = 15806; -pub const ERROR_STATE_READ_SETTING_FAILED: DWORD = 15807; -pub const ERROR_STATE_WRITE_SETTING_FAILED: DWORD = 15808; -pub const ERROR_STATE_DELETE_SETTING_FAILED: DWORD = 15809; -pub const ERROR_STATE_QUERY_SETTING_FAILED: DWORD = 15810; -pub const ERROR_STATE_READ_COMPOSITE_SETTING_FAILED: DWORD = 15811; -pub const ERROR_STATE_WRITE_COMPOSITE_SETTING_FAILED: DWORD = 15812; -pub const ERROR_STATE_ENUMERATE_CONTAINER_FAILED: DWORD = 15813; -pub const ERROR_STATE_ENUMERATE_SETTINGS_FAILED: DWORD = 15814; -pub const ERROR_STATE_COMPOSITE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15815; -pub const ERROR_STATE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15816; -pub const ERROR_STATE_SETTING_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15817; -pub const ERROR_STATE_CONTAINER_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15818; -pub const ERROR_API_UNAVAILABLE: DWORD = 15841; -pub const ERROR_AUDITING_DISABLED: DWORD = 0xC0090001; -pub const ERROR_ALL_SIDS_FILTERED: DWORD = 0xC0090002; - -pub const WSABASEERR: c_int = 10000; -pub const WSAEINTR: c_int = WSABASEERR + 4; -pub const WSAEBADF: c_int = WSABASEERR + 9; -pub const WSAEACCES: c_int = WSABASEERR + 13; -pub const WSAEFAULT: c_int = WSABASEERR + 14; -pub const WSAEINVAL: c_int = WSABASEERR + 22; -pub const WSAEMFILE: c_int = WSABASEERR + 24; -pub const WSAEWOULDBLOCK: c_int = WSABASEERR + 35; -pub const WSAEINPROGRESS: c_int = WSABASEERR + 36; -pub const WSAEALREADY: c_int = WSABASEERR + 37; -pub const WSAENOTSOCK: c_int = WSABASEERR + 38; -pub const WSAEDESTADDRREQ: c_int = WSABASEERR + 39; -pub const WSAEMSGSIZE: c_int = WSABASEERR + 40; -pub const WSAEPROTOTYPE: c_int = WSABASEERR + 41; -pub const WSAENOPROTOOPT: c_int = WSABASEERR + 42; -pub const WSAEPROTONOSUPPORT: c_int = WSABASEERR + 43; -pub const WSAESOCKTNOSUPPORT: c_int = WSABASEERR + 44; -pub const WSAEOPNOTSUPP: c_int = WSABASEERR + 45; -pub const WSAEPFNOSUPPORT: c_int = WSABASEERR + 46; -pub const WSAEAFNOSUPPORT: c_int = WSABASEERR + 47; -pub const WSAEADDRINUSE: c_int = WSABASEERR + 48; -pub const WSAEADDRNOTAVAIL: c_int = WSABASEERR + 49; -pub const WSAENETDOWN: c_int = WSABASEERR + 50; -pub const WSAENETUNREACH: c_int = WSABASEERR + 51; -pub const WSAENETRESET: c_int = WSABASEERR + 52; -pub const WSAECONNABORTED: c_int = WSABASEERR + 53; -pub const WSAECONNRESET: c_int = WSABASEERR + 54; -pub const WSAENOBUFS: c_int = WSABASEERR + 55; -pub const WSAEISCONN: c_int = WSABASEERR + 56; -pub const WSAENOTCONN: c_int = WSABASEERR + 57; -pub const WSAESHUTDOWN: c_int = WSABASEERR + 58; -pub const WSAETOOMANYREFS: c_int = WSABASEERR + 59; -pub const WSAETIMEDOUT: c_int = WSABASEERR + 60; -pub const WSAECONNREFUSED: c_int = WSABASEERR + 61; -pub const WSAELOOP: c_int = WSABASEERR + 62; -pub const WSAENAMETOOLONG: c_int = WSABASEERR + 63; -pub const WSAEHOSTDOWN: c_int = WSABASEERR + 64; -pub const WSAEHOSTUNREACH: c_int = WSABASEERR + 65; -pub const WSAENOTEMPTY: c_int = WSABASEERR + 66; -pub const WSAEPROCLIM: c_int = WSABASEERR + 67; -pub const WSAEUSERS: c_int = WSABASEERR + 68; -pub const WSAEDQUOT: c_int = WSABASEERR + 69; -pub const WSAESTALE: c_int = WSABASEERR + 70; -pub const WSAEREMOTE: c_int = WSABASEERR + 71; -pub const WSASYSNOTREADY: c_int = WSABASEERR + 91; -pub const WSAVERNOTSUPPORTED: c_int = WSABASEERR + 92; -pub const WSANOTINITIALISED: c_int = WSABASEERR + 93; -pub const WSAEDISCON: c_int = WSABASEERR + 101; -pub const WSAENOMORE: c_int = WSABASEERR + 102; -pub const WSAECANCELLED: c_int = WSABASEERR + 103; -pub const WSAEINVALIDPROCTABLE: c_int = WSABASEERR + 104; -pub const WSAEINVALIDPROVIDER: c_int = WSABASEERR + 105; -pub const WSAEPROVIDERFAILEDINIT: c_int = WSABASEERR + 106; -pub const WSASYSCALLFAILURE: c_int = WSABASEERR + 107; -pub const WSASERVICE_NOT_FOUND: c_int = WSABASEERR + 108; -pub const WSATYPE_NOT_FOUND: c_int = WSABASEERR + 109; -pub const WSA_E_NO_MORE: c_int = WSABASEERR + 110; -pub const WSA_E_CANCELLED: c_int = WSABASEERR + 111; -pub const WSAEREFUSED: c_int = WSABASEERR + 112; -pub const WSAHOST_NOT_FOUND: c_int = WSABASEERR + 1001; -pub const WSATRY_AGAIN: c_int = WSABASEERR + 1002; -pub const WSANO_RECOVERY: c_int = WSABASEERR + 1003; -pub const WSANO_DATA: c_int = WSABASEERR + 1004; -pub const WSA_QOS_RECEIVERS: c_int = WSABASEERR + 1005; -pub const WSA_QOS_SENDERS: c_int = WSABASEERR + 1006; -pub const WSA_QOS_NO_SENDERS: c_int = WSABASEERR + 1007; -pub const WSA_QOS_NO_RECEIVERS: c_int = WSABASEERR + 1008; -pub const WSA_QOS_REQUEST_CONFIRMED: c_int = WSABASEERR + 1009; -pub const WSA_QOS_ADMISSION_FAILURE: c_int = WSABASEERR + 1010; -pub const WSA_QOS_POLICY_FAILURE: c_int = WSABASEERR + 1011; -pub const WSA_QOS_BAD_STYLE: c_int = WSABASEERR + 1012; -pub const WSA_QOS_BAD_OBJECT: c_int = WSABASEERR + 1013; -pub const WSA_QOS_TRAFFIC_CTRL_ERROR: c_int = WSABASEERR + 1014; -pub const WSA_QOS_GENERIC_ERROR: c_int = WSABASEERR + 1015; -pub const WSA_QOS_ESERVICETYPE: c_int = WSABASEERR + 1016; -pub const WSA_QOS_EFLOWSPEC: c_int = WSABASEERR + 1017; -pub const WSA_QOS_EPROVSPECBUF: c_int = WSABASEERR + 1018; -pub const WSA_QOS_EFILTERSTYLE: c_int = WSABASEERR + 1019; -pub const WSA_QOS_EFILTERTYPE: c_int = WSABASEERR + 1020; -pub const WSA_QOS_EFILTERCOUNT: c_int = WSABASEERR + 1021; -pub const WSA_QOS_EOBJLENGTH: c_int = WSABASEERR + 1022; -pub const WSA_QOS_EFLOWCOUNT: c_int = WSABASEERR + 1023; -pub const WSA_QOS_EUNKNOWNPSOBJ: c_int = WSABASEERR + 1024; -pub const WSA_QOS_EUNKOWNPSOBJ: c_int = WSA_QOS_EUNKNOWNPSOBJ; -pub const WSA_QOS_EPOLICYOBJ: c_int = WSABASEERR + 1025; -pub const WSA_QOS_EFLOWDESC: c_int = WSABASEERR + 1026; -pub const WSA_QOS_EPSFLOWSPEC: c_int = WSABASEERR + 1027; -pub const WSA_QOS_EPSFILTERSPEC: c_int = WSABASEERR + 1028; -pub const WSA_QOS_ESDMODEOBJ: c_int = WSABASEERR + 1029; -pub const WSA_QOS_ESHAPERATEOBJ: c_int = WSABASEERR + 1030; -pub const WSA_QOS_RESERVED_PETYPE: c_int = WSABASEERR + 1031; diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst new file mode 100644 index 00000000000..3e454199f13 --- /dev/null +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -0,0 +1,2590 @@ +// tidy-alphabetical-start +Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED +Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION +Windows.Wdk.Storage.FileSystem.FILE_CREATE +Windows.Wdk.Storage.FileSystem.FILE_CREATE_TREE_CONNECTION +Windows.Wdk.Storage.FileSystem.FILE_DELETE_ON_CLOSE +Windows.Wdk.Storage.FileSystem.FILE_DIRECTORY_FILE +Windows.Wdk.Storage.FileSystem.FILE_DISALLOW_EXCLUSIVE +Windows.Wdk.Storage.FileSystem.FILE_NO_COMPRESSION +Windows.Wdk.Storage.FileSystem.FILE_NO_EA_KNOWLEDGE +Windows.Wdk.Storage.FileSystem.FILE_NO_INTERMEDIATE_BUFFERING +Windows.Wdk.Storage.FileSystem.FILE_NON_DIRECTORY_FILE +Windows.Wdk.Storage.FileSystem.FILE_OPEN +Windows.Wdk.Storage.FileSystem.FILE_OPEN_BY_FILE_ID +Windows.Wdk.Storage.FileSystem.FILE_OPEN_FOR_BACKUP_INTENT +Windows.Wdk.Storage.FileSystem.FILE_OPEN_FOR_FREE_SPACE_QUERY +Windows.Wdk.Storage.FileSystem.FILE_OPEN_IF +Windows.Wdk.Storage.FileSystem.FILE_OPEN_NO_RECALL +Windows.Wdk.Storage.FileSystem.FILE_OPEN_REPARSE_POINT +Windows.Wdk.Storage.FileSystem.FILE_OPEN_REQUIRING_OPLOCK +Windows.Wdk.Storage.FileSystem.FILE_OVERWRITE +Windows.Wdk.Storage.FileSystem.FILE_OVERWRITE_IF +Windows.Wdk.Storage.FileSystem.FILE_RANDOM_ACCESS +Windows.Wdk.Storage.FileSystem.FILE_RESERVE_OPFILTER +Windows.Wdk.Storage.FileSystem.FILE_SEQUENTIAL_ONLY +Windows.Wdk.Storage.FileSystem.FILE_SESSION_AWARE +Windows.Wdk.Storage.FileSystem.FILE_SUPERSEDE +Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_ALERT +Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_NONALERT +Windows.Wdk.Storage.FileSystem.FILE_WRITE_THROUGH +Windows.Wdk.Storage.FileSystem.NtCreateFile +Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_DISPOSITION +Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_OPTIONS +Windows.Wdk.Storage.FileSystem.NtReadFile +Windows.Wdk.Storage.FileSystem.NtWriteFile +Windows.Wdk.Storage.FileSystem.SYMLINK_FLAG_RELATIVE +Windows.Win32.Foundation.BOOL +Windows.Win32.Foundation.BOOLEAN +Windows.Win32.Foundation.CloseHandle +Windows.Win32.Foundation.DNS_ERROR_ADDRESS_REQUIRED +Windows.Win32.Foundation.DNS_ERROR_ALIAS_LOOP +Windows.Win32.Foundation.DNS_ERROR_AUTOZONE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_AXFR +Windows.Win32.Foundation.DNS_ERROR_BACKGROUND_LOADING +Windows.Win32.Foundation.DNS_ERROR_BAD_KEYMASTER +Windows.Win32.Foundation.DNS_ERROR_BAD_PACKET +Windows.Win32.Foundation.DNS_ERROR_CANNOT_FIND_ROOT_HINTS +Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED +Windows.Win32.Foundation.DNS_ERROR_CNAME_COLLISION +Windows.Win32.Foundation.DNS_ERROR_CNAME_LOOP +Windows.Win32.Foundation.DNS_ERROR_DATAFILE_OPEN_FAILURE +Windows.Win32.Foundation.DNS_ERROR_DATAFILE_PARSING +Windows.Win32.Foundation.DNS_ERROR_DEFAULT_SCOPE +Windows.Win32.Foundation.DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE +Windows.Win32.Foundation.DNS_ERROR_DEFAULT_ZONESCOPE +Windows.Win32.Foundation.DNS_ERROR_DELEGATION_REQUIRED +Windows.Win32.Foundation.DNS_ERROR_DNAME_COLLISION +Windows.Win32.Foundation.DNS_ERROR_DNSSEC_IS_DISABLED +Windows.Win32.Foundation.DNS_ERROR_DP_ALREADY_ENLISTED +Windows.Win32.Foundation.DNS_ERROR_DP_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_DP_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_DP_FSMO_ERROR +Windows.Win32.Foundation.DNS_ERROR_DP_NOT_AVAILABLE +Windows.Win32.Foundation.DNS_ERROR_DP_NOT_ENLISTED +Windows.Win32.Foundation.DNS_ERROR_DS_UNAVAILABLE +Windows.Win32.Foundation.DNS_ERROR_DS_ZONE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_DWORD_VALUE_TOO_LARGE +Windows.Win32.Foundation.DNS_ERROR_DWORD_VALUE_TOO_SMALL +Windows.Win32.Foundation.DNS_ERROR_FILE_WRITEBACK_FAILED +Windows.Win32.Foundation.DNS_ERROR_FORWARDER_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_INCONSISTENT_ROOT_HINTS +Windows.Win32.Foundation.DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME +Windows.Win32.Foundation.DNS_ERROR_INVALID_CLIENT_SUBNET_NAME +Windows.Win32.Foundation.DNS_ERROR_INVALID_DATA +Windows.Win32.Foundation.DNS_ERROR_INVALID_DATAFILE_NAME +Windows.Win32.Foundation.DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET +Windows.Win32.Foundation.DNS_ERROR_INVALID_IP_ADDRESS +Windows.Win32.Foundation.DNS_ERROR_INVALID_KEY_SIZE +Windows.Win32.Foundation.DNS_ERROR_INVALID_NAME +Windows.Win32.Foundation.DNS_ERROR_INVALID_NAME_CHAR +Windows.Win32.Foundation.DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT +Windows.Win32.Foundation.DNS_ERROR_INVALID_POLICY_TABLE +Windows.Win32.Foundation.DNS_ERROR_INVALID_PROPERTY +Windows.Win32.Foundation.DNS_ERROR_INVALID_ROLLOVER_PERIOD +Windows.Win32.Foundation.DNS_ERROR_INVALID_SCOPE_NAME +Windows.Win32.Foundation.DNS_ERROR_INVALID_SCOPE_OPERATION +Windows.Win32.Foundation.DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD +Windows.Win32.Foundation.DNS_ERROR_INVALID_TYPE +Windows.Win32.Foundation.DNS_ERROR_INVALID_XML +Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONE_OPERATION +Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONE_TYPE +Windows.Win32.Foundation.DNS_ERROR_INVALID_ZONESCOPE_NAME +Windows.Win32.Foundation.DNS_ERROR_KEYMASTER_REQUIRED +Windows.Win32.Foundation.DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION +Windows.Win32.Foundation.DNS_ERROR_KSP_NOT_ACCESSIBLE +Windows.Win32.Foundation.DNS_ERROR_LOAD_ZONESCOPE_FAILED +Windows.Win32.Foundation.DNS_ERROR_NAME_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_NAME_NOT_IN_ZONE +Windows.Win32.Foundation.DNS_ERROR_NBSTAT_INIT_FAILED +Windows.Win32.Foundation.DNS_ERROR_NEED_SECONDARY_ADDRESSES +Windows.Win32.Foundation.DNS_ERROR_NEED_WINS_SERVERS +Windows.Win32.Foundation.DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE +Windows.Win32.Foundation.DNS_ERROR_NO_CREATE_CACHE_DATA +Windows.Win32.Foundation.DNS_ERROR_NO_DNS_SERVERS +Windows.Win32.Foundation.DNS_ERROR_NO_MEMORY +Windows.Win32.Foundation.DNS_ERROR_NO_PACKET +Windows.Win32.Foundation.DNS_ERROR_NO_TCPIP +Windows.Win32.Foundation.DNS_ERROR_NO_VALID_TRUST_ANCHORS +Windows.Win32.Foundation.DNS_ERROR_NO_ZONE_INFO +Windows.Win32.Foundation.DNS_ERROR_NODE_CREATION_FAILED +Windows.Win32.Foundation.DNS_ERROR_NODE_IS_CNAME +Windows.Win32.Foundation.DNS_ERROR_NODE_IS_DNAME +Windows.Win32.Foundation.DNS_ERROR_NON_RFC_NAME +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_RODC +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_ON_ZSK +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_UNDER_DNAME +Windows.Win32.Foundation.DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES +Windows.Win32.Foundation.DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS +Windows.Win32.Foundation.DNS_ERROR_NOT_UNIQUE +Windows.Win32.Foundation.DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1 +Windows.Win32.Foundation.DNS_ERROR_NSEC3_NAME_COLLISION +Windows.Win32.Foundation.DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1 +Windows.Win32.Foundation.DNS_ERROR_NUMERIC_NAME +Windows.Win32.Foundation.DNS_ERROR_POLICY_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_POLICY_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_NAME +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_SETTINGS +Windows.Win32.Foundation.DNS_ERROR_POLICY_INVALID_WEIGHT +Windows.Win32.Foundation.DNS_ERROR_POLICY_LOCKED +Windows.Win32.Foundation.DNS_ERROR_POLICY_MISSING_CRITERIA +Windows.Win32.Foundation.DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID +Windows.Win32.Foundation.DNS_ERROR_POLICY_SCOPE_MISSING +Windows.Win32.Foundation.DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED +Windows.Win32.Foundation.DNS_ERROR_PRIMARY_REQUIRES_DATAFILE +Windows.Win32.Foundation.DNS_ERROR_RCODE +Windows.Win32.Foundation.DNS_ERROR_RCODE_BADKEY +Windows.Win32.Foundation.DNS_ERROR_RCODE_BADSIG +Windows.Win32.Foundation.DNS_ERROR_RCODE_BADTIME +Windows.Win32.Foundation.DNS_ERROR_RCODE_FORMAT_ERROR +Windows.Win32.Foundation.DNS_ERROR_RCODE_NAME_ERROR +Windows.Win32.Foundation.DNS_ERROR_RCODE_NOT_IMPLEMENTED +Windows.Win32.Foundation.DNS_ERROR_RCODE_NOTAUTH +Windows.Win32.Foundation.DNS_ERROR_RCODE_NOTZONE +Windows.Win32.Foundation.DNS_ERROR_RCODE_NXRRSET +Windows.Win32.Foundation.DNS_ERROR_RCODE_REFUSED +Windows.Win32.Foundation.DNS_ERROR_RCODE_SERVER_FAILURE +Windows.Win32.Foundation.DNS_ERROR_RCODE_YXDOMAIN +Windows.Win32.Foundation.DNS_ERROR_RCODE_YXRRSET +Windows.Win32.Foundation.DNS_ERROR_RECORD_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_RECORD_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_RECORD_FORMAT +Windows.Win32.Foundation.DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT +Windows.Win32.Foundation.DNS_ERROR_RECORD_TIMED_OUT +Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_ALREADY_QUEUED +Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_IN_PROGRESS +Windows.Win32.Foundation.DNS_ERROR_ROLLOVER_NOT_POKEABLE +Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_IPV4_PREFIX +Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_IPV6_PREFIX +Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_LEAK_RATE +Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_TC_RATE +Windows.Win32.Foundation.DNS_ERROR_RRL_INVALID_WINDOW_SIZE +Windows.Win32.Foundation.DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE +Windows.Win32.Foundation.DNS_ERROR_RRL_NOT_ENABLED +Windows.Win32.Foundation.DNS_ERROR_SCOPE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_SCOPE_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_SCOPE_LOCKED +Windows.Win32.Foundation.DNS_ERROR_SECONDARY_DATA +Windows.Win32.Foundation.DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP +Windows.Win32.Foundation.DNS_ERROR_SERVERSCOPE_IS_REFERENCED +Windows.Win32.Foundation.DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE +Windows.Win32.Foundation.DNS_ERROR_SOA_DELETE_INVALID +Windows.Win32.Foundation.DNS_ERROR_STANDBY_KEY_NOT_PRESENT +Windows.Win32.Foundation.DNS_ERROR_SUBNET_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_SUBNET_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_TOO_MANY_SKDS +Windows.Win32.Foundation.DNS_ERROR_TRY_AGAIN_LATER +Windows.Win32.Foundation.DNS_ERROR_UNEXPECTED_CNG_ERROR +Windows.Win32.Foundation.DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR +Windows.Win32.Foundation.DNS_ERROR_UNKNOWN_RECORD_TYPE +Windows.Win32.Foundation.DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION +Windows.Win32.Foundation.DNS_ERROR_UNSECURE_PACKET +Windows.Win32.Foundation.DNS_ERROR_UNSUPPORTED_ALGORITHM +Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_VIRTUALIZATION_TREE_LOCKED +Windows.Win32.Foundation.DNS_ERROR_WINS_INIT_FAILED +Windows.Win32.Foundation.DNS_ERROR_ZONE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_ZONE_CONFIGURATION_ERROR +Windows.Win32.Foundation.DNS_ERROR_ZONE_CREATION_FAILED +Windows.Win32.Foundation.DNS_ERROR_ZONE_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_ZONE_HAS_NO_NS_RECORDS +Windows.Win32.Foundation.DNS_ERROR_ZONE_HAS_NO_SOA_RECORD +Windows.Win32.Foundation.DNS_ERROR_ZONE_IS_SHUTDOWN +Windows.Win32.Foundation.DNS_ERROR_ZONE_LOCKED +Windows.Win32.Foundation.DNS_ERROR_ZONE_LOCKED_FOR_SIGNING +Windows.Win32.Foundation.DNS_ERROR_ZONE_NOT_SECONDARY +Windows.Win32.Foundation.DNS_ERROR_ZONE_REQUIRES_MASTER_IP +Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_ALREADY_EXISTS +Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST +Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED +Windows.Win32.Foundation.DNS_ERROR_ZONESCOPE_IS_REFERENCED +Windows.Win32.Foundation.DUPLICATE_CLOSE_SOURCE +Windows.Win32.Foundation.DUPLICATE_HANDLE_OPTIONS +Windows.Win32.Foundation.DUPLICATE_SAME_ACCESS +Windows.Win32.Foundation.DuplicateHandle +Windows.Win32.Foundation.E_NOTIMPL +Windows.Win32.Foundation.ERROR_ABANDON_HIBERFILE +Windows.Win32.Foundation.ERROR_ABANDONED_WAIT_0 +Windows.Win32.Foundation.ERROR_ABANDONED_WAIT_63 +Windows.Win32.Foundation.ERROR_ABIOS_ERROR +Windows.Win32.Foundation.ERROR_ACCESS_AUDIT_BY_POLICY +Windows.Win32.Foundation.ERROR_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_ACCESS_DENIED_APPDATA +Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_BY_POLICY +Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY +Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_WEBBLADE +Windows.Win32.Foundation.ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER +Windows.Win32.Foundation.ERROR_ACCOUNT_DISABLED +Windows.Win32.Foundation.ERROR_ACCOUNT_EXPIRED +Windows.Win32.Foundation.ERROR_ACCOUNT_LOCKED_OUT +Windows.Win32.Foundation.ERROR_ACCOUNT_RESTRICTION +Windows.Win32.Foundation.ERROR_ACPI_ERROR +Windows.Win32.Foundation.ERROR_ACTIVE_CONNECTIONS +Windows.Win32.Foundation.ERROR_ADAP_HDW_ERR +Windows.Win32.Foundation.ERROR_ADDRESS_ALREADY_ASSOCIATED +Windows.Win32.Foundation.ERROR_ADDRESS_NOT_ASSOCIATED +Windows.Win32.Foundation.ERROR_ALERTED +Windows.Win32.Foundation.ERROR_ALIAS_EXISTS +Windows.Win32.Foundation.ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_ALLOCATE_BUCKET +Windows.Win32.Foundation.ERROR_ALLOTTED_SPACE_EXCEEDED +Windows.Win32.Foundation.ERROR_ALREADY_ASSIGNED +Windows.Win32.Foundation.ERROR_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_ALREADY_FIBER +Windows.Win32.Foundation.ERROR_ALREADY_HAS_STREAM_ID +Windows.Win32.Foundation.ERROR_ALREADY_INITIALIZED +Windows.Win32.Foundation.ERROR_ALREADY_REGISTERED +Windows.Win32.Foundation.ERROR_ALREADY_RUNNING_LKG +Windows.Win32.Foundation.ERROR_ALREADY_THREAD +Windows.Win32.Foundation.ERROR_ALREADY_WAITING +Windows.Win32.Foundation.ERROR_ALREADY_WIN32 +Windows.Win32.Foundation.ERROR_API_UNAVAILABLE +Windows.Win32.Foundation.ERROR_APP_HANG +Windows.Win32.Foundation.ERROR_APP_INIT_FAILURE +Windows.Win32.Foundation.ERROR_APP_WRONG_OS +Windows.Win32.Foundation.ERROR_APPCONTAINER_REQUIRED +Windows.Win32.Foundation.ERROR_APPEXEC_APP_COMPAT_BLOCK +Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT +Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_LICENSING +Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_RESOURCES +Windows.Win32.Foundation.ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_TERMINATION +Windows.Win32.Foundation.ERROR_APPEXEC_CONDITION_NOT_SATISFIED +Windows.Win32.Foundation.ERROR_APPEXEC_HANDLE_INVALIDATED +Windows.Win32.Foundation.ERROR_APPEXEC_HOST_ID_MISMATCH +Windows.Win32.Foundation.ERROR_APPEXEC_INVALID_HOST_GENERATION +Windows.Win32.Foundation.ERROR_APPEXEC_INVALID_HOST_STATE +Windows.Win32.Foundation.ERROR_APPEXEC_NO_DONOR +Windows.Win32.Foundation.ERROR_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION +Windows.Win32.Foundation.ERROR_APPEXEC_UNKNOWN_USER +Windows.Win32.Foundation.ERROR_APPHELP_BLOCK +Windows.Win32.Foundation.ERROR_APPX_FILE_NOT_ENCRYPTED +Windows.Win32.Foundation.ERROR_ARBITRATION_UNHANDLED +Windows.Win32.Foundation.ERROR_ARENA_TRASHED +Windows.Win32.Foundation.ERROR_ARITHMETIC_OVERFLOW +Windows.Win32.Foundation.ERROR_ASSERTION_FAILURE +Windows.Win32.Foundation.ERROR_ATOMIC_LOCKS_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_AUDIT_FAILED +Windows.Win32.Foundation.ERROR_AUTHENTICATION_FIREWALL_FAILED +Windows.Win32.Foundation.ERROR_AUTHIP_FAILURE +Windows.Win32.Foundation.ERROR_AUTODATASEG_EXCEEDS_64k +Windows.Win32.Foundation.ERROR_BACKUP_CONTROLLER +Windows.Win32.Foundation.ERROR_BAD_ACCESSOR_FLAGS +Windows.Win32.Foundation.ERROR_BAD_ARGUMENTS +Windows.Win32.Foundation.ERROR_BAD_COMMAND +Windows.Win32.Foundation.ERROR_BAD_COMPRESSION_BUFFER +Windows.Win32.Foundation.ERROR_BAD_CONFIGURATION +Windows.Win32.Foundation.ERROR_BAD_CURRENT_DIRECTORY +Windows.Win32.Foundation.ERROR_BAD_DESCRIPTOR_FORMAT +Windows.Win32.Foundation.ERROR_BAD_DEV_TYPE +Windows.Win32.Foundation.ERROR_BAD_DEVICE +Windows.Win32.Foundation.ERROR_BAD_DEVICE_PATH +Windows.Win32.Foundation.ERROR_BAD_DLL_ENTRYPOINT +Windows.Win32.Foundation.ERROR_BAD_DRIVER_LEVEL +Windows.Win32.Foundation.ERROR_BAD_ENVIRONMENT +Windows.Win32.Foundation.ERROR_BAD_EXE_FORMAT +Windows.Win32.Foundation.ERROR_BAD_FILE_TYPE +Windows.Win32.Foundation.ERROR_BAD_FORMAT +Windows.Win32.Foundation.ERROR_BAD_FUNCTION_TABLE +Windows.Win32.Foundation.ERROR_BAD_IMPERSONATION_LEVEL +Windows.Win32.Foundation.ERROR_BAD_INHERITANCE_ACL +Windows.Win32.Foundation.ERROR_BAD_LENGTH +Windows.Win32.Foundation.ERROR_BAD_LOGON_SESSION_STATE +Windows.Win32.Foundation.ERROR_BAD_MCFG_TABLE +Windows.Win32.Foundation.ERROR_BAD_NET_NAME +Windows.Win32.Foundation.ERROR_BAD_NET_RESP +Windows.Win32.Foundation.ERROR_BAD_NETPATH +Windows.Win32.Foundation.ERROR_BAD_PATHNAME +Windows.Win32.Foundation.ERROR_BAD_PIPE +Windows.Win32.Foundation.ERROR_BAD_PROFILE +Windows.Win32.Foundation.ERROR_BAD_PROVIDER +Windows.Win32.Foundation.ERROR_BAD_QUERY_SYNTAX +Windows.Win32.Foundation.ERROR_BAD_RECOVERY_POLICY +Windows.Win32.Foundation.ERROR_BAD_REM_ADAP +Windows.Win32.Foundation.ERROR_BAD_SERVICE_ENTRYPOINT +Windows.Win32.Foundation.ERROR_BAD_STACK +Windows.Win32.Foundation.ERROR_BAD_THREADID_ADDR +Windows.Win32.Foundation.ERROR_BAD_TOKEN_TYPE +Windows.Win32.Foundation.ERROR_BAD_UNIT +Windows.Win32.Foundation.ERROR_BAD_USER_PROFILE +Windows.Win32.Foundation.ERROR_BAD_USERNAME +Windows.Win32.Foundation.ERROR_BAD_VALIDATION_CLASS +Windows.Win32.Foundation.ERROR_BADDB +Windows.Win32.Foundation.ERROR_BADKEY +Windows.Win32.Foundation.ERROR_BADSTARTPOSITION +Windows.Win32.Foundation.ERROR_BEGINNING_OF_MEDIA +Windows.Win32.Foundation.ERROR_BEYOND_VDL +Windows.Win32.Foundation.ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT +Windows.Win32.Foundation.ERROR_BLOCK_SHARED +Windows.Win32.Foundation.ERROR_BLOCK_SOURCE_WEAK_REFERENCE_INVALID +Windows.Win32.Foundation.ERROR_BLOCK_TARGET_WEAK_REFERENCE_INVALID +Windows.Win32.Foundation.ERROR_BLOCK_TOO_MANY_REFERENCES +Windows.Win32.Foundation.ERROR_BLOCK_WEAK_REFERENCE_INVALID +Windows.Win32.Foundation.ERROR_BLOCKED_BY_PARENTAL_CONTROLS +Windows.Win32.Foundation.ERROR_BOOT_ALREADY_ACCEPTED +Windows.Win32.Foundation.ERROR_BROKEN_PIPE +Windows.Win32.Foundation.ERROR_BUFFER_ALL_ZEROS +Windows.Win32.Foundation.ERROR_BUFFER_OVERFLOW +Windows.Win32.Foundation.ERROR_BUS_RESET +Windows.Win32.Foundation.ERROR_BUSY +Windows.Win32.Foundation.ERROR_BUSY_DRIVE +Windows.Win32.Foundation.ERROR_BYPASSIO_FLT_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_CACHE_PAGE_LOCKED +Windows.Win32.Foundation.ERROR_CALL_NOT_IMPLEMENTED +Windows.Win32.Foundation.ERROR_CALLBACK_INVOKE_INLINE +Windows.Win32.Foundation.ERROR_CALLBACK_POP_STACK +Windows.Win32.Foundation.ERROR_CALLBACK_SUPPLIED_INVALID_DATA +Windows.Win32.Foundation.ERROR_CAN_NOT_COMPLETE +Windows.Win32.Foundation.ERROR_CANCEL_VIOLATION +Windows.Win32.Foundation.ERROR_CANCELLED +Windows.Win32.Foundation.ERROR_CANNOT_BREAK_OPLOCK +Windows.Win32.Foundation.ERROR_CANNOT_COPY +Windows.Win32.Foundation.ERROR_CANNOT_DETECT_DRIVER_FAILURE +Windows.Win32.Foundation.ERROR_CANNOT_DETECT_PROCESS_ABORT +Windows.Win32.Foundation.ERROR_CANNOT_FIND_WND_CLASS +Windows.Win32.Foundation.ERROR_CANNOT_GRANT_REQUESTED_OPLOCK +Windows.Win32.Foundation.ERROR_CANNOT_IMPERSONATE +Windows.Win32.Foundation.ERROR_CANNOT_LOAD_REGISTRY_FILE +Windows.Win32.Foundation.ERROR_CANNOT_MAKE +Windows.Win32.Foundation.ERROR_CANNOT_OPEN_PROFILE +Windows.Win32.Foundation.ERROR_CANT_ACCESS_DOMAIN_INFO +Windows.Win32.Foundation.ERROR_CANT_ACCESS_FILE +Windows.Win32.Foundation.ERROR_CANT_CLEAR_ENCRYPTION_FLAG +Windows.Win32.Foundation.ERROR_CANT_DISABLE_MANDATORY +Windows.Win32.Foundation.ERROR_CANT_ENABLE_DENY_ONLY +Windows.Win32.Foundation.ERROR_CANT_OPEN_ANONYMOUS +Windows.Win32.Foundation.ERROR_CANT_RESOLVE_FILENAME +Windows.Win32.Foundation.ERROR_CANT_TERMINATE_SELF +Windows.Win32.Foundation.ERROR_CANT_WAIT +Windows.Win32.Foundation.ERROR_CANTFETCHBACKWARDS +Windows.Win32.Foundation.ERROR_CANTOPEN +Windows.Win32.Foundation.ERROR_CANTREAD +Windows.Win32.Foundation.ERROR_CANTSCROLLBACKWARDS +Windows.Win32.Foundation.ERROR_CANTWRITE +Windows.Win32.Foundation.ERROR_CAPAUTHZ_CHANGE_TYPE +Windows.Win32.Foundation.ERROR_CAPAUTHZ_DB_CORRUPTED +Windows.Win32.Foundation.ERROR_CAPAUTHZ_NO_POLICY +Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_AUTHORIZED +Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_DEVUNLOCKED +Windows.Win32.Foundation.ERROR_CAPAUTHZ_NOT_PROVISIONED +Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_DEV_MODE_REQUIRED +Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_INVALID_CATALOG +Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_NO_AUTH_ENTITY +Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_NO_CAPABILITY_MATCH +Windows.Win32.Foundation.ERROR_CAPAUTHZ_SCCD_PARSE_ERROR +Windows.Win32.Foundation.ERROR_CARDBUS_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_CASE_DIFFERING_NAMES_IN_DIR +Windows.Win32.Foundation.ERROR_CASE_SENSITIVE_PATH +Windows.Win32.Foundation.ERROR_CERTIFICATE_VALIDATION_PREFERENCE_CONFLICT +Windows.Win32.Foundation.ERROR_CHECKING_FILE_SYSTEM +Windows.Win32.Foundation.ERROR_CHECKOUT_REQUIRED +Windows.Win32.Foundation.ERROR_CHILD_MUST_BE_VOLATILE +Windows.Win32.Foundation.ERROR_CHILD_NOT_COMPLETE +Windows.Win32.Foundation.ERROR_CHILD_PROCESS_BLOCKED +Windows.Win32.Foundation.ERROR_CHILD_WINDOW_MENU +Windows.Win32.Foundation.ERROR_CIMFS_IMAGE_CORRUPT +Windows.Win32.Foundation.ERROR_CIMFS_IMAGE_VERSION_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_CIRCULAR_DEPENDENCY +Windows.Win32.Foundation.ERROR_CLASS_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_CLASS_DOES_NOT_EXIST +Windows.Win32.Foundation.ERROR_CLASS_HAS_WINDOWS +Windows.Win32.Foundation.ERROR_CLIENT_SERVER_PARAMETERS_INVALID +Windows.Win32.Foundation.ERROR_CLIPBOARD_NOT_OPEN +Windows.Win32.Foundation.ERROR_CLOUD_FILE_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_ALREADY_CONNECTED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_AUTHENTICATION_FAILED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_CONNECTED_PROVIDER_ONLY +Windows.Win32.Foundation.ERROR_CLOUD_FILE_DEHYDRATION_DISALLOWED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_IN_USE +Windows.Win32.Foundation.ERROR_CLOUD_FILE_INCOMPATIBLE_HARDLINKS +Windows.Win32.Foundation.ERROR_CLOUD_FILE_INSUFFICIENT_RESOURCES +Windows.Win32.Foundation.ERROR_CLOUD_FILE_INVALID_REQUEST +Windows.Win32.Foundation.ERROR_CLOUD_FILE_METADATA_CORRUPT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_METADATA_TOO_LARGE +Windows.Win32.Foundation.ERROR_CLOUD_FILE_NETWORK_UNAVAILABLE +Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_IN_SYNC +Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PINNED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_CORRUPT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_LOCK_CONFLICT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING +Windows.Win32.Foundation.ERROR_CLOUD_FILE_PROVIDER_TERMINATED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_READ_ONLY_VOLUME +Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_ABORTED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_CANCELED +Windows.Win32.Foundation.ERROR_CLOUD_FILE_REQUEST_TIMEOUT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS +Windows.Win32.Foundation.ERROR_CLOUD_FILE_UNSUCCESSFUL +Windows.Win32.Foundation.ERROR_CLOUD_FILE_US_MESSAGE_TIMEOUT +Windows.Win32.Foundation.ERROR_CLOUD_FILE_VALIDATION_FAILED +Windows.Win32.Foundation.ERROR_COMMITMENT_LIMIT +Windows.Win32.Foundation.ERROR_COMMITMENT_MINIMUM +Windows.Win32.Foundation.ERROR_COMPRESSED_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_COMPRESSION_DISABLED +Windows.Win32.Foundation.ERROR_COMPRESSION_NOT_BENEFICIAL +Windows.Win32.Foundation.ERROR_CONNECTED_OTHER_PASSWORD +Windows.Win32.Foundation.ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT +Windows.Win32.Foundation.ERROR_CONNECTION_ABORTED +Windows.Win32.Foundation.ERROR_CONNECTION_ACTIVE +Windows.Win32.Foundation.ERROR_CONNECTION_COUNT_LIMIT +Windows.Win32.Foundation.ERROR_CONNECTION_INVALID +Windows.Win32.Foundation.ERROR_CONNECTION_REFUSED +Windows.Win32.Foundation.ERROR_CONNECTION_UNAVAIL +Windows.Win32.Foundation.ERROR_CONTAINER_ASSIGNED +Windows.Win32.Foundation.ERROR_CONTENT_BLOCKED +Windows.Win32.Foundation.ERROR_CONTEXT_EXPIRED +Windows.Win32.Foundation.ERROR_CONTINUE +Windows.Win32.Foundation.ERROR_CONTROL_C_EXIT +Windows.Win32.Foundation.ERROR_CONTROL_ID_NOT_FOUND +Windows.Win32.Foundation.ERROR_CONVERT_TO_LARGE +Windows.Win32.Foundation.ERROR_CORRUPT_LOG_CLEARED +Windows.Win32.Foundation.ERROR_CORRUPT_LOG_CORRUPTED +Windows.Win32.Foundation.ERROR_CORRUPT_LOG_DELETED_FULL +Windows.Win32.Foundation.ERROR_CORRUPT_LOG_OVERFULL +Windows.Win32.Foundation.ERROR_CORRUPT_LOG_UNAVAILABLE +Windows.Win32.Foundation.ERROR_CORRUPT_SYSTEM_FILE +Windows.Win32.Foundation.ERROR_COULD_NOT_INTERPRET +Windows.Win32.Foundation.ERROR_COUNTER_TIMEOUT +Windows.Win32.Foundation.ERROR_CPU_SET_INVALID +Windows.Win32.Foundation.ERROR_CRASH_DUMP +Windows.Win32.Foundation.ERROR_CRC +Windows.Win32.Foundation.ERROR_CREATE_FAILED +Windows.Win32.Foundation.ERROR_CROSS_PARTITION_VIOLATION +Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE +Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_FILE_NOT_CSE +Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE +Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE +Windows.Win32.Foundation.ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER +Windows.Win32.Foundation.ERROR_CSCSHARE_OFFLINE +Windows.Win32.Foundation.ERROR_CTX_CLIENT_QUERY_TIMEOUT +Windows.Win32.Foundation.ERROR_CTX_MODEM_RESPONSE_TIMEOUT +Windows.Win32.Foundation.ERROR_CURRENT_DIRECTORY +Windows.Win32.Foundation.ERROR_CURRENT_DOMAIN_NOT_ALLOWED +Windows.Win32.Foundation.ERROR_DATA_CHECKSUM_ERROR +Windows.Win32.Foundation.ERROR_DATA_NOT_ACCEPTED +Windows.Win32.Foundation.ERROR_DATABASE_DOES_NOT_EXIST +Windows.Win32.Foundation.ERROR_DATATYPE_MISMATCH +Windows.Win32.Foundation.ERROR_DAX_MAPPING_EXISTS +Windows.Win32.Foundation.ERROR_DBG_COMMAND_EXCEPTION +Windows.Win32.Foundation.ERROR_DBG_CONTINUE +Windows.Win32.Foundation.ERROR_DBG_CONTROL_BREAK +Windows.Win32.Foundation.ERROR_DBG_CONTROL_C +Windows.Win32.Foundation.ERROR_DBG_EXCEPTION_HANDLED +Windows.Win32.Foundation.ERROR_DBG_EXCEPTION_NOT_HANDLED +Windows.Win32.Foundation.ERROR_DBG_PRINTEXCEPTION_C +Windows.Win32.Foundation.ERROR_DBG_REPLY_LATER +Windows.Win32.Foundation.ERROR_DBG_RIPEXCEPTION +Windows.Win32.Foundation.ERROR_DBG_TERMINATE_PROCESS +Windows.Win32.Foundation.ERROR_DBG_TERMINATE_THREAD +Windows.Win32.Foundation.ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE +Windows.Win32.Foundation.ERROR_DC_NOT_FOUND +Windows.Win32.Foundation.ERROR_DDE_FAIL +Windows.Win32.Foundation.ERROR_DEBUG_ATTACH_FAILED +Windows.Win32.Foundation.ERROR_DEBUGGER_INACTIVE +Windows.Win32.Foundation.ERROR_DECRYPTION_FAILED +Windows.Win32.Foundation.ERROR_DELAY_LOAD_FAILED +Windows.Win32.Foundation.ERROR_DELETE_PENDING +Windows.Win32.Foundation.ERROR_DEPENDENT_SERVICES_RUNNING +Windows.Win32.Foundation.ERROR_DESTINATION_ELEMENT_FULL +Windows.Win32.Foundation.ERROR_DESTROY_OBJECT_OF_OTHER_THREAD +Windows.Win32.Foundation.ERROR_DEV_NOT_EXIST +Windows.Win32.Foundation.ERROR_DEVICE_ALREADY_ATTACHED +Windows.Win32.Foundation.ERROR_DEVICE_ALREADY_REMEMBERED +Windows.Win32.Foundation.ERROR_DEVICE_DOOR_OPEN +Windows.Win32.Foundation.ERROR_DEVICE_ENUMERATION_ERROR +Windows.Win32.Foundation.ERROR_DEVICE_FEATURE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_DEVICE_HARDWARE_ERROR +Windows.Win32.Foundation.ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL +Windows.Win32.Foundation.ERROR_DEVICE_IN_MAINTENANCE +Windows.Win32.Foundation.ERROR_DEVICE_IN_USE +Windows.Win32.Foundation.ERROR_DEVICE_NO_RESOURCES +Windows.Win32.Foundation.ERROR_DEVICE_NOT_CONNECTED +Windows.Win32.Foundation.ERROR_DEVICE_NOT_PARTITIONED +Windows.Win32.Foundation.ERROR_DEVICE_REINITIALIZATION_NEEDED +Windows.Win32.Foundation.ERROR_DEVICE_REMOVED +Windows.Win32.Foundation.ERROR_DEVICE_REQUIRES_CLEANING +Windows.Win32.Foundation.ERROR_DEVICE_RESET_REQUIRED +Windows.Win32.Foundation.ERROR_DEVICE_SUPPORT_IN_PROGRESS +Windows.Win32.Foundation.ERROR_DEVICE_UNREACHABLE +Windows.Win32.Foundation.ERROR_DHCP_ADDRESS_CONFLICT +Windows.Win32.Foundation.ERROR_DIFFERENT_SERVICE_ACCOUNT +Windows.Win32.Foundation.ERROR_DIR_EFS_DISALLOWED +Windows.Win32.Foundation.ERROR_DIR_NOT_EMPTY +Windows.Win32.Foundation.ERROR_DIR_NOT_ROOT +Windows.Win32.Foundation.ERROR_DIRECT_ACCESS_HANDLE +Windows.Win32.Foundation.ERROR_DIRECTORY +Windows.Win32.Foundation.ERROR_DIRECTORY_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_DISCARDED +Windows.Win32.Foundation.ERROR_DISK_CHANGE +Windows.Win32.Foundation.ERROR_DISK_CORRUPT +Windows.Win32.Foundation.ERROR_DISK_FULL +Windows.Win32.Foundation.ERROR_DISK_OPERATION_FAILED +Windows.Win32.Foundation.ERROR_DISK_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_DISK_RECALIBRATE_FAILED +Windows.Win32.Foundation.ERROR_DISK_REPAIR_DISABLED +Windows.Win32.Foundation.ERROR_DISK_REPAIR_REDIRECTED +Windows.Win32.Foundation.ERROR_DISK_REPAIR_UNSUCCESSFUL +Windows.Win32.Foundation.ERROR_DISK_RESET_FAILED +Windows.Win32.Foundation.ERROR_DISK_RESOURCES_EXHAUSTED +Windows.Win32.Foundation.ERROR_DISK_TOO_FRAGMENTED +Windows.Win32.Foundation.ERROR_DLL_INIT_FAILED +Windows.Win32.Foundation.ERROR_DLL_INIT_FAILED_LOGOFF +Windows.Win32.Foundation.ERROR_DLL_MIGHT_BE_INCOMPATIBLE +Windows.Win32.Foundation.ERROR_DLL_MIGHT_BE_INSECURE +Windows.Win32.Foundation.ERROR_DLL_NOT_FOUND +Windows.Win32.Foundation.ERROR_DLP_POLICY_DENIES_OPERATION +Windows.Win32.Foundation.ERROR_DLP_POLICY_SILENTLY_FAIL +Windows.Win32.Foundation.ERROR_DLP_POLICY_WARNS_AGAINST_OPERATION +Windows.Win32.Foundation.ERROR_DOMAIN_CONTROLLER_EXISTS +Windows.Win32.Foundation.ERROR_DOMAIN_CONTROLLER_NOT_FOUND +Windows.Win32.Foundation.ERROR_DOMAIN_CTRLR_CONFIG_ERROR +Windows.Win32.Foundation.ERROR_DOMAIN_EXISTS +Windows.Win32.Foundation.ERROR_DOMAIN_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION +Windows.Win32.Foundation.ERROR_DOMAIN_TRUST_INCONSISTENT +Windows.Win32.Foundation.ERROR_DOWNGRADE_DETECTED +Windows.Win32.Foundation.ERROR_DPL_NOT_SUPPORTED_FOR_USER +Windows.Win32.Foundation.ERROR_DRIVE_LOCKED +Windows.Win32.Foundation.ERROR_DRIVER_BLOCKED +Windows.Win32.Foundation.ERROR_DRIVER_CANCEL_TIMEOUT +Windows.Win32.Foundation.ERROR_DRIVER_DATABASE_ERROR +Windows.Win32.Foundation.ERROR_DRIVER_FAILED_PRIOR_UNLOAD +Windows.Win32.Foundation.ERROR_DRIVER_FAILED_SLEEP +Windows.Win32.Foundation.ERROR_DRIVER_PROCESS_TERMINATED +Windows.Win32.Foundation.ERROR_DRIVERS_LEAKING_LOCKED_PAGES +Windows.Win32.Foundation.ERROR_DS_ADD_REPLICA_INHIBITED +Windows.Win32.Foundation.ERROR_DS_ADMIN_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_AFFECTS_MULTIPLE_DSAS +Windows.Win32.Foundation.ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER +Windows.Win32.Foundation.ERROR_DS_ALIAS_DEREF_PROBLEM +Windows.Win32.Foundation.ERROR_DS_ALIAS_POINTS_TO_ALIAS +Windows.Win32.Foundation.ERROR_DS_ALIAS_PROBLEM +Windows.Win32.Foundation.ERROR_DS_ALIASED_OBJ_MISSING +Windows.Win32.Foundation.ERROR_DS_ATT_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_DS_ATT_IS_NOT_ON_OBJ +Windows.Win32.Foundation.ERROR_DS_ATT_NOT_DEF_FOR_CLASS +Windows.Win32.Foundation.ERROR_DS_ATT_NOT_DEF_IN_SCHEMA +Windows.Win32.Foundation.ERROR_DS_ATT_SCHEMA_REQ_ID +Windows.Win32.Foundation.ERROR_DS_ATT_SCHEMA_REQ_SYNTAX +Windows.Win32.Foundation.ERROR_DS_ATT_VAL_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS +Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM +Windows.Win32.Foundation.ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED +Windows.Win32.Foundation.ERROR_DS_AUDIT_FAILURE +Windows.Win32.Foundation.ERROR_DS_AUTH_METHOD_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_DS_AUTH_UNKNOWN +Windows.Win32.Foundation.ERROR_DS_AUTHORIZATION_FAILED +Windows.Win32.Foundation.ERROR_DS_AUX_CLS_TEST_FAIL +Windows.Win32.Foundation.ERROR_DS_BACKLINK_WITHOUT_LINK +Windows.Win32.Foundation.ERROR_DS_BAD_ATT_SCHEMA_SYNTAX +Windows.Win32.Foundation.ERROR_DS_BAD_HIERARCHY_FILE +Windows.Win32.Foundation.ERROR_DS_BAD_INSTANCE_TYPE +Windows.Win32.Foundation.ERROR_DS_BAD_NAME_SYNTAX +Windows.Win32.Foundation.ERROR_DS_BAD_RDN_ATT_ID_SYNTAX +Windows.Win32.Foundation.ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED +Windows.Win32.Foundation.ERROR_DS_BUSY +Windows.Win32.Foundation.ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD +Windows.Win32.Foundation.ERROR_DS_CANT_ADD_ATT_VALUES +Windows.Win32.Foundation.ERROR_DS_CANT_ADD_SYSTEM_ONLY +Windows.Win32.Foundation.ERROR_DS_CANT_ADD_TO_GC +Windows.Win32.Foundation.ERROR_DS_CANT_CACHE_ATT +Windows.Win32.Foundation.ERROR_DS_CANT_CACHE_CLASS +Windows.Win32.Foundation.ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC +Windows.Win32.Foundation.ERROR_DS_CANT_CREATE_UNDER_SCHEMA +Windows.Win32.Foundation.ERROR_DS_CANT_DEL_MASTER_CROSSREF +Windows.Win32.Foundation.ERROR_DS_CANT_DELETE +Windows.Win32.Foundation.ERROR_DS_CANT_DELETE_DSA_OBJ +Windows.Win32.Foundation.ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC +Windows.Win32.Foundation.ERROR_DS_CANT_DEREF_ALIAS +Windows.Win32.Foundation.ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN +Windows.Win32.Foundation.ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF +Windows.Win32.Foundation.ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN +Windows.Win32.Foundation.ERROR_DS_CANT_FIND_DSA_OBJ +Windows.Win32.Foundation.ERROR_DS_CANT_FIND_EXPECTED_NC +Windows.Win32.Foundation.ERROR_DS_CANT_FIND_NC_IN_CACHE +Windows.Win32.Foundation.ERROR_DS_CANT_MIX_MASTER_AND_REPS +Windows.Win32.Foundation.ERROR_DS_CANT_MOD_OBJ_CLASS +Windows.Win32.Foundation.ERROR_DS_CANT_MOD_PRIMARYGROUPID +Windows.Win32.Foundation.ERROR_DS_CANT_MOD_SYSTEM_ONLY +Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_ACCOUNT_GROUP +Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_APP_BASIC_GROUP +Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_APP_QUERY_GROUP +Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_DELETED_OBJECT +Windows.Win32.Foundation.ERROR_DS_CANT_MOVE_RESOURCE_GROUP +Windows.Win32.Foundation.ERROR_DS_CANT_ON_NON_LEAF +Windows.Win32.Foundation.ERROR_DS_CANT_ON_RDN +Windows.Win32.Foundation.ERROR_DS_CANT_REM_MISSING_ATT +Windows.Win32.Foundation.ERROR_DS_CANT_REM_MISSING_ATT_VAL +Windows.Win32.Foundation.ERROR_DS_CANT_REMOVE_ATT_CACHE +Windows.Win32.Foundation.ERROR_DS_CANT_REMOVE_CLASS_CACHE +Windows.Win32.Foundation.ERROR_DS_CANT_REPLACE_HIDDEN_REC +Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_ATTS +Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_CHILD +Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_DN +Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_INSTANCE +Windows.Win32.Foundation.ERROR_DS_CANT_RETRIEVE_SD +Windows.Win32.Foundation.ERROR_DS_CANT_START +Windows.Win32.Foundation.ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ +Windows.Win32.Foundation.ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS +Windows.Win32.Foundation.ERROR_DS_CHILDREN_EXIST +Windows.Win32.Foundation.ERROR_DS_CLASS_MUST_BE_CONCRETE +Windows.Win32.Foundation.ERROR_DS_CLASS_NOT_DSA +Windows.Win32.Foundation.ERROR_DS_CLIENT_LOOP +Windows.Win32.Foundation.ERROR_DS_CODE_INCONSISTENCY +Windows.Win32.Foundation.ERROR_DS_COMPARE_FALSE +Windows.Win32.Foundation.ERROR_DS_COMPARE_TRUE +Windows.Win32.Foundation.ERROR_DS_CONFIDENTIALITY_REQUIRED +Windows.Win32.Foundation.ERROR_DS_CONFIG_PARAM_MISSING +Windows.Win32.Foundation.ERROR_DS_CONSTRAINT_VIOLATION +Windows.Win32.Foundation.ERROR_DS_CONSTRUCTED_ATT_MOD +Windows.Win32.Foundation.ERROR_DS_CONTROL_NOT_FOUND +Windows.Win32.Foundation.ERROR_DS_COULDNT_CONTACT_FSMO +Windows.Win32.Foundation.ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE +Windows.Win32.Foundation.ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE +Windows.Win32.Foundation.ERROR_DS_COULDNT_UPDATE_SPNS +Windows.Win32.Foundation.ERROR_DS_COUNTING_AB_INDICES_FAILED +Windows.Win32.Foundation.ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE +Windows.Win32.Foundation.ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 +Windows.Win32.Foundation.ERROR_DS_CROSS_DOM_MOVE_ERROR +Windows.Win32.Foundation.ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD +Windows.Win32.Foundation.ERROR_DS_CROSS_NC_DN_RENAME +Windows.Win32.Foundation.ERROR_DS_CROSS_REF_BUSY +Windows.Win32.Foundation.ERROR_DS_CROSS_REF_EXISTS +Windows.Win32.Foundation.ERROR_DS_DATABASE_ERROR +Windows.Win32.Foundation.ERROR_DS_DECODING_ERROR +Windows.Win32.Foundation.ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED +Windows.Win32.Foundation.ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_DIFFERENT_REPL_EPOCHS +Windows.Win32.Foundation.ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER +Windows.Win32.Foundation.ERROR_DS_DISALLOWED_NC_REDIRECT +Windows.Win32.Foundation.ERROR_DS_DNS_LOOKUP_FAILURE +Windows.Win32.Foundation.ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_DOMAIN_RENAME_IN_PROGRESS +Windows.Win32.Foundation.ERROR_DS_DOMAIN_VERSION_TOO_HIGH +Windows.Win32.Foundation.ERROR_DS_DOMAIN_VERSION_TOO_LOW +Windows.Win32.Foundation.ERROR_DS_DRA_ABANDON_SYNC +Windows.Win32.Foundation.ERROR_DS_DRA_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_DS_DRA_BAD_DN +Windows.Win32.Foundation.ERROR_DS_DRA_BAD_INSTANCE_TYPE +Windows.Win32.Foundation.ERROR_DS_DRA_BAD_NC +Windows.Win32.Foundation.ERROR_DS_DRA_BUSY +Windows.Win32.Foundation.ERROR_DS_DRA_CONNECTION_FAILED +Windows.Win32.Foundation.ERROR_DS_DRA_CORRUPT_UTD_VECTOR +Windows.Win32.Foundation.ERROR_DS_DRA_DB_ERROR +Windows.Win32.Foundation.ERROR_DS_DRA_DN_EXISTS +Windows.Win32.Foundation.ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT +Windows.Win32.Foundation.ERROR_DS_DRA_EXTN_CONNECTION_FAILED +Windows.Win32.Foundation.ERROR_DS_DRA_GENERIC +Windows.Win32.Foundation.ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET +Windows.Win32.Foundation.ERROR_DS_DRA_INCONSISTENT_DIT +Windows.Win32.Foundation.ERROR_DS_DRA_INTERNAL_ERROR +Windows.Win32.Foundation.ERROR_DS_DRA_INVALID_PARAMETER +Windows.Win32.Foundation.ERROR_DS_DRA_MAIL_PROBLEM +Windows.Win32.Foundation.ERROR_DS_DRA_MISSING_KRBTGT_SECRET +Windows.Win32.Foundation.ERROR_DS_DRA_MISSING_PARENT +Windows.Win32.Foundation.ERROR_DS_DRA_NAME_COLLISION +Windows.Win32.Foundation.ERROR_DS_DRA_NO_REPLICA +Windows.Win32.Foundation.ERROR_DS_DRA_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_DS_DRA_OBJ_IS_REP_SOURCE +Windows.Win32.Foundation.ERROR_DS_DRA_OBJ_NC_MISMATCH +Windows.Win32.Foundation.ERROR_DS_DRA_OUT_OF_MEM +Windows.Win32.Foundation.ERROR_DS_DRA_OUT_SCHEDULE_WINDOW +Windows.Win32.Foundation.ERROR_DS_DRA_PREEMPTED +Windows.Win32.Foundation.ERROR_DS_DRA_RECYCLED_TARGET +Windows.Win32.Foundation.ERROR_DS_DRA_REF_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_DS_DRA_REF_NOT_FOUND +Windows.Win32.Foundation.ERROR_DS_DRA_REPL_PENDING +Windows.Win32.Foundation.ERROR_DS_DRA_RPC_CANCELLED +Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_CONFLICT +Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_INFO_SHIP +Windows.Win32.Foundation.ERROR_DS_DRA_SCHEMA_MISMATCH +Windows.Win32.Foundation.ERROR_DS_DRA_SECRETS_DENIED +Windows.Win32.Foundation.ERROR_DS_DRA_SHUTDOWN +Windows.Win32.Foundation.ERROR_DS_DRA_SINK_DISABLED +Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_DISABLED +Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA +Windows.Win32.Foundation.ERROR_DS_DRA_SOURCE_REINSTALLED +Windows.Win32.Foundation.ERROR_DS_DRS_EXTENSIONS_CHANGED +Windows.Win32.Foundation.ERROR_DS_DS_REQUIRED +Windows.Win32.Foundation.ERROR_DS_DSA_MUST_BE_INT_MASTER +Windows.Win32.Foundation.ERROR_DS_DST_DOMAIN_NOT_NATIVE +Windows.Win32.Foundation.ERROR_DS_DST_NC_MISMATCH +Windows.Win32.Foundation.ERROR_DS_DUP_LDAP_DISPLAY_NAME +Windows.Win32.Foundation.ERROR_DS_DUP_LINK_ID +Windows.Win32.Foundation.ERROR_DS_DUP_MAPI_ID +Windows.Win32.Foundation.ERROR_DS_DUP_MSDS_INTID +Windows.Win32.Foundation.ERROR_DS_DUP_OID +Windows.Win32.Foundation.ERROR_DS_DUP_RDN +Windows.Win32.Foundation.ERROR_DS_DUP_SCHEMA_ID_GUID +Windows.Win32.Foundation.ERROR_DS_DUPLICATE_ID_FOUND +Windows.Win32.Foundation.ERROR_DS_ENCODING_ERROR +Windows.Win32.Foundation.ERROR_DS_EPOCH_MISMATCH +Windows.Win32.Foundation.ERROR_DS_EXISTING_AD_CHILD_NC +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_AUX_CLS +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_MAY_HAVE +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_MUST_HAVE +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_POSS_SUP +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_RDNATTID +Windows.Win32.Foundation.ERROR_DS_EXISTS_IN_SUB_CLS +Windows.Win32.Foundation.ERROR_DS_FILTER_UNKNOWN +Windows.Win32.Foundation.ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS +Windows.Win32.Foundation.ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_FOREST_VERSION_TOO_HIGH +Windows.Win32.Foundation.ERROR_DS_FOREST_VERSION_TOO_LOW +Windows.Win32.Foundation.ERROR_DS_GC_NOT_AVAILABLE +Windows.Win32.Foundation.ERROR_DS_GC_REQUIRED +Windows.Win32.Foundation.ERROR_DS_GCVERIFY_ERROR +Windows.Win32.Foundation.ERROR_DS_GENERIC_ERROR +Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER +Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER +Windows.Win32.Foundation.ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER +Windows.Win32.Foundation.ERROR_DS_GOVERNSID_MISSING +Windows.Win32.Foundation.ERROR_DS_GROUP_CONVERSION_ERROR +Windows.Win32.Foundation.ERROR_DS_HAVE_PRIMARY_MEMBERS +Windows.Win32.Foundation.ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED +Windows.Win32.Foundation.ERROR_DS_HIERARCHY_TABLE_TOO_DEEP +Windows.Win32.Foundation.ERROR_DS_HIGH_ADLDS_FFL +Windows.Win32.Foundation.ERROR_DS_HIGH_DSA_VERSION +Windows.Win32.Foundation.ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD +Windows.Win32.Foundation.ERROR_DS_ILLEGAL_MOD_OPERATION +Windows.Win32.Foundation.ERROR_DS_ILLEGAL_SUPERIOR +Windows.Win32.Foundation.ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION +Windows.Win32.Foundation.ERROR_DS_INAPPROPRIATE_AUTH +Windows.Win32.Foundation.ERROR_DS_INAPPROPRIATE_MATCHING +Windows.Win32.Foundation.ERROR_DS_INCOMPATIBLE_CONTROLS_USED +Windows.Win32.Foundation.ERROR_DS_INCOMPATIBLE_VERSION +Windows.Win32.Foundation.ERROR_DS_INCORRECT_ROLE_OWNER +Windows.Win32.Foundation.ERROR_DS_INIT_FAILURE +Windows.Win32.Foundation.ERROR_DS_INIT_FAILURE_CONSOLE +Windows.Win32.Foundation.ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE +Windows.Win32.Foundation.ERROR_DS_INSTALL_NO_SRC_SCH_VERSION +Windows.Win32.Foundation.ERROR_DS_INSTALL_SCHEMA_MISMATCH +Windows.Win32.Foundation.ERROR_DS_INSUFF_ACCESS_RIGHTS +Windows.Win32.Foundation.ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT +Windows.Win32.Foundation.ERROR_DS_INTERNAL_FAILURE +Windows.Win32.Foundation.ERROR_DS_INVALID_ATTRIBUTE_SYNTAX +Windows.Win32.Foundation.ERROR_DS_INVALID_DMD +Windows.Win32.Foundation.ERROR_DS_INVALID_DN_SYNTAX +Windows.Win32.Foundation.ERROR_DS_INVALID_GROUP_TYPE +Windows.Win32.Foundation.ERROR_DS_INVALID_LDAP_DISPLAY_NAME +Windows.Win32.Foundation.ERROR_DS_INVALID_NAME_FOR_SPN +Windows.Win32.Foundation.ERROR_DS_INVALID_ROLE_OWNER +Windows.Win32.Foundation.ERROR_DS_INVALID_SCRIPT +Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG +Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE +Windows.Win32.Foundation.ERROR_DS_INVALID_SEARCH_FLAG_TUPLE +Windows.Win32.Foundation.ERROR_DS_IS_LEAF +Windows.Win32.Foundation.ERROR_DS_KEY_NOT_UNIQUE +Windows.Win32.Foundation.ERROR_DS_LDAP_SEND_QUEUE_FULL +Windows.Win32.Foundation.ERROR_DS_LINK_ID_NOT_AVAILABLE +Windows.Win32.Foundation.ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER +Windows.Win32.Foundation.ERROR_DS_LOCAL_ERROR +Windows.Win32.Foundation.ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY +Windows.Win32.Foundation.ERROR_DS_LOOP_DETECT +Windows.Win32.Foundation.ERROR_DS_LOW_ADLDS_FFL +Windows.Win32.Foundation.ERROR_DS_LOW_DSA_VERSION +Windows.Win32.Foundation.ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 +Windows.Win32.Foundation.ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_MAPI_ID_NOT_AVAILABLE +Windows.Win32.Foundation.ERROR_DS_MASTERDSA_REQUIRED +Windows.Win32.Foundation.ERROR_DS_MAX_OBJ_SIZE_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY +Windows.Win32.Foundation.ERROR_DS_MISSING_EXPECTED_ATT +Windows.Win32.Foundation.ERROR_DS_MISSING_FOREST_TRUST +Windows.Win32.Foundation.ERROR_DS_MISSING_FSMO_SETTINGS +Windows.Win32.Foundation.ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER +Windows.Win32.Foundation.ERROR_DS_MISSING_REQUIRED_ATT +Windows.Win32.Foundation.ERROR_DS_MISSING_SUPREF +Windows.Win32.Foundation.ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG +Windows.Win32.Foundation.ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE +Windows.Win32.Foundation.ERROR_DS_MODIFYDN_WRONG_GRANDPARENT +Windows.Win32.Foundation.ERROR_DS_MUST_BE_RUN_ON_DST_DC +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_DOMAIN_ONLY +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NO_MAPPING +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NOT_FOUND +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_NOT_UNIQUE +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_RESOLVING +Windows.Win32.Foundation.ERROR_DS_NAME_ERROR_TRUST_REFERRAL +Windows.Win32.Foundation.ERROR_DS_NAME_NOT_UNIQUE +Windows.Win32.Foundation.ERROR_DS_NAME_REFERENCE_INVALID +Windows.Win32.Foundation.ERROR_DS_NAME_TOO_LONG +Windows.Win32.Foundation.ERROR_DS_NAME_TOO_MANY_PARTS +Windows.Win32.Foundation.ERROR_DS_NAME_TYPE_UNKNOWN +Windows.Win32.Foundation.ERROR_DS_NAME_UNPARSEABLE +Windows.Win32.Foundation.ERROR_DS_NAME_VALUE_TOO_LONG +Windows.Win32.Foundation.ERROR_DS_NAMING_MASTER_GC +Windows.Win32.Foundation.ERROR_DS_NAMING_VIOLATION +Windows.Win32.Foundation.ERROR_DS_NC_MUST_HAVE_NC_PARENT +Windows.Win32.Foundation.ERROR_DS_NC_STILL_HAS_DSAS +Windows.Win32.Foundation.ERROR_DS_NCNAME_MISSING_CR_REF +Windows.Win32.Foundation.ERROR_DS_NCNAME_MUST_BE_NC +Windows.Win32.Foundation.ERROR_DS_NO_ATTRIBUTE_OR_VALUE +Windows.Win32.Foundation.ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN +Windows.Win32.Foundation.ERROR_DS_NO_CHAINED_EVAL +Windows.Win32.Foundation.ERROR_DS_NO_CHAINING +Windows.Win32.Foundation.ERROR_DS_NO_CHECKPOINT_WITH_PDC +Windows.Win32.Foundation.ERROR_DS_NO_CROSSREF_FOR_NC +Windows.Win32.Foundation.ERROR_DS_NO_DELETED_NAME +Windows.Win32.Foundation.ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS +Windows.Win32.Foundation.ERROR_DS_NO_MORE_RIDS +Windows.Win32.Foundation.ERROR_DS_NO_MSDS_INTID +Windows.Win32.Foundation.ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN +Windows.Win32.Foundation.ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN +Windows.Win32.Foundation.ERROR_DS_NO_NTDSA_OBJECT +Windows.Win32.Foundation.ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC +Windows.Win32.Foundation.ERROR_DS_NO_PARENT_OBJECT +Windows.Win32.Foundation.ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION +Windows.Win32.Foundation.ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA +Windows.Win32.Foundation.ERROR_DS_NO_REF_DOMAIN +Windows.Win32.Foundation.ERROR_DS_NO_REQUESTED_ATTS_FOUND +Windows.Win32.Foundation.ERROR_DS_NO_RESULTS_RETURNED +Windows.Win32.Foundation.ERROR_DS_NO_RIDS_ALLOCATED +Windows.Win32.Foundation.ERROR_DS_NO_SERVER_OBJECT +Windows.Win32.Foundation.ERROR_DS_NO_SUCH_OBJECT +Windows.Win32.Foundation.ERROR_DS_NO_TREE_DELETE_ABOVE_NC +Windows.Win32.Foundation.ERROR_DS_NON_ASQ_SEARCH +Windows.Win32.Foundation.ERROR_DS_NON_BASE_SEARCH +Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_MAY_HAVE +Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_MUST_HAVE +Windows.Win32.Foundation.ERROR_DS_NONEXISTENT_POSS_SUP +Windows.Win32.Foundation.ERROR_DS_NONSAFE_SCHEMA_CHANGE +Windows.Win32.Foundation.ERROR_DS_NOT_AN_OBJECT +Windows.Win32.Foundation.ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC +Windows.Win32.Foundation.ERROR_DS_NOT_CLOSEST +Windows.Win32.Foundation.ERROR_DS_NOT_INSTALLED +Windows.Win32.Foundation.ERROR_DS_NOT_ON_BACKLINK +Windows.Win32.Foundation.ERROR_DS_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_DS_NOT_SUPPORTED_SORT_ORDER +Windows.Win32.Foundation.ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX +Windows.Win32.Foundation.ERROR_DS_NTDSCRIPT_PROCESS_ERROR +Windows.Win32.Foundation.ERROR_DS_NTDSCRIPT_SYNTAX_ERROR +Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_NOT_DEFINED +Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_NOT_SUBCLASS +Windows.Win32.Foundation.ERROR_DS_OBJ_CLASS_VIOLATION +Windows.Win32.Foundation.ERROR_DS_OBJ_GUID_EXISTS +Windows.Win32.Foundation.ERROR_DS_OBJ_NOT_FOUND +Windows.Win32.Foundation.ERROR_DS_OBJ_STRING_NAME_EXISTS +Windows.Win32.Foundation.ERROR_DS_OBJ_TOO_LARGE +Windows.Win32.Foundation.ERROR_DS_OBJECT_BEING_REMOVED +Windows.Win32.Foundation.ERROR_DS_OBJECT_CLASS_REQUIRED +Windows.Win32.Foundation.ERROR_DS_OBJECT_RESULTS_TOO_LARGE +Windows.Win32.Foundation.ERROR_DS_OFFSET_RANGE_ERROR +Windows.Win32.Foundation.ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS +Windows.Win32.Foundation.ERROR_DS_OID_NOT_FOUND +Windows.Win32.Foundation.ERROR_DS_OPERATIONS_ERROR +Windows.Win32.Foundation.ERROR_DS_OUT_OF_SCOPE +Windows.Win32.Foundation.ERROR_DS_OUT_OF_VERSION_STORE +Windows.Win32.Foundation.ERROR_DS_PARAM_ERROR +Windows.Win32.Foundation.ERROR_DS_PARENT_IS_AN_ALIAS +Windows.Win32.Foundation.ERROR_DS_PDC_OPERATION_IN_PROGRESS +Windows.Win32.Foundation.ERROR_DS_PER_ATTRIBUTE_AUTHZ_FAILED_DURING_ADD +Windows.Win32.Foundation.ERROR_DS_POLICY_NOT_KNOWN +Windows.Win32.Foundation.ERROR_DS_PROTOCOL_ERROR +Windows.Win32.Foundation.ERROR_DS_RANGE_CONSTRAINT +Windows.Win32.Foundation.ERROR_DS_RDN_DOESNT_MATCH_SCHEMA +Windows.Win32.Foundation.ERROR_DS_RECALCSCHEMA_FAILED +Windows.Win32.Foundation.ERROR_DS_REFERRAL +Windows.Win32.Foundation.ERROR_DS_REFERRAL_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_REFUSING_FSMO_ROLES +Windows.Win32.Foundation.ERROR_DS_REMOTE_CROSSREF_OP_FAILED +Windows.Win32.Foundation.ERROR_DS_REPL_LIFETIME_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR +Windows.Win32.Foundation.ERROR_DS_REPLICATOR_ONLY +Windows.Win32.Foundation.ERROR_DS_RESERVED_LINK_ID +Windows.Win32.Foundation.ERROR_DS_RESERVED_MAPI_ID +Windows.Win32.Foundation.ERROR_DS_RIDMGR_DISABLED +Windows.Win32.Foundation.ERROR_DS_RIDMGR_INIT_ERROR +Windows.Win32.Foundation.ERROR_DS_ROLE_NOT_VERIFIED +Windows.Win32.Foundation.ERROR_DS_ROOT_CANT_BE_SUBREF +Windows.Win32.Foundation.ERROR_DS_ROOT_MUST_BE_NC +Windows.Win32.Foundation.ERROR_DS_ROOT_REQUIRES_CLASS_TOP +Windows.Win32.Foundation.ERROR_DS_SAM_INIT_FAILURE +Windows.Win32.Foundation.ERROR_DS_SAM_INIT_FAILURE_CONSOLE +Windows.Win32.Foundation.ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY +Windows.Win32.Foundation.ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD +Windows.Win32.Foundation.ERROR_DS_SCHEMA_ALLOC_FAILED +Windows.Win32.Foundation.ERROR_DS_SCHEMA_NOT_LOADED +Windows.Win32.Foundation.ERROR_DS_SCHEMA_UPDATE_DISALLOWED +Windows.Win32.Foundation.ERROR_DS_SEC_DESC_INVALID +Windows.Win32.Foundation.ERROR_DS_SEC_DESC_TOO_SHORT +Windows.Win32.Foundation.ERROR_DS_SECURITY_CHECKING_ERROR +Windows.Win32.Foundation.ERROR_DS_SECURITY_ILLEGAL_MODIFY +Windows.Win32.Foundation.ERROR_DS_SEMANTIC_ATT_TEST +Windows.Win32.Foundation.ERROR_DS_SENSITIVE_GROUP_VIOLATION +Windows.Win32.Foundation.ERROR_DS_SERVER_DOWN +Windows.Win32.Foundation.ERROR_DS_SHUTTING_DOWN +Windows.Win32.Foundation.ERROR_DS_SINGLE_USER_MODE_FAILED +Windows.Win32.Foundation.ERROR_DS_SINGLE_VALUE_CONSTRAINT +Windows.Win32.Foundation.ERROR_DS_SIZELIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_SORT_CONTROL_MISSING +Windows.Win32.Foundation.ERROR_DS_SOURCE_AUDITING_NOT_ENABLED +Windows.Win32.Foundation.ERROR_DS_SOURCE_DOMAIN_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_SRC_AND_DST_NC_IDENTICAL +Windows.Win32.Foundation.ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH +Windows.Win32.Foundation.ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER +Windows.Win32.Foundation.ERROR_DS_SRC_GUID_MISMATCH +Windows.Win32.Foundation.ERROR_DS_SRC_NAME_MISMATCH +Windows.Win32.Foundation.ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER +Windows.Win32.Foundation.ERROR_DS_SRC_SID_EXISTS_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_STRING_SD_CONVERSION_FAILED +Windows.Win32.Foundation.ERROR_DS_STRONG_AUTH_REQUIRED +Windows.Win32.Foundation.ERROR_DS_SUB_CLS_TEST_FAIL +Windows.Win32.Foundation.ERROR_DS_SUBREF_MUST_HAVE_PARENT +Windows.Win32.Foundation.ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD +Windows.Win32.Foundation.ERROR_DS_SYNTAX_MISMATCH +Windows.Win32.Foundation.ERROR_DS_THREAD_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_TIMELIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_DS_TREE_DELETE_NOT_FINISHED +Windows.Win32.Foundation.ERROR_DS_UNABLE_TO_SURRENDER_ROLES +Windows.Win32.Foundation.ERROR_DS_UNAVAILABLE +Windows.Win32.Foundation.ERROR_DS_UNAVAILABLE_CRIT_EXTENSION +Windows.Win32.Foundation.ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED +Windows.Win32.Foundation.ERROR_DS_UNICODEPWD_NOT_IN_QUOTES +Windows.Win32.Foundation.ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER +Windows.Win32.Foundation.ERROR_DS_UNKNOWN_ERROR +Windows.Win32.Foundation.ERROR_DS_UNKNOWN_OPERATION +Windows.Win32.Foundation.ERROR_DS_UNWILLING_TO_PERFORM +Windows.Win32.Foundation.ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST +Windows.Win32.Foundation.ERROR_DS_USER_BUFFER_TO_SMALL +Windows.Win32.Foundation.ERROR_DS_VALUE_KEY_NOT_UNIQUE +Windows.Win32.Foundation.ERROR_DS_VERSION_CHECK_FAILURE +Windows.Win32.Foundation.ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL +Windows.Win32.Foundation.ERROR_DS_WRONG_LINKED_ATT_SYNTAX +Windows.Win32.Foundation.ERROR_DS_WRONG_OM_OBJ_CLASS +Windows.Win32.Foundation.ERROR_DUP_DOMAINNAME +Windows.Win32.Foundation.ERROR_DUP_NAME +Windows.Win32.Foundation.ERROR_DUPLICATE_PRIVILEGES +Windows.Win32.Foundation.ERROR_DUPLICATE_SERVICE_NAME +Windows.Win32.Foundation.ERROR_DYNAMIC_CODE_BLOCKED +Windows.Win32.Foundation.ERROR_DYNLINK_FROM_INVALID_RING +Windows.Win32.Foundation.ERROR_EA_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_EA_FILE_CORRUPT +Windows.Win32.Foundation.ERROR_EA_LIST_INCONSISTENT +Windows.Win32.Foundation.ERROR_EA_TABLE_FULL +Windows.Win32.Foundation.ERROR_EAS_DIDNT_FIT +Windows.Win32.Foundation.ERROR_EAS_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_EDP_DPL_POLICY_CANT_BE_SATISFIED +Windows.Win32.Foundation.ERROR_EDP_POLICY_DENIES_OPERATION +Windows.Win32.Foundation.ERROR_EFS_ALG_BLOB_TOO_BIG +Windows.Win32.Foundation.ERROR_EFS_DISABLED +Windows.Win32.Foundation.ERROR_EFS_SERVER_NOT_TRUSTED +Windows.Win32.Foundation.ERROR_EFS_VERSION_NOT_SUPPORT +Windows.Win32.Foundation.ERROR_ELEVATION_REQUIRED +Windows.Win32.Foundation.ERROR_ENCLAVE_FAILURE +Windows.Win32.Foundation.ERROR_ENCLAVE_NOT_TERMINATED +Windows.Win32.Foundation.ERROR_ENCLAVE_VIOLATION +Windows.Win32.Foundation.ERROR_ENCRYPTED_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_ENCRYPTED_IO_NOT_POSSIBLE +Windows.Win32.Foundation.ERROR_ENCRYPTING_METADATA_DISALLOWED +Windows.Win32.Foundation.ERROR_ENCRYPTION_DISABLED +Windows.Win32.Foundation.ERROR_ENCRYPTION_FAILED +Windows.Win32.Foundation.ERROR_ENCRYPTION_POLICY_DENIES_OPERATION +Windows.Win32.Foundation.ERROR_END_OF_MEDIA +Windows.Win32.Foundation.ERROR_ENVVAR_NOT_FOUND +Windows.Win32.Foundation.ERROR_EOM_OVERFLOW +Windows.Win32.Foundation.ERROR_ERRORS_ENCOUNTERED +Windows.Win32.Foundation.ERROR_EVALUATION_EXPIRATION +Windows.Win32.Foundation.ERROR_EVENT_DONE +Windows.Win32.Foundation.ERROR_EVENT_PENDING +Windows.Win32.Foundation.ERROR_EVENTLOG_CANT_START +Windows.Win32.Foundation.ERROR_EVENTLOG_FILE_CHANGED +Windows.Win32.Foundation.ERROR_EVENTLOG_FILE_CORRUPT +Windows.Win32.Foundation.ERROR_EXCEPTION_IN_SERVICE +Windows.Win32.Foundation.ERROR_EXCL_SEM_ALREADY_OWNED +Windows.Win32.Foundation.ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY +Windows.Win32.Foundation.ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY +Windows.Win32.Foundation.ERROR_EXE_MACHINE_TYPE_MISMATCH +Windows.Win32.Foundation.ERROR_EXE_MARKED_INVALID +Windows.Win32.Foundation.ERROR_EXTENDED_ERROR +Windows.Win32.Foundation.ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN +Windows.Win32.Foundation.ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_EXTRANEOUS_INFORMATION +Windows.Win32.Foundation.ERROR_FAIL_FAST_EXCEPTION +Windows.Win32.Foundation.ERROR_FAIL_I24 +Windows.Win32.Foundation.ERROR_FAIL_NOACTION_REBOOT +Windows.Win32.Foundation.ERROR_FAIL_RESTART +Windows.Win32.Foundation.ERROR_FAIL_SHUTDOWN +Windows.Win32.Foundation.ERROR_FAILED_DRIVER_ENTRY +Windows.Win32.Foundation.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT +Windows.Win32.Foundation.ERROR_FATAL_APP_EXIT +Windows.Win32.Foundation.ERROR_FILE_CHECKED_OUT +Windows.Win32.Foundation.ERROR_FILE_CORRUPT +Windows.Win32.Foundation.ERROR_FILE_ENCRYPTED +Windows.Win32.Foundation.ERROR_FILE_EXISTS +Windows.Win32.Foundation.ERROR_FILE_HANDLE_REVOKED +Windows.Win32.Foundation.ERROR_FILE_INVALID +Windows.Win32.Foundation.ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS +Windows.Win32.Foundation.ERROR_FILE_NOT_ENCRYPTED +Windows.Win32.Foundation.ERROR_FILE_NOT_FOUND +Windows.Win32.Foundation.ERROR_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_FILE_OFFLINE +Windows.Win32.Foundation.ERROR_FILE_PROTECTED_UNDER_DPL +Windows.Win32.Foundation.ERROR_FILE_READ_ONLY +Windows.Win32.Foundation.ERROR_FILE_SNAP_IN_PROGRESS +Windows.Win32.Foundation.ERROR_FILE_SNAP_INVALID_PARAMETER +Windows.Win32.Foundation.ERROR_FILE_SNAP_IO_NOT_COORDINATED +Windows.Win32.Foundation.ERROR_FILE_SNAP_MODIFY_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_FILE_SNAP_UNEXPECTED_ERROR +Windows.Win32.Foundation.ERROR_FILE_SNAP_USER_SECTION_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_LIMITATION +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_BUSY +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN +Windows.Win32.Foundation.ERROR_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE +Windows.Win32.Foundation.ERROR_FILE_TOO_LARGE +Windows.Win32.Foundation.ERROR_FILEMARK_DETECTED +Windows.Win32.Foundation.ERROR_FILENAME_EXCED_RANGE +Windows.Win32.Foundation.ERROR_FIRMWARE_UPDATED +Windows.Win32.Foundation.ERROR_FLOAT_MULTIPLE_FAULTS +Windows.Win32.Foundation.ERROR_FLOAT_MULTIPLE_TRAPS +Windows.Win32.Foundation.ERROR_FLOPPY_BAD_REGISTERS +Windows.Win32.Foundation.ERROR_FLOPPY_ID_MARK_NOT_FOUND +Windows.Win32.Foundation.ERROR_FLOPPY_UNKNOWN_ERROR +Windows.Win32.Foundation.ERROR_FLOPPY_VOLUME +Windows.Win32.Foundation.ERROR_FLOPPY_WRONG_CYLINDER +Windows.Win32.Foundation.ERROR_FORMS_AUTH_REQUIRED +Windows.Win32.Foundation.ERROR_FOUND_OUT_OF_SCOPE +Windows.Win32.Foundation.ERROR_FS_DRIVER_REQUIRED +Windows.Win32.Foundation.ERROR_FS_METADATA_INCONSISTENT +Windows.Win32.Foundation.ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY +Windows.Win32.Foundation.ERROR_FT_DI_SCAN_REQUIRED +Windows.Win32.Foundation.ERROR_FT_READ_FAILURE +Windows.Win32.Foundation.ERROR_FT_READ_FROM_COPY_FAILURE +Windows.Win32.Foundation.ERROR_FT_READ_RECOVERY_FROM_BACKUP +Windows.Win32.Foundation.ERROR_FT_WRITE_FAILURE +Windows.Win32.Foundation.ERROR_FT_WRITE_RECOVERY +Windows.Win32.Foundation.ERROR_FULLSCREEN_MODE +Windows.Win32.Foundation.ERROR_FUNCTION_FAILED +Windows.Win32.Foundation.ERROR_FUNCTION_NOT_CALLED +Windows.Win32.Foundation.ERROR_GDI_HANDLE_LEAK +Windows.Win32.Foundation.ERROR_GEN_FAILURE +Windows.Win32.Foundation.ERROR_GENERIC_NOT_MAPPED +Windows.Win32.Foundation.ERROR_GLOBAL_ONLY_HOOK +Windows.Win32.Foundation.ERROR_GRACEFUL_DISCONNECT +Windows.Win32.Foundation.ERROR_GROUP_EXISTS +Windows.Win32.Foundation.ERROR_GUID_SUBSTITUTION_MADE +Windows.Win32.Foundation.ERROR_HANDLE_DISK_FULL +Windows.Win32.Foundation.ERROR_HANDLE_EOF +Windows.Win32.Foundation.ERROR_HANDLE_REVOKED +Windows.Win32.Foundation.ERROR_HANDLES_CLOSED +Windows.Win32.Foundation.ERROR_HAS_SYSTEM_CRITICAL_FILES +Windows.Win32.Foundation.ERROR_HIBERNATED +Windows.Win32.Foundation.ERROR_HIBERNATION_FAILURE +Windows.Win32.Foundation.ERROR_HOOK_NEEDS_HMOD +Windows.Win32.Foundation.ERROR_HOOK_NOT_INSTALLED +Windows.Win32.Foundation.ERROR_HOOK_TYPE_NOT_ALLOWED +Windows.Win32.Foundation.ERROR_HOST_DOWN +Windows.Win32.Foundation.ERROR_HOST_UNREACHABLE +Windows.Win32.Foundation.ERROR_HOTKEY_ALREADY_REGISTERED +Windows.Win32.Foundation.ERROR_HOTKEY_NOT_REGISTERED +Windows.Win32.Foundation.ERROR_HWNDS_HAVE_DIFF_PARENT +Windows.Win32.Foundation.ERROR_ILL_FORMED_PASSWORD +Windows.Win32.Foundation.ERROR_ILLEGAL_CHARACTER +Windows.Win32.Foundation.ERROR_ILLEGAL_DLL_RELOCATION +Windows.Win32.Foundation.ERROR_ILLEGAL_ELEMENT_ADDRESS +Windows.Win32.Foundation.ERROR_ILLEGAL_FLOAT_CONTEXT +Windows.Win32.Foundation.ERROR_IMAGE_AT_DIFFERENT_BASE +Windows.Win32.Foundation.ERROR_IMAGE_MACHINE_TYPE_MISMATCH +Windows.Win32.Foundation.ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE +Windows.Win32.Foundation.ERROR_IMAGE_NOT_AT_BASE +Windows.Win32.Foundation.ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT +Windows.Win32.Foundation.ERROR_IMPLEMENTATION_LIMIT +Windows.Win32.Foundation.ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE +Windows.Win32.Foundation.ERROR_INCOMPATIBLE_SERVICE_SID_TYPE +Windows.Win32.Foundation.ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING +Windows.Win32.Foundation.ERROR_INCORRECT_ACCOUNT_TYPE +Windows.Win32.Foundation.ERROR_INCORRECT_ADDRESS +Windows.Win32.Foundation.ERROR_INCORRECT_SIZE +Windows.Win32.Foundation.ERROR_INDEX_ABSENT +Windows.Win32.Foundation.ERROR_INDEX_OUT_OF_BOUNDS +Windows.Win32.Foundation.ERROR_INFLOOP_IN_RELOC_CHAIN +Windows.Win32.Foundation.ERROR_INSTALL_ALREADY_RUNNING +Windows.Win32.Foundation.ERROR_INSTALL_FAILURE +Windows.Win32.Foundation.ERROR_INSTALL_LANGUAGE_UNSUPPORTED +Windows.Win32.Foundation.ERROR_INSTALL_LOG_FAILURE +Windows.Win32.Foundation.ERROR_INSTALL_NOTUSED +Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_INVALID +Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_OPEN_FAILED +Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_REJECTED +Windows.Win32.Foundation.ERROR_INSTALL_PACKAGE_VERSION +Windows.Win32.Foundation.ERROR_INSTALL_PLATFORM_UNSUPPORTED +Windows.Win32.Foundation.ERROR_INSTALL_REJECTED +Windows.Win32.Foundation.ERROR_INSTALL_REMOTE_DISALLOWED +Windows.Win32.Foundation.ERROR_INSTALL_REMOTE_PROHIBITED +Windows.Win32.Foundation.ERROR_INSTALL_SERVICE_FAILURE +Windows.Win32.Foundation.ERROR_INSTALL_SERVICE_SAFEBOOT +Windows.Win32.Foundation.ERROR_INSTALL_SOURCE_ABSENT +Windows.Win32.Foundation.ERROR_INSTALL_SUSPEND +Windows.Win32.Foundation.ERROR_INSTALL_TEMP_UNWRITABLE +Windows.Win32.Foundation.ERROR_INSTALL_TRANSFORM_FAILURE +Windows.Win32.Foundation.ERROR_INSTALL_TRANSFORM_REJECTED +Windows.Win32.Foundation.ERROR_INSTALL_UI_FAILURE +Windows.Win32.Foundation.ERROR_INSTALL_USEREXIT +Windows.Win32.Foundation.ERROR_INSTRUCTION_MISALIGNMENT +Windows.Win32.Foundation.ERROR_INSUFFICIENT_BUFFER +Windows.Win32.Foundation.ERROR_INSUFFICIENT_LOGON_INFO +Windows.Win32.Foundation.ERROR_INSUFFICIENT_POWER +Windows.Win32.Foundation.ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE +Windows.Win32.Foundation.ERROR_INSUFFICIENT_VIRTUAL_ADDR_RESOURCES +Windows.Win32.Foundation.ERROR_INTERMIXED_KERNEL_EA_OPERATION +Windows.Win32.Foundation.ERROR_INTERNAL_DB_CORRUPTION +Windows.Win32.Foundation.ERROR_INTERNAL_DB_ERROR +Windows.Win32.Foundation.ERROR_INTERNAL_ERROR +Windows.Win32.Foundation.ERROR_INTERRUPT_STILL_CONNECTED +Windows.Win32.Foundation.ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED +Windows.Win32.Foundation.ERROR_INVALID_ACCEL_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_ACCESS +Windows.Win32.Foundation.ERROR_INVALID_ACCOUNT_NAME +Windows.Win32.Foundation.ERROR_INVALID_ACE_CONDITION +Windows.Win32.Foundation.ERROR_INVALID_ACL +Windows.Win32.Foundation.ERROR_INVALID_ADDRESS +Windows.Win32.Foundation.ERROR_INVALID_AT_INTERRUPT_TIME +Windows.Win32.Foundation.ERROR_INVALID_BLOCK +Windows.Win32.Foundation.ERROR_INVALID_BLOCK_LENGTH +Windows.Win32.Foundation.ERROR_INVALID_CAP +Windows.Win32.Foundation.ERROR_INVALID_CATEGORY +Windows.Win32.Foundation.ERROR_INVALID_COMBOBOX_MESSAGE +Windows.Win32.Foundation.ERROR_INVALID_COMMAND_LINE +Windows.Win32.Foundation.ERROR_INVALID_COMPUTERNAME +Windows.Win32.Foundation.ERROR_INVALID_CRUNTIME_PARAMETER +Windows.Win32.Foundation.ERROR_INVALID_CURSOR_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_DATA +Windows.Win32.Foundation.ERROR_INVALID_DATATYPE +Windows.Win32.Foundation.ERROR_INVALID_DEVICE_OBJECT_PARAMETER +Windows.Win32.Foundation.ERROR_INVALID_DLL +Windows.Win32.Foundation.ERROR_INVALID_DOMAIN_ROLE +Windows.Win32.Foundation.ERROR_INVALID_DOMAIN_STATE +Windows.Win32.Foundation.ERROR_INVALID_DOMAINNAME +Windows.Win32.Foundation.ERROR_INVALID_DRIVE +Windows.Win32.Foundation.ERROR_INVALID_DWP_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_EA_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_EA_NAME +Windows.Win32.Foundation.ERROR_INVALID_EDIT_HEIGHT +Windows.Win32.Foundation.ERROR_INVALID_ENVIRONMENT +Windows.Win32.Foundation.ERROR_INVALID_EVENT_COUNT +Windows.Win32.Foundation.ERROR_INVALID_EVENTNAME +Windows.Win32.Foundation.ERROR_INVALID_EXCEPTION_HANDLER +Windows.Win32.Foundation.ERROR_INVALID_EXE_SIGNATURE +Windows.Win32.Foundation.ERROR_INVALID_FIELD +Windows.Win32.Foundation.ERROR_INVALID_FIELD_IN_PARAMETER_LIST +Windows.Win32.Foundation.ERROR_INVALID_FILTER_PROC +Windows.Win32.Foundation.ERROR_INVALID_FLAG_NUMBER +Windows.Win32.Foundation.ERROR_INVALID_FLAGS +Windows.Win32.Foundation.ERROR_INVALID_FORM_NAME +Windows.Win32.Foundation.ERROR_INVALID_FORM_SIZE +Windows.Win32.Foundation.ERROR_INVALID_FUNCTION +Windows.Win32.Foundation.ERROR_INVALID_GROUP_ATTRIBUTES +Windows.Win32.Foundation.ERROR_INVALID_GROUPNAME +Windows.Win32.Foundation.ERROR_INVALID_GW_COMMAND +Windows.Win32.Foundation.ERROR_INVALID_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_HANDLE_STATE +Windows.Win32.Foundation.ERROR_INVALID_HOOK_FILTER +Windows.Win32.Foundation.ERROR_INVALID_HOOK_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_HW_PROFILE +Windows.Win32.Foundation.ERROR_INVALID_ICON_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_ID_AUTHORITY +Windows.Win32.Foundation.ERROR_INVALID_IMAGE_HASH +Windows.Win32.Foundation.ERROR_INVALID_IMPORT_OF_NON_DLL +Windows.Win32.Foundation.ERROR_INVALID_INDEX +Windows.Win32.Foundation.ERROR_INVALID_KERNEL_INFO_VERSION +Windows.Win32.Foundation.ERROR_INVALID_KEYBOARD_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_LABEL +Windows.Win32.Foundation.ERROR_INVALID_LB_MESSAGE +Windows.Win32.Foundation.ERROR_INVALID_LDT_DESCRIPTOR +Windows.Win32.Foundation.ERROR_INVALID_LDT_OFFSET +Windows.Win32.Foundation.ERROR_INVALID_LDT_SIZE +Windows.Win32.Foundation.ERROR_INVALID_LEVEL +Windows.Win32.Foundation.ERROR_INVALID_LIST_FORMAT +Windows.Win32.Foundation.ERROR_INVALID_LOCK_RANGE +Windows.Win32.Foundation.ERROR_INVALID_LOGON_HOURS +Windows.Win32.Foundation.ERROR_INVALID_LOGON_TYPE +Windows.Win32.Foundation.ERROR_INVALID_MEMBER +Windows.Win32.Foundation.ERROR_INVALID_MENU_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_MESSAGE +Windows.Win32.Foundation.ERROR_INVALID_MESSAGEDEST +Windows.Win32.Foundation.ERROR_INVALID_MESSAGENAME +Windows.Win32.Foundation.ERROR_INVALID_MINALLOCSIZE +Windows.Win32.Foundation.ERROR_INVALID_MODULETYPE +Windows.Win32.Foundation.ERROR_INVALID_MONITOR_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_MSGBOX_STYLE +Windows.Win32.Foundation.ERROR_INVALID_NAME +Windows.Win32.Foundation.ERROR_INVALID_NETNAME +Windows.Win32.Foundation.ERROR_INVALID_OPLOCK_PROTOCOL +Windows.Win32.Foundation.ERROR_INVALID_ORDINAL +Windows.Win32.Foundation.ERROR_INVALID_OWNER +Windows.Win32.Foundation.ERROR_INVALID_PACKAGE_SID_LENGTH +Windows.Win32.Foundation.ERROR_INVALID_PARAMETER +Windows.Win32.Foundation.ERROR_INVALID_PASSWORD +Windows.Win32.Foundation.ERROR_INVALID_PASSWORDNAME +Windows.Win32.Foundation.ERROR_INVALID_PATCH_XML +Windows.Win32.Foundation.ERROR_INVALID_PEP_INFO_VERSION +Windows.Win32.Foundation.ERROR_INVALID_PLUGPLAY_DEVICE_PATH +Windows.Win32.Foundation.ERROR_INVALID_PORT_ATTRIBUTES +Windows.Win32.Foundation.ERROR_INVALID_PRIMARY_GROUP +Windows.Win32.Foundation.ERROR_INVALID_PRINTER_COMMAND +Windows.Win32.Foundation.ERROR_INVALID_PRINTER_NAME +Windows.Win32.Foundation.ERROR_INVALID_PRINTER_STATE +Windows.Win32.Foundation.ERROR_INVALID_PRIORITY +Windows.Win32.Foundation.ERROR_INVALID_QUOTA_LOWER +Windows.Win32.Foundation.ERROR_INVALID_REPARSE_DATA +Windows.Win32.Foundation.ERROR_INVALID_SCROLLBAR_RANGE +Windows.Win32.Foundation.ERROR_INVALID_SECURITY_DESCR +Windows.Win32.Foundation.ERROR_INVALID_SEGDPL +Windows.Win32.Foundation.ERROR_INVALID_SEGMENT_NUMBER +Windows.Win32.Foundation.ERROR_INVALID_SEPARATOR_FILE +Windows.Win32.Foundation.ERROR_INVALID_SERVER_STATE +Windows.Win32.Foundation.ERROR_INVALID_SERVICE_ACCOUNT +Windows.Win32.Foundation.ERROR_INVALID_SERVICE_CONTROL +Windows.Win32.Foundation.ERROR_INVALID_SERVICE_LOCK +Windows.Win32.Foundation.ERROR_INVALID_SERVICENAME +Windows.Win32.Foundation.ERROR_INVALID_SHARENAME +Windows.Win32.Foundation.ERROR_INVALID_SHOWWIN_COMMAND +Windows.Win32.Foundation.ERROR_INVALID_SID +Windows.Win32.Foundation.ERROR_INVALID_SIGNAL_NUMBER +Windows.Win32.Foundation.ERROR_INVALID_SPI_VALUE +Windows.Win32.Foundation.ERROR_INVALID_STACKSEG +Windows.Win32.Foundation.ERROR_INVALID_STARTING_CODESEG +Windows.Win32.Foundation.ERROR_INVALID_SUB_AUTHORITY +Windows.Win32.Foundation.ERROR_INVALID_TABLE +Windows.Win32.Foundation.ERROR_INVALID_TARGET_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_TASK_INDEX +Windows.Win32.Foundation.ERROR_INVALID_TASK_NAME +Windows.Win32.Foundation.ERROR_INVALID_THREAD_ID +Windows.Win32.Foundation.ERROR_INVALID_TIME +Windows.Win32.Foundation.ERROR_INVALID_TOKEN +Windows.Win32.Foundation.ERROR_INVALID_UNWIND_TARGET +Windows.Win32.Foundation.ERROR_INVALID_USER_BUFFER +Windows.Win32.Foundation.ERROR_INVALID_USER_PRINCIPAL_NAME +Windows.Win32.Foundation.ERROR_INVALID_VARIANT +Windows.Win32.Foundation.ERROR_INVALID_VERIFY_SWITCH +Windows.Win32.Foundation.ERROR_INVALID_WINDOW_HANDLE +Windows.Win32.Foundation.ERROR_INVALID_WORKSTATION +Windows.Win32.Foundation.ERROR_IO_DEVICE +Windows.Win32.Foundation.ERROR_IO_INCOMPLETE +Windows.Win32.Foundation.ERROR_IO_PENDING +Windows.Win32.Foundation.ERROR_IO_PRIVILEGE_FAILED +Windows.Win32.Foundation.ERROR_IO_REISSUE_AS_CACHED +Windows.Win32.Foundation.ERROR_IOPL_NOT_ENABLED +Windows.Win32.Foundation.ERROR_IP_ADDRESS_CONFLICT1 +Windows.Win32.Foundation.ERROR_IP_ADDRESS_CONFLICT2 +Windows.Win32.Foundation.ERROR_IPSEC_IKE_TIMED_OUT +Windows.Win32.Foundation.ERROR_IRQ_BUSY +Windows.Win32.Foundation.ERROR_IS_JOIN_PATH +Windows.Win32.Foundation.ERROR_IS_JOIN_TARGET +Windows.Win32.Foundation.ERROR_IS_JOINED +Windows.Win32.Foundation.ERROR_IS_SUBST_PATH +Windows.Win32.Foundation.ERROR_IS_SUBST_TARGET +Windows.Win32.Foundation.ERROR_IS_SUBSTED +Windows.Win32.Foundation.ERROR_ITERATED_DATA_EXCEEDS_64k +Windows.Win32.Foundation.ERROR_JOB_NO_CONTAINER +Windows.Win32.Foundation.ERROR_JOIN_TO_JOIN +Windows.Win32.Foundation.ERROR_JOIN_TO_SUBST +Windows.Win32.Foundation.ERROR_JOURNAL_DELETE_IN_PROGRESS +Windows.Win32.Foundation.ERROR_JOURNAL_ENTRY_DELETED +Windows.Win32.Foundation.ERROR_JOURNAL_HOOK_SET +Windows.Win32.Foundation.ERROR_JOURNAL_NOT_ACTIVE +Windows.Win32.Foundation.ERROR_KERNEL_APC +Windows.Win32.Foundation.ERROR_KEY_DELETED +Windows.Win32.Foundation.ERROR_KEY_HAS_CHILDREN +Windows.Win32.Foundation.ERROR_KM_DRIVER_BLOCKED +Windows.Win32.Foundation.ERROR_LABEL_TOO_LONG +Windows.Win32.Foundation.ERROR_LAST_ADMIN +Windows.Win32.Foundation.ERROR_LB_WITHOUT_TABSTOPS +Windows.Win32.Foundation.ERROR_LICENSE_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_LINUX_SUBSYSTEM_NOT_PRESENT +Windows.Win32.Foundation.ERROR_LINUX_SUBSYSTEM_UPDATE_REQUIRED +Windows.Win32.Foundation.ERROR_LISTBOX_ID_NOT_FOUND +Windows.Win32.Foundation.ERROR_LM_CROSS_ENCRYPTION_REQUIRED +Windows.Win32.Foundation.ERROR_LOCAL_POLICY_MODIFICATION_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_LOCAL_USER_SESSION_KEY +Windows.Win32.Foundation.ERROR_LOCK_FAILED +Windows.Win32.Foundation.ERROR_LOCK_VIOLATION +Windows.Win32.Foundation.ERROR_LOCKED +Windows.Win32.Foundation.ERROR_LOG_FILE_FULL +Windows.Win32.Foundation.ERROR_LOG_HARD_ERROR +Windows.Win32.Foundation.ERROR_LOGIN_TIME_RESTRICTION +Windows.Win32.Foundation.ERROR_LOGIN_WKSTA_RESTRICTION +Windows.Win32.Foundation.ERROR_LOGON_FAILURE +Windows.Win32.Foundation.ERROR_LOGON_NOT_GRANTED +Windows.Win32.Foundation.ERROR_LOGON_SERVER_CONFLICT +Windows.Win32.Foundation.ERROR_LOGON_SESSION_COLLISION +Windows.Win32.Foundation.ERROR_LOGON_SESSION_EXISTS +Windows.Win32.Foundation.ERROR_LOGON_TYPE_NOT_GRANTED +Windows.Win32.Foundation.ERROR_LONGJUMP +Windows.Win32.Foundation.ERROR_LOST_MODE_LOGON_RESTRICTION +Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA +Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR +Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED +Windows.Win32.Foundation.ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR +Windows.Win32.Foundation.ERROR_LUIDS_EXHAUSTED +Windows.Win32.Foundation.ERROR_MACHINE_LOCKED +Windows.Win32.Foundation.ERROR_MAGAZINE_NOT_PRESENT +Windows.Win32.Foundation.ERROR_MAPPED_ALIGNMENT +Windows.Win32.Foundation.ERROR_MARKED_TO_DISALLOW_WRITES +Windows.Win32.Foundation.ERROR_MARSHALL_OVERFLOW +Windows.Win32.Foundation.ERROR_MAX_SESSIONS_REACHED +Windows.Win32.Foundation.ERROR_MAX_THRDS_REACHED +Windows.Win32.Foundation.ERROR_MCA_EXCEPTION +Windows.Win32.Foundation.ERROR_MCA_OCCURED +Windows.Win32.Foundation.ERROR_MEDIA_CHANGED +Windows.Win32.Foundation.ERROR_MEDIA_CHECK +Windows.Win32.Foundation.ERROR_MEMBER_IN_ALIAS +Windows.Win32.Foundation.ERROR_MEMBER_IN_GROUP +Windows.Win32.Foundation.ERROR_MEMBER_NOT_IN_ALIAS +Windows.Win32.Foundation.ERROR_MEMBER_NOT_IN_GROUP +Windows.Win32.Foundation.ERROR_MEMBERS_PRIMARY_GROUP +Windows.Win32.Foundation.ERROR_MEMORY_HARDWARE +Windows.Win32.Foundation.ERROR_MENU_ITEM_NOT_FOUND +Windows.Win32.Foundation.ERROR_MESSAGE_SYNC_ONLY +Windows.Win32.Foundation.ERROR_META_EXPANSION_TOO_LONG +Windows.Win32.Foundation.ERROR_MISSING_SYSTEMFILE +Windows.Win32.Foundation.ERROR_MOD_NOT_FOUND +Windows.Win32.Foundation.ERROR_MORE_DATA +Windows.Win32.Foundation.ERROR_MORE_WRITES +Windows.Win32.Foundation.ERROR_MOUNT_POINT_NOT_RESOLVED +Windows.Win32.Foundation.ERROR_MP_PROCESSOR_MISMATCH +Windows.Win32.Foundation.ERROR_MR_MID_NOT_FOUND +Windows.Win32.Foundation.ERROR_MULTIPLE_FAULT_VIOLATION +Windows.Win32.Foundation.ERROR_MUTANT_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_MUTUAL_AUTH_FAILED +Windows.Win32.Foundation.ERROR_NEGATIVE_SEEK +Windows.Win32.Foundation.ERROR_NESTING_NOT_ALLOWED +Windows.Win32.Foundation.ERROR_NET_OPEN_FAILED +Windows.Win32.Foundation.ERROR_NET_WRITE_FAULT +Windows.Win32.Foundation.ERROR_NETLOGON_NOT_STARTED +Windows.Win32.Foundation.ERROR_NETNAME_DELETED +Windows.Win32.Foundation.ERROR_NETWORK_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_NETWORK_ACCESS_DENIED_EDP +Windows.Win32.Foundation.ERROR_NETWORK_BUSY +Windows.Win32.Foundation.ERROR_NETWORK_UNREACHABLE +Windows.Win32.Foundation.ERROR_NO_ACE_CONDITION +Windows.Win32.Foundation.ERROR_NO_ASSOCIATION +Windows.Win32.Foundation.ERROR_NO_BYPASSIO_DRIVER_SUPPORT +Windows.Win32.Foundation.ERROR_NO_CALLBACK_ACTIVE +Windows.Win32.Foundation.ERROR_NO_DATA +Windows.Win32.Foundation.ERROR_NO_DATA_DETECTED +Windows.Win32.Foundation.ERROR_NO_EFS +Windows.Win32.Foundation.ERROR_NO_EVENT_PAIR +Windows.Win32.Foundation.ERROR_NO_GUID_TRANSLATION +Windows.Win32.Foundation.ERROR_NO_IMPERSONATION_TOKEN +Windows.Win32.Foundation.ERROR_NO_INHERITANCE +Windows.Win32.Foundation.ERROR_NO_LOG_SPACE +Windows.Win32.Foundation.ERROR_NO_LOGON_SERVERS +Windows.Win32.Foundation.ERROR_NO_MATCH +Windows.Win32.Foundation.ERROR_NO_MEDIA_IN_DRIVE +Windows.Win32.Foundation.ERROR_NO_MORE_DEVICES +Windows.Win32.Foundation.ERROR_NO_MORE_FILES +Windows.Win32.Foundation.ERROR_NO_MORE_ITEMS +Windows.Win32.Foundation.ERROR_NO_MORE_MATCHES +Windows.Win32.Foundation.ERROR_NO_MORE_SEARCH_HANDLES +Windows.Win32.Foundation.ERROR_NO_MORE_USER_HANDLES +Windows.Win32.Foundation.ERROR_NO_NET_OR_BAD_PATH +Windows.Win32.Foundation.ERROR_NO_NETWORK +Windows.Win32.Foundation.ERROR_NO_NVRAM_RESOURCES +Windows.Win32.Foundation.ERROR_NO_PAGEFILE +Windows.Win32.Foundation.ERROR_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND +Windows.Win32.Foundation.ERROR_NO_PROC_SLOTS +Windows.Win32.Foundation.ERROR_NO_PROMOTION_ACTIVE +Windows.Win32.Foundation.ERROR_NO_QUOTAS_FOR_ACCOUNT +Windows.Win32.Foundation.ERROR_NO_RANGES_PROCESSED +Windows.Win32.Foundation.ERROR_NO_RECOVERY_POLICY +Windows.Win32.Foundation.ERROR_NO_RECOVERY_PROGRAM +Windows.Win32.Foundation.ERROR_NO_SCROLLBARS +Windows.Win32.Foundation.ERROR_NO_SECRETS +Windows.Win32.Foundation.ERROR_NO_SECURITY_ON_OBJECT +Windows.Win32.Foundation.ERROR_NO_SHUTDOWN_IN_PROGRESS +Windows.Win32.Foundation.ERROR_NO_SIGNAL_SENT +Windows.Win32.Foundation.ERROR_NO_SITE_SETTINGS_OBJECT +Windows.Win32.Foundation.ERROR_NO_SITENAME +Windows.Win32.Foundation.ERROR_NO_SPOOL_SPACE +Windows.Win32.Foundation.ERROR_NO_SUCH_ALIAS +Windows.Win32.Foundation.ERROR_NO_SUCH_DEVICE +Windows.Win32.Foundation.ERROR_NO_SUCH_DOMAIN +Windows.Win32.Foundation.ERROR_NO_SUCH_GROUP +Windows.Win32.Foundation.ERROR_NO_SUCH_LOGON_SESSION +Windows.Win32.Foundation.ERROR_NO_SUCH_MEMBER +Windows.Win32.Foundation.ERROR_NO_SUCH_PACKAGE +Windows.Win32.Foundation.ERROR_NO_SUCH_PRIVILEGE +Windows.Win32.Foundation.ERROR_NO_SUCH_SITE +Windows.Win32.Foundation.ERROR_NO_SUCH_USER +Windows.Win32.Foundation.ERROR_NO_SYSTEM_MENU +Windows.Win32.Foundation.ERROR_NO_SYSTEM_RESOURCES +Windows.Win32.Foundation.ERROR_NO_TASK_QUEUE +Windows.Win32.Foundation.ERROR_NO_TOKEN +Windows.Win32.Foundation.ERROR_NO_TRACKING_SERVICE +Windows.Win32.Foundation.ERROR_NO_TRUST_LSA_SECRET +Windows.Win32.Foundation.ERROR_NO_TRUST_SAM_ACCOUNT +Windows.Win32.Foundation.ERROR_NO_UNICODE_TRANSLATION +Windows.Win32.Foundation.ERROR_NO_USER_KEYS +Windows.Win32.Foundation.ERROR_NO_USER_SESSION_KEY +Windows.Win32.Foundation.ERROR_NO_VOLUME_ID +Windows.Win32.Foundation.ERROR_NO_VOLUME_LABEL +Windows.Win32.Foundation.ERROR_NO_WILDCARD_CHARACTERS +Windows.Win32.Foundation.ERROR_NO_WORK_DONE +Windows.Win32.Foundation.ERROR_NO_WRITABLE_DC_FOUND +Windows.Win32.Foundation.ERROR_NO_YIELD_PERFORMED +Windows.Win32.Foundation.ERROR_NOACCESS +Windows.Win32.Foundation.ERROR_NOINTERFACE +Windows.Win32.Foundation.ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT +Windows.Win32.Foundation.ERROR_NOLOGON_SERVER_TRUST_ACCOUNT +Windows.Win32.Foundation.ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT +Windows.Win32.Foundation.ERROR_NON_ACCOUNT_SID +Windows.Win32.Foundation.ERROR_NON_DOMAIN_SID +Windows.Win32.Foundation.ERROR_NON_MDICHILD_WINDOW +Windows.Win32.Foundation.ERROR_NONE_MAPPED +Windows.Win32.Foundation.ERROR_NONPAGED_SYSTEM_RESOURCES +Windows.Win32.Foundation.ERROR_NOT_A_CLOUD_FILE +Windows.Win32.Foundation.ERROR_NOT_A_CLOUD_SYNC_ROOT +Windows.Win32.Foundation.ERROR_NOT_A_DAX_VOLUME +Windows.Win32.Foundation.ERROR_NOT_A_REPARSE_POINT +Windows.Win32.Foundation.ERROR_NOT_ALL_ASSIGNED +Windows.Win32.Foundation.ERROR_NOT_ALLOWED_ON_SYSTEM_FILE +Windows.Win32.Foundation.ERROR_NOT_APPCONTAINER +Windows.Win32.Foundation.ERROR_NOT_AUTHENTICATED +Windows.Win32.Foundation.ERROR_NOT_CAPABLE +Windows.Win32.Foundation.ERROR_NOT_CHILD_WINDOW +Windows.Win32.Foundation.ERROR_NOT_CONNECTED +Windows.Win32.Foundation.ERROR_NOT_CONTAINER +Windows.Win32.Foundation.ERROR_NOT_DAX_MAPPABLE +Windows.Win32.Foundation.ERROR_NOT_DOS_DISK +Windows.Win32.Foundation.ERROR_NOT_ENOUGH_MEMORY +Windows.Win32.Foundation.ERROR_NOT_ENOUGH_QUOTA +Windows.Win32.Foundation.ERROR_NOT_ENOUGH_SERVER_MEMORY +Windows.Win32.Foundation.ERROR_NOT_EXPORT_FORMAT +Windows.Win32.Foundation.ERROR_NOT_FOUND +Windows.Win32.Foundation.ERROR_NOT_GUI_PROCESS +Windows.Win32.Foundation.ERROR_NOT_JOINED +Windows.Win32.Foundation.ERROR_NOT_LOCKED +Windows.Win32.Foundation.ERROR_NOT_LOGGED_ON +Windows.Win32.Foundation.ERROR_NOT_LOGON_PROCESS +Windows.Win32.Foundation.ERROR_NOT_OWNER +Windows.Win32.Foundation.ERROR_NOT_READ_FROM_COPY +Windows.Win32.Foundation.ERROR_NOT_READY +Windows.Win32.Foundation.ERROR_NOT_REDUNDANT_STORAGE +Windows.Win32.Foundation.ERROR_NOT_REGISTRY_FILE +Windows.Win32.Foundation.ERROR_NOT_SAFE_MODE_DRIVER +Windows.Win32.Foundation.ERROR_NOT_SAFEBOOT_SERVICE +Windows.Win32.Foundation.ERROR_NOT_SAME_DEVICE +Windows.Win32.Foundation.ERROR_NOT_SAME_OBJECT +Windows.Win32.Foundation.ERROR_NOT_SUBSTED +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_IN_APPCONTAINER +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_DAX +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_SBS +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_AUDITING +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_BTT +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_BYPASSIO +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_CACHED_HANDLE +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_COMPRESSION +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_DEDUPLICATION +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_ENCRYPTION +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_MONITORING +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_REPLICATION +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_SNAPSHOT +Windows.Win32.Foundation.ERROR_NOT_SUPPORTED_WITH_VIRTUALIZATION +Windows.Win32.Foundation.ERROR_NOT_TINY_STREAM +Windows.Win32.Foundation.ERROR_NOTHING_TO_TERMINATE +Windows.Win32.Foundation.ERROR_NOTIFICATION_GUID_ALREADY_DEFINED +Windows.Win32.Foundation.ERROR_NOTIFY_CLEANUP +Windows.Win32.Foundation.ERROR_NOTIFY_ENUM_DIR +Windows.Win32.Foundation.ERROR_NT_CROSS_ENCRYPTION_REQUIRED +Windows.Win32.Foundation.ERROR_NTLM_BLOCKED +Windows.Win32.Foundation.ERROR_NULL_LM_PASSWORD +Windows.Win32.Foundation.ERROR_OBJECT_IS_IMMUTABLE +Windows.Win32.Foundation.ERROR_OBJECT_NAME_EXISTS +Windows.Win32.Foundation.ERROR_OBJECT_NOT_EXTERNALLY_BACKED +Windows.Win32.Foundation.ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_OFFSET_ALIGNMENT_VIOLATION +Windows.Win32.Foundation.ERROR_OLD_WIN_VERSION +Windows.Win32.Foundation.ERROR_ONLY_IF_CONNECTED +Windows.Win32.Foundation.ERROR_OPEN_FAILED +Windows.Win32.Foundation.ERROR_OPEN_FILES +Windows.Win32.Foundation.ERROR_OPERATION_ABORTED +Windows.Win32.Foundation.ERROR_OPERATION_IN_PROGRESS +Windows.Win32.Foundation.ERROR_OPLOCK_BREAK_IN_PROGRESS +Windows.Win32.Foundation.ERROR_OPLOCK_HANDLE_CLOSED +Windows.Win32.Foundation.ERROR_OPLOCK_NOT_GRANTED +Windows.Win32.Foundation.ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE +Windows.Win32.Foundation.ERROR_ORPHAN_NAME_EXHAUSTED +Windows.Win32.Foundation.ERROR_OUT_OF_PAPER +Windows.Win32.Foundation.ERROR_OUT_OF_STRUCTURES +Windows.Win32.Foundation.ERROR_OUTOFMEMORY +Windows.Win32.Foundation.ERROR_OVERRIDE_NOCHANGES +Windows.Win32.Foundation.ERROR_PAGE_FAULT_COPY_ON_WRITE +Windows.Win32.Foundation.ERROR_PAGE_FAULT_DEMAND_ZERO +Windows.Win32.Foundation.ERROR_PAGE_FAULT_GUARD_PAGE +Windows.Win32.Foundation.ERROR_PAGE_FAULT_PAGING_FILE +Windows.Win32.Foundation.ERROR_PAGE_FAULT_TRANSITION +Windows.Win32.Foundation.ERROR_PAGED_SYSTEM_RESOURCES +Windows.Win32.Foundation.ERROR_PAGEFILE_CREATE_FAILED +Windows.Win32.Foundation.ERROR_PAGEFILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_PAGEFILE_QUOTA +Windows.Win32.Foundation.ERROR_PAGEFILE_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_PARAMETER_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_PARTIAL_COPY +Windows.Win32.Foundation.ERROR_PARTITION_FAILURE +Windows.Win32.Foundation.ERROR_PARTITION_TERMINATING +Windows.Win32.Foundation.ERROR_PASSWORD_CHANGE_REQUIRED +Windows.Win32.Foundation.ERROR_PASSWORD_EXPIRED +Windows.Win32.Foundation.ERROR_PASSWORD_MUST_CHANGE +Windows.Win32.Foundation.ERROR_PASSWORD_RESTRICTION +Windows.Win32.Foundation.ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT +Windows.Win32.Foundation.ERROR_PATCH_NO_SEQUENCE +Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_INVALID +Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_OPEN_FAILED +Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_REJECTED +Windows.Win32.Foundation.ERROR_PATCH_PACKAGE_UNSUPPORTED +Windows.Win32.Foundation.ERROR_PATCH_REMOVAL_DISALLOWED +Windows.Win32.Foundation.ERROR_PATCH_REMOVAL_UNSUPPORTED +Windows.Win32.Foundation.ERROR_PATCH_TARGET_NOT_FOUND +Windows.Win32.Foundation.ERROR_PATH_BUSY +Windows.Win32.Foundation.ERROR_PATH_NOT_FOUND +Windows.Win32.Foundation.ERROR_PER_USER_TRUST_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_PIPE_BUSY +Windows.Win32.Foundation.ERROR_PIPE_CONNECTED +Windows.Win32.Foundation.ERROR_PIPE_LISTENING +Windows.Win32.Foundation.ERROR_PIPE_LOCAL +Windows.Win32.Foundation.ERROR_PIPE_NOT_CONNECTED +Windows.Win32.Foundation.ERROR_PKINIT_FAILURE +Windows.Win32.Foundation.ERROR_PLUGPLAY_QUERY_VETOED +Windows.Win32.Foundation.ERROR_PNP_BAD_MPS_TABLE +Windows.Win32.Foundation.ERROR_PNP_INVALID_ID +Windows.Win32.Foundation.ERROR_PNP_IRQ_TRANSLATION_FAILED +Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_DEVICE_TIMEOUT +Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_RELATED_DEVICE_TIMEOUT +Windows.Win32.Foundation.ERROR_PNP_QUERY_REMOVE_UNRELATED_DEVICE_TIMEOUT +Windows.Win32.Foundation.ERROR_PNP_REBOOT_REQUIRED +Windows.Win32.Foundation.ERROR_PNP_RESTART_ENUMERATION +Windows.Win32.Foundation.ERROR_PNP_TRANSLATION_FAILED +Windows.Win32.Foundation.ERROR_POINT_NOT_FOUND +Windows.Win32.Foundation.ERROR_POLICY_OBJECT_NOT_FOUND +Windows.Win32.Foundation.ERROR_POLICY_ONLY_IN_DS +Windows.Win32.Foundation.ERROR_POPUP_ALREADY_ACTIVE +Windows.Win32.Foundation.ERROR_PORT_MESSAGE_TOO_LONG +Windows.Win32.Foundation.ERROR_PORT_NOT_SET +Windows.Win32.Foundation.ERROR_PORT_UNREACHABLE +Windows.Win32.Foundation.ERROR_POSSIBLE_DEADLOCK +Windows.Win32.Foundation.ERROR_POTENTIAL_FILE_FOUND +Windows.Win32.Foundation.ERROR_PREDEFINED_HANDLE +Windows.Win32.Foundation.ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED +Windows.Win32.Foundation.ERROR_PRINT_CANCELLED +Windows.Win32.Foundation.ERROR_PRINTER_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_PRINTER_DELETED +Windows.Win32.Foundation.ERROR_PRINTER_DRIVER_ALREADY_INSTALLED +Windows.Win32.Foundation.ERROR_PRINTQ_FULL +Windows.Win32.Foundation.ERROR_PRIVATE_DIALOG_INDEX +Windows.Win32.Foundation.ERROR_PRIVILEGE_NOT_HELD +Windows.Win32.Foundation.ERROR_PROC_NOT_FOUND +Windows.Win32.Foundation.ERROR_PROCESS_ABORTED +Windows.Win32.Foundation.ERROR_PROCESS_IN_JOB +Windows.Win32.Foundation.ERROR_PROCESS_IS_PROTECTED +Windows.Win32.Foundation.ERROR_PROCESS_MODE_ALREADY_BACKGROUND +Windows.Win32.Foundation.ERROR_PROCESS_MODE_NOT_BACKGROUND +Windows.Win32.Foundation.ERROR_PROCESS_NOT_IN_JOB +Windows.Win32.Foundation.ERROR_PRODUCT_UNINSTALLED +Windows.Win32.Foundation.ERROR_PRODUCT_VERSION +Windows.Win32.Foundation.ERROR_PROFILING_AT_LIMIT +Windows.Win32.Foundation.ERROR_PROFILING_NOT_STARTED +Windows.Win32.Foundation.ERROR_PROFILING_NOT_STOPPED +Windows.Win32.Foundation.ERROR_PROMOTION_ACTIVE +Windows.Win32.Foundation.ERROR_PROTOCOL_UNREACHABLE +Windows.Win32.Foundation.ERROR_PWD_HISTORY_CONFLICT +Windows.Win32.Foundation.ERROR_PWD_TOO_LONG +Windows.Win32.Foundation.ERROR_PWD_TOO_RECENT +Windows.Win32.Foundation.ERROR_PWD_TOO_SHORT +Windows.Win32.Foundation.ERROR_QUOTA_ACTIVITY +Windows.Win32.Foundation.ERROR_QUOTA_LIST_INCONSISTENT +Windows.Win32.Foundation.ERROR_RANGE_LIST_CONFLICT +Windows.Win32.Foundation.ERROR_RANGE_NOT_FOUND +Windows.Win32.Foundation.ERROR_READ_FAULT +Windows.Win32.Foundation.ERROR_RECEIVE_EXPEDITED +Windows.Win32.Foundation.ERROR_RECEIVE_PARTIAL +Windows.Win32.Foundation.ERROR_RECEIVE_PARTIAL_EXPEDITED +Windows.Win32.Foundation.ERROR_RECOVERY_FAILURE +Windows.Win32.Foundation.ERROR_REDIR_PAUSED +Windows.Win32.Foundation.ERROR_REDIRECTOR_HAS_OPEN_HANDLES +Windows.Win32.Foundation.ERROR_REG_NAT_CONSUMPTION +Windows.Win32.Foundation.ERROR_REGISTRY_CORRUPT +Windows.Win32.Foundation.ERROR_REGISTRY_HIVE_RECOVERED +Windows.Win32.Foundation.ERROR_REGISTRY_IO_FAILED +Windows.Win32.Foundation.ERROR_REGISTRY_QUOTA_LIMIT +Windows.Win32.Foundation.ERROR_REGISTRY_RECOVERED +Windows.Win32.Foundation.ERROR_RELOC_CHAIN_XEEDS_SEGLIM +Windows.Win32.Foundation.ERROR_REM_NOT_LIST +Windows.Win32.Foundation.ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED +Windows.Win32.Foundation.ERROR_REMOTE_SESSION_LIMIT_EXCEEDED +Windows.Win32.Foundation.ERROR_REMOTE_STORAGE_MEDIA_ERROR +Windows.Win32.Foundation.ERROR_REMOTE_STORAGE_NOT_ACTIVE +Windows.Win32.Foundation.ERROR_REPARSE +Windows.Win32.Foundation.ERROR_REPARSE_ATTRIBUTE_CONFLICT +Windows.Win32.Foundation.ERROR_REPARSE_OBJECT +Windows.Win32.Foundation.ERROR_REPARSE_POINT_ENCOUNTERED +Windows.Win32.Foundation.ERROR_REPARSE_TAG_INVALID +Windows.Win32.Foundation.ERROR_REPARSE_TAG_MISMATCH +Windows.Win32.Foundation.ERROR_REPLY_MESSAGE_MISMATCH +Windows.Win32.Foundation.ERROR_REQ_NOT_ACCEP +Windows.Win32.Foundation.ERROR_REQUEST_ABORTED +Windows.Win32.Foundation.ERROR_REQUEST_OUT_OF_SEQUENCE +Windows.Win32.Foundation.ERROR_REQUEST_PAUSED +Windows.Win32.Foundation.ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION +Windows.Win32.Foundation.ERROR_RESIDENT_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_RESOURCE_CALL_TIMED_OUT +Windows.Win32.Foundation.ERROR_RESOURCE_DATA_NOT_FOUND +Windows.Win32.Foundation.ERROR_RESOURCE_LANG_NOT_FOUND +Windows.Win32.Foundation.ERROR_RESOURCE_NAME_NOT_FOUND +Windows.Win32.Foundation.ERROR_RESOURCE_REQUIREMENTS_CHANGED +Windows.Win32.Foundation.ERROR_RESOURCE_TYPE_NOT_FOUND +Windows.Win32.Foundation.ERROR_RESTART_APPLICATION +Windows.Win32.Foundation.ERROR_RESUME_HIBERNATION +Windows.Win32.Foundation.ERROR_RETRY +Windows.Win32.Foundation.ERROR_RETURN_ADDRESS_HIJACK_ATTEMPT +Windows.Win32.Foundation.ERROR_REVISION_MISMATCH +Windows.Win32.Foundation.ERROR_RING2_STACK_IN_USE +Windows.Win32.Foundation.ERROR_RING2SEG_MUST_BE_MOVABLE +Windows.Win32.Foundation.ERROR_RMODE_APP +Windows.Win32.Foundation.ERROR_ROWSNOTRELEASED +Windows.Win32.Foundation.ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT +Windows.Win32.Foundation.ERROR_RUNLEVEL_SWITCH_TIMEOUT +Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED +Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET +Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE +Windows.Win32.Foundation.ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER +Windows.Win32.Foundation.ERROR_RXACT_COMMIT_FAILURE +Windows.Win32.Foundation.ERROR_RXACT_COMMIT_NECESSARY +Windows.Win32.Foundation.ERROR_RXACT_COMMITTED +Windows.Win32.Foundation.ERROR_RXACT_INVALID_STATE +Windows.Win32.Foundation.ERROR_RXACT_STATE_CREATED +Windows.Win32.Foundation.ERROR_SAM_INIT_FAILURE +Windows.Win32.Foundation.ERROR_SAME_DRIVE +Windows.Win32.Foundation.ERROR_SCOPE_NOT_FOUND +Windows.Win32.Foundation.ERROR_SCREEN_ALREADY_LOCKED +Windows.Win32.Foundation.ERROR_SCRUB_DATA_DISABLED +Windows.Win32.Foundation.ERROR_SECRET_TOO_LONG +Windows.Win32.Foundation.ERROR_SECTION_DIRECT_MAP_ONLY +Windows.Win32.Foundation.ERROR_SECTOR_NOT_FOUND +Windows.Win32.Foundation.ERROR_SECURITY_DENIES_OPERATION +Windows.Win32.Foundation.ERROR_SECURITY_STREAM_IS_INCONSISTENT +Windows.Win32.Foundation.ERROR_SEEK +Windows.Win32.Foundation.ERROR_SEEK_ON_DEVICE +Windows.Win32.Foundation.ERROR_SEGMENT_NOTIFICATION +Windows.Win32.Foundation.ERROR_SEM_IS_SET +Windows.Win32.Foundation.ERROR_SEM_NOT_FOUND +Windows.Win32.Foundation.ERROR_SEM_OWNER_DIED +Windows.Win32.Foundation.ERROR_SEM_TIMEOUT +Windows.Win32.Foundation.ERROR_SEM_USER_LIMIT +Windows.Win32.Foundation.ERROR_SERIAL_NO_DEVICE +Windows.Win32.Foundation.ERROR_SERVER_DISABLED +Windows.Win32.Foundation.ERROR_SERVER_HAS_OPEN_HANDLES +Windows.Win32.Foundation.ERROR_SERVER_NOT_DISABLED +Windows.Win32.Foundation.ERROR_SERVER_SHUTDOWN_IN_PROGRESS +Windows.Win32.Foundation.ERROR_SERVER_SID_MISMATCH +Windows.Win32.Foundation.ERROR_SERVER_TRANSPORT_CONFLICT +Windows.Win32.Foundation.ERROR_SERVICE_ALREADY_RUNNING +Windows.Win32.Foundation.ERROR_SERVICE_CANNOT_ACCEPT_CTRL +Windows.Win32.Foundation.ERROR_SERVICE_DATABASE_LOCKED +Windows.Win32.Foundation.ERROR_SERVICE_DEPENDENCY_DELETED +Windows.Win32.Foundation.ERROR_SERVICE_DEPENDENCY_FAIL +Windows.Win32.Foundation.ERROR_SERVICE_DISABLED +Windows.Win32.Foundation.ERROR_SERVICE_DOES_NOT_EXIST +Windows.Win32.Foundation.ERROR_SERVICE_EXISTS +Windows.Win32.Foundation.ERROR_SERVICE_LOGON_FAILED +Windows.Win32.Foundation.ERROR_SERVICE_MARKED_FOR_DELETE +Windows.Win32.Foundation.ERROR_SERVICE_NEVER_STARTED +Windows.Win32.Foundation.ERROR_SERVICE_NO_THREAD +Windows.Win32.Foundation.ERROR_SERVICE_NOT_ACTIVE +Windows.Win32.Foundation.ERROR_SERVICE_NOT_FOUND +Windows.Win32.Foundation.ERROR_SERVICE_NOT_IN_EXE +Windows.Win32.Foundation.ERROR_SERVICE_NOTIFICATION +Windows.Win32.Foundation.ERROR_SERVICE_NOTIFY_CLIENT_LAGGING +Windows.Win32.Foundation.ERROR_SERVICE_REQUEST_TIMEOUT +Windows.Win32.Foundation.ERROR_SERVICE_SPECIFIC_ERROR +Windows.Win32.Foundation.ERROR_SERVICE_START_HANG +Windows.Win32.Foundation.ERROR_SESSION_CREDENTIAL_CONFLICT +Windows.Win32.Foundation.ERROR_SESSION_KEY_TOO_SHORT +Windows.Win32.Foundation.ERROR_SET_CONTEXT_DENIED +Windows.Win32.Foundation.ERROR_SET_NOT_FOUND +Windows.Win32.Foundation.ERROR_SET_POWER_STATE_FAILED +Windows.Win32.Foundation.ERROR_SET_POWER_STATE_VETOED +Windows.Win32.Foundation.ERROR_SETCOUNT_ON_BAD_LB +Windows.Win32.Foundation.ERROR_SETMARK_DETECTED +Windows.Win32.Foundation.ERROR_SHARED_POLICY +Windows.Win32.Foundation.ERROR_SHARING_BUFFER_EXCEEDED +Windows.Win32.Foundation.ERROR_SHARING_PAUSED +Windows.Win32.Foundation.ERROR_SHARING_VIOLATION +Windows.Win32.Foundation.ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME +Windows.Win32.Foundation.ERROR_SHUTDOWN_DISKS_NOT_IN_MAINTENANCE_MODE +Windows.Win32.Foundation.ERROR_SHUTDOWN_IN_PROGRESS +Windows.Win32.Foundation.ERROR_SHUTDOWN_IS_SCHEDULED +Windows.Win32.Foundation.ERROR_SHUTDOWN_USERS_LOGGED_ON +Windows.Win32.Foundation.ERROR_SIGNAL_PENDING +Windows.Win32.Foundation.ERROR_SIGNAL_REFUSED +Windows.Win32.Foundation.ERROR_SINGLE_INSTANCE_APP +Windows.Win32.Foundation.ERROR_SMARTCARD_SUBSYSTEM_FAILURE +Windows.Win32.Foundation.ERROR_SMB1_NOT_AVAILABLE +Windows.Win32.Foundation.ERROR_SMB_GUEST_LOGON_BLOCKED +Windows.Win32.Foundation.ERROR_SMR_GARBAGE_COLLECTION_REQUIRED +Windows.Win32.Foundation.ERROR_SOME_NOT_MAPPED +Windows.Win32.Foundation.ERROR_SOURCE_ELEMENT_EMPTY +Windows.Win32.Foundation.ERROR_SPARSE_FILE_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_SPECIAL_ACCOUNT +Windows.Win32.Foundation.ERROR_SPECIAL_GROUP +Windows.Win32.Foundation.ERROR_SPECIAL_USER +Windows.Win32.Foundation.ERROR_SRC_SRV_DLL_LOAD_FAILED +Windows.Win32.Foundation.ERROR_STACK_BUFFER_OVERRUN +Windows.Win32.Foundation.ERROR_STACK_OVERFLOW +Windows.Win32.Foundation.ERROR_STACK_OVERFLOW_READ +Windows.Win32.Foundation.ERROR_STOPPED_ON_SYMLINK +Windows.Win32.Foundation.ERROR_STORAGE_LOST_DATA_PERSISTENCE +Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_ALREADY_EXISTS +Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_DOES_NOT_EXIST +Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_ID_INVALID +Windows.Win32.Foundation.ERROR_STORAGE_RESERVE_NOT_EMPTY +Windows.Win32.Foundation.ERROR_STORAGE_STACK_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_STORAGE_TOPOLOGY_ID_MISMATCH +Windows.Win32.Foundation.ERROR_STRICT_CFG_VIOLATION +Windows.Win32.Foundation.ERROR_SUBST_TO_JOIN +Windows.Win32.Foundation.ERROR_SUBST_TO_SUBST +Windows.Win32.Foundation.ERROR_SUCCESS +Windows.Win32.Foundation.ERROR_SUCCESS_REBOOT_INITIATED +Windows.Win32.Foundation.ERROR_SWAPERROR +Windows.Win32.Foundation.ERROR_SYMLINK_CLASS_DISABLED +Windows.Win32.Foundation.ERROR_SYMLINK_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED +Windows.Win32.Foundation.ERROR_SYNCHRONIZATION_REQUIRED +Windows.Win32.Foundation.ERROR_SYSTEM_HIVE_TOO_LARGE +Windows.Win32.Foundation.ERROR_SYSTEM_IMAGE_BAD_SIGNATURE +Windows.Win32.Foundation.ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION +Windows.Win32.Foundation.ERROR_SYSTEM_POWERSTATE_TRANSITION +Windows.Win32.Foundation.ERROR_SYSTEM_PROCESS_TERMINATED +Windows.Win32.Foundation.ERROR_SYSTEM_SHUTDOWN +Windows.Win32.Foundation.ERROR_SYSTEM_TRACE +Windows.Win32.Foundation.ERROR_THREAD_1_INACTIVE +Windows.Win32.Foundation.ERROR_THREAD_ALREADY_IN_TASK +Windows.Win32.Foundation.ERROR_THREAD_MODE_ALREADY_BACKGROUND +Windows.Win32.Foundation.ERROR_THREAD_MODE_NOT_BACKGROUND +Windows.Win32.Foundation.ERROR_THREAD_NOT_IN_PROCESS +Windows.Win32.Foundation.ERROR_THREAD_WAS_SUSPENDED +Windows.Win32.Foundation.ERROR_TIME_SENSITIVE_THREAD +Windows.Win32.Foundation.ERROR_TIME_SKEW +Windows.Win32.Foundation.ERROR_TIMEOUT +Windows.Win32.Foundation.ERROR_TIMER_NOT_CANCELED +Windows.Win32.Foundation.ERROR_TIMER_RESOLUTION_NOT_SET +Windows.Win32.Foundation.ERROR_TIMER_RESUME_IGNORED +Windows.Win32.Foundation.ERROR_TLW_WITH_WSCHILD +Windows.Win32.Foundation.ERROR_TOKEN_ALREADY_IN_USE +Windows.Win32.Foundation.ERROR_TOO_MANY_CMDS +Windows.Win32.Foundation.ERROR_TOO_MANY_CONTEXT_IDS +Windows.Win32.Foundation.ERROR_TOO_MANY_DESCRIPTORS +Windows.Win32.Foundation.ERROR_TOO_MANY_LINKS +Windows.Win32.Foundation.ERROR_TOO_MANY_LUIDS_REQUESTED +Windows.Win32.Foundation.ERROR_TOO_MANY_MODULES +Windows.Win32.Foundation.ERROR_TOO_MANY_MUXWAITERS +Windows.Win32.Foundation.ERROR_TOO_MANY_NAMES +Windows.Win32.Foundation.ERROR_TOO_MANY_OPEN_FILES +Windows.Win32.Foundation.ERROR_TOO_MANY_POSTS +Windows.Win32.Foundation.ERROR_TOO_MANY_SECRETS +Windows.Win32.Foundation.ERROR_TOO_MANY_SEM_REQUESTS +Windows.Win32.Foundation.ERROR_TOO_MANY_SEMAPHORES +Windows.Win32.Foundation.ERROR_TOO_MANY_SESS +Windows.Win32.Foundation.ERROR_TOO_MANY_SIDS +Windows.Win32.Foundation.ERROR_TOO_MANY_TCBS +Windows.Win32.Foundation.ERROR_TOO_MANY_THREADS +Windows.Win32.Foundation.ERROR_TRANSLATION_COMPLETE +Windows.Win32.Foundation.ERROR_TRUST_FAILURE +Windows.Win32.Foundation.ERROR_TRUSTED_DOMAIN_FAILURE +Windows.Win32.Foundation.ERROR_TRUSTED_RELATIONSHIP_FAILURE +Windows.Win32.Foundation.ERROR_UNABLE_TO_LOCK_MEDIA +Windows.Win32.Foundation.ERROR_UNABLE_TO_MOVE_REPLACEMENT +Windows.Win32.Foundation.ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 +Windows.Win32.Foundation.ERROR_UNABLE_TO_REMOVE_REPLACED +Windows.Win32.Foundation.ERROR_UNABLE_TO_UNLOAD_MEDIA +Windows.Win32.Foundation.ERROR_UNDEFINED_CHARACTER +Windows.Win32.Foundation.ERROR_UNDEFINED_SCOPE +Windows.Win32.Foundation.ERROR_UNEXP_NET_ERR +Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_CREATE_ERR +Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_EXTEND_ERR +Windows.Win32.Foundation.ERROR_UNEXPECTED_MM_MAP_ERROR +Windows.Win32.Foundation.ERROR_UNEXPECTED_NTCACHEMANAGER_ERROR +Windows.Win32.Foundation.ERROR_UNHANDLED_EXCEPTION +Windows.Win32.Foundation.ERROR_UNIDENTIFIED_ERROR +Windows.Win32.Foundation.ERROR_UNKNOWN_COMPONENT +Windows.Win32.Foundation.ERROR_UNKNOWN_FEATURE +Windows.Win32.Foundation.ERROR_UNKNOWN_PATCH +Windows.Win32.Foundation.ERROR_UNKNOWN_PORT +Windows.Win32.Foundation.ERROR_UNKNOWN_PRINTER_DRIVER +Windows.Win32.Foundation.ERROR_UNKNOWN_PRINTPROCESSOR +Windows.Win32.Foundation.ERROR_UNKNOWN_PRODUCT +Windows.Win32.Foundation.ERROR_UNKNOWN_PROPERTY +Windows.Win32.Foundation.ERROR_UNKNOWN_REVISION +Windows.Win32.Foundation.ERROR_UNRECOGNIZED_MEDIA +Windows.Win32.Foundation.ERROR_UNRECOGNIZED_VOLUME +Windows.Win32.Foundation.ERROR_UNSATISFIED_DEPENDENCIES +Windows.Win32.Foundation.ERROR_UNSUPPORTED_COMPRESSION +Windows.Win32.Foundation.ERROR_UNSUPPORTED_TYPE +Windows.Win32.Foundation.ERROR_UNTRUSTED_MOUNT_POINT +Windows.Win32.Foundation.ERROR_UNWIND +Windows.Win32.Foundation.ERROR_UNWIND_CONSOLIDATE +Windows.Win32.Foundation.ERROR_USER_APC +Windows.Win32.Foundation.ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED +Windows.Win32.Foundation.ERROR_USER_EXISTS +Windows.Win32.Foundation.ERROR_USER_MAPPED_FILE +Windows.Win32.Foundation.ERROR_USER_PROFILE_LOAD +Windows.Win32.Foundation.ERROR_VALIDATE_CONTINUE +Windows.Win32.Foundation.ERROR_VC_DISCONNECTED +Windows.Win32.Foundation.ERROR_VDM_DISALLOWED +Windows.Win32.Foundation.ERROR_VDM_HARD_ERROR +Windows.Win32.Foundation.ERROR_VERIFIER_STOP +Windows.Win32.Foundation.ERROR_VERSION_PARSE_ERROR +Windows.Win32.Foundation.ERROR_VIRUS_DELETED +Windows.Win32.Foundation.ERROR_VIRUS_INFECTED +Windows.Win32.Foundation.ERROR_VOLSNAP_HIBERNATE_READY +Windows.Win32.Foundation.ERROR_VOLSNAP_PREPARE_HIBERNATE +Windows.Win32.Foundation.ERROR_VOLUME_MOUNTED +Windows.Win32.Foundation.ERROR_VOLUME_NOT_CLUSTER_ALIGNED +Windows.Win32.Foundation.ERROR_VOLUME_NOT_SIS_ENABLED +Windows.Win32.Foundation.ERROR_VOLUME_NOT_SUPPORT_EFS +Windows.Win32.Foundation.ERROR_VOLUME_NOT_SUPPORTED +Windows.Win32.Foundation.ERROR_VOLUME_WRITE_ACCESS_DENIED +Windows.Win32.Foundation.ERROR_WAIT_1 +Windows.Win32.Foundation.ERROR_WAIT_2 +Windows.Win32.Foundation.ERROR_WAIT_3 +Windows.Win32.Foundation.ERROR_WAIT_63 +Windows.Win32.Foundation.ERROR_WAIT_FOR_OPLOCK +Windows.Win32.Foundation.ERROR_WAIT_NO_CHILDREN +Windows.Win32.Foundation.ERROR_WAKE_SYSTEM +Windows.Win32.Foundation.ERROR_WAKE_SYSTEM_DEBUGGER +Windows.Win32.Foundation.ERROR_WAS_LOCKED +Windows.Win32.Foundation.ERROR_WAS_UNLOCKED +Windows.Win32.Foundation.ERROR_WEAK_WHFBKEY_BLOCKED +Windows.Win32.Foundation.ERROR_WINDOW_NOT_COMBOBOX +Windows.Win32.Foundation.ERROR_WINDOW_NOT_DIALOG +Windows.Win32.Foundation.ERROR_WINDOW_OF_OTHER_THREAD +Windows.Win32.Foundation.ERROR_WIP_ENCRYPTION_FAILED +Windows.Win32.Foundation.ERROR_WOF_FILE_RESOURCE_TABLE_CORRUPT +Windows.Win32.Foundation.ERROR_WOF_WIM_HEADER_CORRUPT +Windows.Win32.Foundation.ERROR_WOF_WIM_RESOURCE_TABLE_CORRUPT +Windows.Win32.Foundation.ERROR_WORKING_SET_QUOTA +Windows.Win32.Foundation.ERROR_WOW_ASSERTION +Windows.Win32.Foundation.ERROR_WRITE_FAULT +Windows.Win32.Foundation.ERROR_WRITE_PROTECT +Windows.Win32.Foundation.ERROR_WRONG_COMPARTMENT +Windows.Win32.Foundation.ERROR_WRONG_DISK +Windows.Win32.Foundation.ERROR_WRONG_EFS +Windows.Win32.Foundation.ERROR_WRONG_PASSWORD +Windows.Win32.Foundation.ERROR_WRONG_TARGET_NAME +Windows.Win32.Foundation.ERROR_WX86_ERROR +Windows.Win32.Foundation.ERROR_WX86_WARNING +Windows.Win32.Foundation.ERROR_XML_PARSE_ERROR +Windows.Win32.Foundation.ERROR_XMLDSIG_ERROR +Windows.Win32.Foundation.EXCEPTION_STACK_OVERFLOW +Windows.Win32.Foundation.FALSE +Windows.Win32.Foundation.FARPROC +Windows.Win32.Foundation.FILETIME +Windows.Win32.Foundation.FRS_ERR_SYSVOL_POPULATE_TIMEOUT +Windows.Win32.Foundation.GENERIC_ACCESS_RIGHTS +Windows.Win32.Foundation.GENERIC_ALL +Windows.Win32.Foundation.GENERIC_EXECUTE +Windows.Win32.Foundation.GENERIC_READ +Windows.Win32.Foundation.GENERIC_WRITE +Windows.Win32.Foundation.GetLastError +Windows.Win32.Foundation.HANDLE +Windows.Win32.Foundation.HANDLE_FLAG_INHERIT +Windows.Win32.Foundation.HANDLE_FLAG_PROTECT_FROM_CLOSE +Windows.Win32.Foundation.HANDLE_FLAGS +Windows.Win32.Foundation.HMODULE +Windows.Win32.Foundation.INVALID_HANDLE_VALUE +Windows.Win32.Foundation.MAX_PATH +Windows.Win32.Foundation.NO_ERROR +Windows.Win32.Foundation.NTSTATUS +Windows.Win32.Foundation.RtlNtStatusToDosError +Windows.Win32.Foundation.SetHandleInformation +Windows.Win32.Foundation.SetLastError +Windows.Win32.Foundation.STATUS_DELETE_PENDING +Windows.Win32.Foundation.STATUS_END_OF_FILE +Windows.Win32.Foundation.STATUS_INVALID_PARAMETER +Windows.Win32.Foundation.STATUS_PENDING +Windows.Win32.Foundation.STATUS_SUCCESS +Windows.Win32.Foundation.TRUE +Windows.Win32.Foundation.UNICODE_STRING +Windows.Win32.Foundation.WAIT_ABANDONED +Windows.Win32.Foundation.WAIT_ABANDONED_0 +Windows.Win32.Foundation.WAIT_FAILED +Windows.Win32.Foundation.WAIT_IO_COMPLETION +Windows.Win32.Foundation.WAIT_OBJECT_0 +Windows.Win32.Foundation.WAIT_TIMEOUT +Windows.Win32.Foundation.WIN32_ERROR +Windows.Win32.Globalization.COMPARESTRING_RESULT +Windows.Win32.Globalization.CompareStringOrdinal +Windows.Win32.Globalization.CP_UTF8 +Windows.Win32.Globalization.CSTR_EQUAL +Windows.Win32.Globalization.CSTR_GREATER_THAN +Windows.Win32.Globalization.CSTR_LESS_THAN +Windows.Win32.Globalization.MB_COMPOSITE +Windows.Win32.Globalization.MB_ERR_INVALID_CHARS +Windows.Win32.Globalization.MB_PRECOMPOSED +Windows.Win32.Globalization.MB_USEGLYPHCHARS +Windows.Win32.Globalization.MULTI_BYTE_TO_WIDE_CHAR_FLAGS +Windows.Win32.Globalization.MultiByteToWideChar +Windows.Win32.Globalization.WC_ERR_INVALID_CHARS +Windows.Win32.Globalization.WideCharToMultiByte +Windows.Win32.Networking.WinSock.accept +Windows.Win32.Networking.WinSock.ADDRESS_FAMILY +Windows.Win32.Networking.WinSock.ADDRINFOA +Windows.Win32.Networking.WinSock.AF_INET +Windows.Win32.Networking.WinSock.AF_INET6 +Windows.Win32.Networking.WinSock.AF_UNSPEC +Windows.Win32.Networking.WinSock.bind +Windows.Win32.Networking.WinSock.closesocket +Windows.Win32.Networking.WinSock.connect +Windows.Win32.Networking.WinSock.FD_SET +Windows.Win32.Networking.WinSock.FIONBIO +Windows.Win32.Networking.WinSock.freeaddrinfo +Windows.Win32.Networking.WinSock.getaddrinfo +Windows.Win32.Networking.WinSock.getpeername +Windows.Win32.Networking.WinSock.getsockname +Windows.Win32.Networking.WinSock.getsockopt +Windows.Win32.Networking.WinSock.IN6_ADDR +Windows.Win32.Networking.WinSock.IN_ADDR +Windows.Win32.Networking.WinSock.INVALID_SOCKET +Windows.Win32.Networking.WinSock.ioctlsocket +Windows.Win32.Networking.WinSock.IP_ADD_MEMBERSHIP +Windows.Win32.Networking.WinSock.IP_DROP_MEMBERSHIP +Windows.Win32.Networking.WinSock.IP_MREQ +Windows.Win32.Networking.WinSock.IP_MULTICAST_LOOP +Windows.Win32.Networking.WinSock.IP_MULTICAST_TTL +Windows.Win32.Networking.WinSock.IP_TTL +Windows.Win32.Networking.WinSock.IPPROTO +Windows.Win32.Networking.WinSock.IPPROTO_AH +Windows.Win32.Networking.WinSock.IPPROTO_CBT +Windows.Win32.Networking.WinSock.IPPROTO_DSTOPTS +Windows.Win32.Networking.WinSock.IPPROTO_EGP +Windows.Win32.Networking.WinSock.IPPROTO_ESP +Windows.Win32.Networking.WinSock.IPPROTO_FRAGMENT +Windows.Win32.Networking.WinSock.IPPROTO_GGP +Windows.Win32.Networking.WinSock.IPPROTO_HOPOPTS +Windows.Win32.Networking.WinSock.IPPROTO_ICLFXBM +Windows.Win32.Networking.WinSock.IPPROTO_ICMP +Windows.Win32.Networking.WinSock.IPPROTO_ICMPV6 +Windows.Win32.Networking.WinSock.IPPROTO_IDP +Windows.Win32.Networking.WinSock.IPPROTO_IGMP +Windows.Win32.Networking.WinSock.IPPROTO_IGP +Windows.Win32.Networking.WinSock.IPPROTO_IP +Windows.Win32.Networking.WinSock.IPPROTO_IPV4 +Windows.Win32.Networking.WinSock.IPPROTO_IPV6 +Windows.Win32.Networking.WinSock.IPPROTO_L2TP +Windows.Win32.Networking.WinSock.IPPROTO_MAX +Windows.Win32.Networking.WinSock.IPPROTO_ND +Windows.Win32.Networking.WinSock.IPPROTO_NONE +Windows.Win32.Networking.WinSock.IPPROTO_PGM +Windows.Win32.Networking.WinSock.IPPROTO_PIM +Windows.Win32.Networking.WinSock.IPPROTO_PUP +Windows.Win32.Networking.WinSock.IPPROTO_RAW +Windows.Win32.Networking.WinSock.IPPROTO_RDP +Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_IPSEC +Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_IPSECOFFLOAD +Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_MAX +Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_RAW +Windows.Win32.Networking.WinSock.IPPROTO_RESERVED_WNV +Windows.Win32.Networking.WinSock.IPPROTO_RM +Windows.Win32.Networking.WinSock.IPPROTO_ROUTING +Windows.Win32.Networking.WinSock.IPPROTO_SCTP +Windows.Win32.Networking.WinSock.IPPROTO_ST +Windows.Win32.Networking.WinSock.IPPROTO_TCP +Windows.Win32.Networking.WinSock.IPPROTO_UDP +Windows.Win32.Networking.WinSock.IPV6_ADD_MEMBERSHIP +Windows.Win32.Networking.WinSock.IPV6_DROP_MEMBERSHIP +Windows.Win32.Networking.WinSock.IPV6_MREQ +Windows.Win32.Networking.WinSock.IPV6_MULTICAST_LOOP +Windows.Win32.Networking.WinSock.IPV6_V6ONLY +Windows.Win32.Networking.WinSock.LINGER +Windows.Win32.Networking.WinSock.listen +Windows.Win32.Networking.WinSock.LPWSAOVERLAPPED_COMPLETION_ROUTINE +Windows.Win32.Networking.WinSock.MSG_DONTROUTE +Windows.Win32.Networking.WinSock.MSG_OOB +Windows.Win32.Networking.WinSock.MSG_PEEK +Windows.Win32.Networking.WinSock.MSG_PUSH_IMMEDIATE +Windows.Win32.Networking.WinSock.MSG_WAITALL +Windows.Win32.Networking.WinSock.recv +Windows.Win32.Networking.WinSock.recvfrom +Windows.Win32.Networking.WinSock.SD_BOTH +Windows.Win32.Networking.WinSock.SD_RECEIVE +Windows.Win32.Networking.WinSock.SD_SEND +Windows.Win32.Networking.WinSock.select +Windows.Win32.Networking.WinSock.send +Windows.Win32.Networking.WinSock.SEND_RECV_FLAGS +Windows.Win32.Networking.WinSock.sendto +Windows.Win32.Networking.WinSock.setsockopt +Windows.Win32.Networking.WinSock.shutdown +Windows.Win32.Networking.WinSock.SO_BROADCAST +Windows.Win32.Networking.WinSock.SO_ERROR +Windows.Win32.Networking.WinSock.SO_LINGER +Windows.Win32.Networking.WinSock.SO_RCVTIMEO +Windows.Win32.Networking.WinSock.SO_SNDTIMEO +Windows.Win32.Networking.WinSock.SOCK_DGRAM +Windows.Win32.Networking.WinSock.SOCK_RAW +Windows.Win32.Networking.WinSock.SOCK_RDM +Windows.Win32.Networking.WinSock.SOCK_SEQPACKET +Windows.Win32.Networking.WinSock.SOCK_STREAM +Windows.Win32.Networking.WinSock.SOCKADDR +Windows.Win32.Networking.WinSock.SOCKET +Windows.Win32.Networking.WinSock.SOCKET_ERROR +Windows.Win32.Networking.WinSock.SOL_SOCKET +Windows.Win32.Networking.WinSock.TCP_NODELAY +Windows.Win32.Networking.WinSock.TIMEVAL +Windows.Win32.Networking.WinSock.WINSOCK_SHUTDOWN_HOW +Windows.Win32.Networking.WinSock.WINSOCK_SOCKET_TYPE +Windows.Win32.Networking.WinSock.WSA_E_CANCELLED +Windows.Win32.Networking.WinSock.WSA_E_NO_MORE +Windows.Win32.Networking.WinSock.WSA_ERROR +Windows.Win32.Networking.WinSock.WSA_FLAG_NO_HANDLE_INHERIT +Windows.Win32.Networking.WinSock.WSA_FLAG_OVERLAPPED +Windows.Win32.Networking.WinSock.WSA_INVALID_HANDLE +Windows.Win32.Networking.WinSock.WSA_INVALID_PARAMETER +Windows.Win32.Networking.WinSock.WSA_IO_INCOMPLETE +Windows.Win32.Networking.WinSock.WSA_IO_PENDING +Windows.Win32.Networking.WinSock.WSA_IPSEC_NAME_POLICY_ERROR +Windows.Win32.Networking.WinSock.WSA_NOT_ENOUGH_MEMORY +Windows.Win32.Networking.WinSock.WSA_OPERATION_ABORTED +Windows.Win32.Networking.WinSock.WSA_QOS_ADMISSION_FAILURE +Windows.Win32.Networking.WinSock.WSA_QOS_BAD_OBJECT +Windows.Win32.Networking.WinSock.WSA_QOS_BAD_STYLE +Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERCOUNT +Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERSTYLE +Windows.Win32.Networking.WinSock.WSA_QOS_EFILTERTYPE +Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWCOUNT +Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWDESC +Windows.Win32.Networking.WinSock.WSA_QOS_EFLOWSPEC +Windows.Win32.Networking.WinSock.WSA_QOS_EOBJLENGTH +Windows.Win32.Networking.WinSock.WSA_QOS_EPOLICYOBJ +Windows.Win32.Networking.WinSock.WSA_QOS_EPROVSPECBUF +Windows.Win32.Networking.WinSock.WSA_QOS_EPSFILTERSPEC +Windows.Win32.Networking.WinSock.WSA_QOS_EPSFLOWSPEC +Windows.Win32.Networking.WinSock.WSA_QOS_ESDMODEOBJ +Windows.Win32.Networking.WinSock.WSA_QOS_ESERVICETYPE +Windows.Win32.Networking.WinSock.WSA_QOS_ESHAPERATEOBJ +Windows.Win32.Networking.WinSock.WSA_QOS_EUNKOWNPSOBJ +Windows.Win32.Networking.WinSock.WSA_QOS_GENERIC_ERROR +Windows.Win32.Networking.WinSock.WSA_QOS_NO_RECEIVERS +Windows.Win32.Networking.WinSock.WSA_QOS_NO_SENDERS +Windows.Win32.Networking.WinSock.WSA_QOS_POLICY_FAILURE +Windows.Win32.Networking.WinSock.WSA_QOS_RECEIVERS +Windows.Win32.Networking.WinSock.WSA_QOS_REQUEST_CONFIRMED +Windows.Win32.Networking.WinSock.WSA_QOS_RESERVED_PETYPE +Windows.Win32.Networking.WinSock.WSA_QOS_SENDERS +Windows.Win32.Networking.WinSock.WSA_QOS_TRAFFIC_CTRL_ERROR +Windows.Win32.Networking.WinSock.WSA_SECURE_HOST_NOT_FOUND +Windows.Win32.Networking.WinSock.WSA_WAIT_EVENT_0 +Windows.Win32.Networking.WinSock.WSA_WAIT_IO_COMPLETION +Windows.Win32.Networking.WinSock.WSABASEERR +Windows.Win32.Networking.WinSock.WSABUF +Windows.Win32.Networking.WinSock.WSACleanup +Windows.Win32.Networking.WinSock.WSADATA +Windows.Win32.Networking.WinSock.WSADATA +Windows.Win32.Networking.WinSock.WSADuplicateSocketW +Windows.Win32.Networking.WinSock.WSAEACCES +Windows.Win32.Networking.WinSock.WSAEADDRINUSE +Windows.Win32.Networking.WinSock.WSAEADDRNOTAVAIL +Windows.Win32.Networking.WinSock.WSAEAFNOSUPPORT +Windows.Win32.Networking.WinSock.WSAEALREADY +Windows.Win32.Networking.WinSock.WSAEBADF +Windows.Win32.Networking.WinSock.WSAECANCELLED +Windows.Win32.Networking.WinSock.WSAECONNABORTED +Windows.Win32.Networking.WinSock.WSAECONNREFUSED +Windows.Win32.Networking.WinSock.WSAECONNRESET +Windows.Win32.Networking.WinSock.WSAEDESTADDRREQ +Windows.Win32.Networking.WinSock.WSAEDISCON +Windows.Win32.Networking.WinSock.WSAEDQUOT +Windows.Win32.Networking.WinSock.WSAEFAULT +Windows.Win32.Networking.WinSock.WSAEHOSTDOWN +Windows.Win32.Networking.WinSock.WSAEHOSTUNREACH +Windows.Win32.Networking.WinSock.WSAEINPROGRESS +Windows.Win32.Networking.WinSock.WSAEINTR +Windows.Win32.Networking.WinSock.WSAEINVAL +Windows.Win32.Networking.WinSock.WSAEINVALIDPROCTABLE +Windows.Win32.Networking.WinSock.WSAEINVALIDPROVIDER +Windows.Win32.Networking.WinSock.WSAEISCONN +Windows.Win32.Networking.WinSock.WSAELOOP +Windows.Win32.Networking.WinSock.WSAEMFILE +Windows.Win32.Networking.WinSock.WSAEMSGSIZE +Windows.Win32.Networking.WinSock.WSAENAMETOOLONG +Windows.Win32.Networking.WinSock.WSAENETDOWN +Windows.Win32.Networking.WinSock.WSAENETRESET +Windows.Win32.Networking.WinSock.WSAENETUNREACH +Windows.Win32.Networking.WinSock.WSAENOBUFS +Windows.Win32.Networking.WinSock.WSAENOMORE +Windows.Win32.Networking.WinSock.WSAENOPROTOOPT +Windows.Win32.Networking.WinSock.WSAENOTCONN +Windows.Win32.Networking.WinSock.WSAENOTEMPTY +Windows.Win32.Networking.WinSock.WSAENOTSOCK +Windows.Win32.Networking.WinSock.WSAEOPNOTSUPP +Windows.Win32.Networking.WinSock.WSAEPFNOSUPPORT +Windows.Win32.Networking.WinSock.WSAEPROCLIM +Windows.Win32.Networking.WinSock.WSAEPROTONOSUPPORT +Windows.Win32.Networking.WinSock.WSAEPROTOTYPE +Windows.Win32.Networking.WinSock.WSAEPROVIDERFAILEDINIT +Windows.Win32.Networking.WinSock.WSAEREFUSED +Windows.Win32.Networking.WinSock.WSAEREMOTE +Windows.Win32.Networking.WinSock.WSAESHUTDOWN +Windows.Win32.Networking.WinSock.WSAESOCKTNOSUPPORT +Windows.Win32.Networking.WinSock.WSAESTALE +Windows.Win32.Networking.WinSock.WSAETIMEDOUT +Windows.Win32.Networking.WinSock.WSAETOOMANYREFS +Windows.Win32.Networking.WinSock.WSAEUSERS +Windows.Win32.Networking.WinSock.WSAEWOULDBLOCK +Windows.Win32.Networking.WinSock.WSAGetLastError +Windows.Win32.Networking.WinSock.WSAHOST_NOT_FOUND +Windows.Win32.Networking.WinSock.WSANO_DATA +Windows.Win32.Networking.WinSock.WSANO_RECOVERY +Windows.Win32.Networking.WinSock.WSANOTINITIALISED +Windows.Win32.Networking.WinSock.WSAPROTOCOL_INFOW +Windows.Win32.Networking.WinSock.WSAPROTOCOLCHAIN +Windows.Win32.Networking.WinSock.WSARecv +Windows.Win32.Networking.WinSock.WSASend +Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND +Windows.Win32.Networking.WinSock.WSASocketW +Windows.Win32.Networking.WinSock.WSAStartup +Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE +Windows.Win32.Networking.WinSock.WSASYSNOTREADY +Windows.Win32.Networking.WinSock.WSATRY_AGAIN +Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND +Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED +Windows.Win32.Security.Authentication.Identity.RtlGenRandom +Windows.Win32.Security.Cryptography.BCRYPT_ALG_HANDLE +Windows.Win32.Security.Cryptography.BCRYPT_USE_SYSTEM_PREFERRED_RNG +Windows.Win32.Security.Cryptography.BCryptGenRandom +Windows.Win32.Security.Cryptography.BCRYPTGENRANDOM_FLAGS +Windows.Win32.Security.SECURITY_ATTRIBUTES +Windows.Win32.Security.TOKEN_ACCESS_MASK +Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE +Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 +Windows.Win32.Security.TOKEN_ACCESS_SYSTEM_SECURITY +Windows.Win32.Security.TOKEN_ADJUST_DEFAULT +Windows.Win32.Security.TOKEN_ADJUST_GROUPS +Windows.Win32.Security.TOKEN_ADJUST_PRIVILEGES +Windows.Win32.Security.TOKEN_ADJUST_SESSIONID +Windows.Win32.Security.TOKEN_ALL_ACCESS +Windows.Win32.Security.TOKEN_ASSIGN_PRIMARY +Windows.Win32.Security.TOKEN_DELETE +Windows.Win32.Security.TOKEN_DUPLICATE +Windows.Win32.Security.TOKEN_EXECUTE +Windows.Win32.Security.TOKEN_IMPERSONATE +Windows.Win32.Security.TOKEN_QUERY +Windows.Win32.Security.TOKEN_QUERY_SOURCE +Windows.Win32.Security.TOKEN_READ +Windows.Win32.Security.TOKEN_READ_CONTROL +Windows.Win32.Security.TOKEN_TRUST_CONSTRAINT_MASK +Windows.Win32.Security.TOKEN_WRITE +Windows.Win32.Security.TOKEN_WRITE_DAC +Windows.Win32.Security.TOKEN_WRITE_OWNER +Windows.Win32.Storage.FileSystem.BY_HANDLE_FILE_INFORMATION +Windows.Win32.Storage.FileSystem.CALLBACK_CHUNK_FINISHED +Windows.Win32.Storage.FileSystem.CALLBACK_STREAM_SWITCH +Windows.Win32.Storage.FileSystem.CopyFileExW +Windows.Win32.Storage.FileSystem.CREATE_ALWAYS +Windows.Win32.Storage.FileSystem.CREATE_NEW +Windows.Win32.Storage.FileSystem.CreateDirectoryW +Windows.Win32.Storage.FileSystem.CreateFileW +Windows.Win32.Storage.FileSystem.CreateHardLinkW +Windows.Win32.Storage.FileSystem.CreateSymbolicLinkW +Windows.Win32.Storage.FileSystem.DELETE +Windows.Win32.Storage.FileSystem.DeleteFileW +Windows.Win32.Storage.FileSystem.FILE_ACCESS_RIGHTS +Windows.Win32.Storage.FileSystem.FILE_ADD_FILE +Windows.Win32.Storage.FileSystem.FILE_ADD_SUBDIRECTORY +Windows.Win32.Storage.FileSystem.FILE_ALL_ACCESS +Windows.Win32.Storage.FileSystem.FILE_APPEND_DATA +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_ARCHIVE +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_COMPRESSED +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_DEVICE +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_DIRECTORY +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_EA +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_ENCRYPTED +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_HIDDEN +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_INTEGRITY_STREAM +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NO_SCRUB_DATA +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NORMAL +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_OFFLINE +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_PINNED +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_READONLY +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_RECALL_ON_OPEN +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_REPARSE_POINT +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_SPARSE_FILE +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_SYSTEM +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_TAG_INFO +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_TEMPORARY +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_UNPINNED +Windows.Win32.Storage.FileSystem.FILE_ATTRIBUTE_VIRTUAL +Windows.Win32.Storage.FileSystem.FILE_BASIC_INFO +Windows.Win32.Storage.FileSystem.FILE_BEGIN +Windows.Win32.Storage.FileSystem.FILE_CREATE_PIPE_INSTANCE +Windows.Win32.Storage.FileSystem.FILE_CREATION_DISPOSITION +Windows.Win32.Storage.FileSystem.FILE_CURRENT +Windows.Win32.Storage.FileSystem.FILE_DELETE_CHILD +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_DELETE +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_DO_NOT_DELETE +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_FORCE_IMAGE_SECTION_CHECK +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_ON_CLOSE +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_FLAG_POSIX_SEMANTICS +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO_EX +Windows.Win32.Storage.FileSystem.FILE_DISPOSITION_INFO_EX_FLAGS +Windows.Win32.Storage.FileSystem.FILE_END +Windows.Win32.Storage.FileSystem.FILE_END_OF_FILE_INFO +Windows.Win32.Storage.FileSystem.FILE_EXECUTE +Windows.Win32.Storage.FileSystem.FILE_FLAG_BACKUP_SEMANTICS +Windows.Win32.Storage.FileSystem.FILE_FLAG_DELETE_ON_CLOSE +Windows.Win32.Storage.FileSystem.FILE_FLAG_FIRST_PIPE_INSTANCE +Windows.Win32.Storage.FileSystem.FILE_FLAG_NO_BUFFERING +Windows.Win32.Storage.FileSystem.FILE_FLAG_OPEN_NO_RECALL +Windows.Win32.Storage.FileSystem.FILE_FLAG_OPEN_REPARSE_POINT +Windows.Win32.Storage.FileSystem.FILE_FLAG_OVERLAPPED +Windows.Win32.Storage.FileSystem.FILE_FLAG_POSIX_SEMANTICS +Windows.Win32.Storage.FileSystem.FILE_FLAG_RANDOM_ACCESS +Windows.Win32.Storage.FileSystem.FILE_FLAG_SEQUENTIAL_SCAN +Windows.Win32.Storage.FileSystem.FILE_FLAG_SESSION_AWARE +Windows.Win32.Storage.FileSystem.FILE_FLAG_WRITE_THROUGH +Windows.Win32.Storage.FileSystem.FILE_FLAGS_AND_ATTRIBUTES +Windows.Win32.Storage.FileSystem.FILE_GENERIC_EXECUTE +Windows.Win32.Storage.FileSystem.FILE_GENERIC_READ +Windows.Win32.Storage.FileSystem.FILE_GENERIC_WRITE +Windows.Win32.Storage.FileSystem.FILE_ID_BOTH_DIR_INFO +Windows.Win32.Storage.FileSystem.FILE_INFO_BY_HANDLE_CLASS +Windows.Win32.Storage.FileSystem.FILE_LIST_DIRECTORY +Windows.Win32.Storage.FileSystem.FILE_NAME_NORMALIZED +Windows.Win32.Storage.FileSystem.FILE_NAME_OPENED +Windows.Win32.Storage.FileSystem.FILE_READ_ATTRIBUTES +Windows.Win32.Storage.FileSystem.FILE_READ_DATA +Windows.Win32.Storage.FileSystem.FILE_READ_EA +Windows.Win32.Storage.FileSystem.FILE_SHARE_DELETE +Windows.Win32.Storage.FileSystem.FILE_SHARE_MODE +Windows.Win32.Storage.FileSystem.FILE_SHARE_NONE +Windows.Win32.Storage.FileSystem.FILE_SHARE_READ +Windows.Win32.Storage.FileSystem.FILE_SHARE_WRITE +Windows.Win32.Storage.FileSystem.FILE_STANDARD_INFO +Windows.Win32.Storage.FileSystem.FILE_TRAVERSE +Windows.Win32.Storage.FileSystem.FILE_TYPE +Windows.Win32.Storage.FileSystem.FILE_TYPE_CHAR +Windows.Win32.Storage.FileSystem.FILE_TYPE_DISK +Windows.Win32.Storage.FileSystem.FILE_TYPE_PIPE +Windows.Win32.Storage.FileSystem.FILE_TYPE_REMOTE +Windows.Win32.Storage.FileSystem.FILE_TYPE_UNKNOWN +Windows.Win32.Storage.FileSystem.FILE_WRITE_ATTRIBUTES +Windows.Win32.Storage.FileSystem.FILE_WRITE_DATA +Windows.Win32.Storage.FileSystem.FILE_WRITE_EA +Windows.Win32.Storage.FileSystem.FileAlignmentInfo +Windows.Win32.Storage.FileSystem.FileAllocationInfo +Windows.Win32.Storage.FileSystem.FileAttributeTagInfo +Windows.Win32.Storage.FileSystem.FileBasicInfo +Windows.Win32.Storage.FileSystem.FileCaseSensitiveInfo +Windows.Win32.Storage.FileSystem.FileCompressionInfo +Windows.Win32.Storage.FileSystem.FileDispositionInfo +Windows.Win32.Storage.FileSystem.FileDispositionInfoEx +Windows.Win32.Storage.FileSystem.FileEndOfFileInfo +Windows.Win32.Storage.FileSystem.FileFullDirectoryInfo +Windows.Win32.Storage.FileSystem.FileFullDirectoryRestartInfo +Windows.Win32.Storage.FileSystem.FileIdBothDirectoryInfo +Windows.Win32.Storage.FileSystem.FileIdBothDirectoryRestartInfo +Windows.Win32.Storage.FileSystem.FileIdExtdDirectoryInfo +Windows.Win32.Storage.FileSystem.FileIdExtdDirectoryRestartInfo +Windows.Win32.Storage.FileSystem.FileIdInfo +Windows.Win32.Storage.FileSystem.FileIoPriorityHintInfo +Windows.Win32.Storage.FileSystem.FileNameInfo +Windows.Win32.Storage.FileSystem.FileNormalizedNameInfo +Windows.Win32.Storage.FileSystem.FileRemoteProtocolInfo +Windows.Win32.Storage.FileSystem.FileRenameInfo +Windows.Win32.Storage.FileSystem.FileRenameInfoEx +Windows.Win32.Storage.FileSystem.FileStandardInfo +Windows.Win32.Storage.FileSystem.FileStorageInfo +Windows.Win32.Storage.FileSystem.FileStreamInfo +Windows.Win32.Storage.FileSystem.FindClose +Windows.Win32.Storage.FileSystem.FindFileHandle +Windows.Win32.Storage.FileSystem.FindFirstFileW +Windows.Win32.Storage.FileSystem.FindNextFileW +Windows.Win32.Storage.FileSystem.FlushFileBuffers +Windows.Win32.Storage.FileSystem.GetFileAttributesW +Windows.Win32.Storage.FileSystem.GetFileInformationByHandle +Windows.Win32.Storage.FileSystem.GetFileInformationByHandleEx +Windows.Win32.Storage.FileSystem.GetFileType +Windows.Win32.Storage.FileSystem.GETFINALPATHNAMEBYHANDLE_FLAGS +Windows.Win32.Storage.FileSystem.GetFinalPathNameByHandleW +Windows.Win32.Storage.FileSystem.GetFullPathNameW +Windows.Win32.Storage.FileSystem.GetTempPathW +Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES +Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE +Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE_CALLBACK_REASON +Windows.Win32.Storage.FileSystem.MAXIMUM_REPARSE_DATA_BUFFER_SIZE +Windows.Win32.Storage.FileSystem.MaximumFileInfoByHandleClass +Windows.Win32.Storage.FileSystem.MOVE_FILE_FLAGS +Windows.Win32.Storage.FileSystem.MOVEFILE_COPY_ALLOWED +Windows.Win32.Storage.FileSystem.MOVEFILE_CREATE_HARDLINK +Windows.Win32.Storage.FileSystem.MOVEFILE_DELAY_UNTIL_REBOOT +Windows.Win32.Storage.FileSystem.MOVEFILE_FAIL_IF_NOT_TRACKABLE +Windows.Win32.Storage.FileSystem.MOVEFILE_REPLACE_EXISTING +Windows.Win32.Storage.FileSystem.MOVEFILE_WRITE_THROUGH +Windows.Win32.Storage.FileSystem.MoveFileExW +Windows.Win32.Storage.FileSystem.OPEN_ALWAYS +Windows.Win32.Storage.FileSystem.OPEN_EXISTING +Windows.Win32.Storage.FileSystem.PIPE_ACCESS_DUPLEX +Windows.Win32.Storage.FileSystem.PIPE_ACCESS_INBOUND +Windows.Win32.Storage.FileSystem.PIPE_ACCESS_OUTBOUND +Windows.Win32.Storage.FileSystem.READ_CONTROL +Windows.Win32.Storage.FileSystem.ReadFile +Windows.Win32.Storage.FileSystem.ReadFileEx +Windows.Win32.Storage.FileSystem.RemoveDirectoryW +Windows.Win32.Storage.FileSystem.SECURITY_ANONYMOUS +Windows.Win32.Storage.FileSystem.SECURITY_CONTEXT_TRACKING +Windows.Win32.Storage.FileSystem.SECURITY_DELEGATION +Windows.Win32.Storage.FileSystem.SECURITY_EFFECTIVE_ONLY +Windows.Win32.Storage.FileSystem.SECURITY_IDENTIFICATION +Windows.Win32.Storage.FileSystem.SECURITY_IMPERSONATION +Windows.Win32.Storage.FileSystem.SECURITY_SQOS_PRESENT +Windows.Win32.Storage.FileSystem.SECURITY_VALID_SQOS_FLAGS +Windows.Win32.Storage.FileSystem.SET_FILE_POINTER_MOVE_METHOD +Windows.Win32.Storage.FileSystem.SetFileAttributesW +Windows.Win32.Storage.FileSystem.SetFileInformationByHandle +Windows.Win32.Storage.FileSystem.SetFilePointerEx +Windows.Win32.Storage.FileSystem.SetFileTime +Windows.Win32.Storage.FileSystem.SPECIFIC_RIGHTS_ALL +Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_ALL +Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_EXECUTE +Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_READ +Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_REQUIRED +Windows.Win32.Storage.FileSystem.STANDARD_RIGHTS_WRITE +Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAG_DIRECTORY +Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAGS +Windows.Win32.Storage.FileSystem.SYNCHRONIZE +Windows.Win32.Storage.FileSystem.TRUNCATE_EXISTING +Windows.Win32.Storage.FileSystem.VOLUME_NAME_DOS +Windows.Win32.Storage.FileSystem.VOLUME_NAME_GUID +Windows.Win32.Storage.FileSystem.VOLUME_NAME_NONE +Windows.Win32.Storage.FileSystem.WIN32_FIND_DATAW +Windows.Win32.Storage.FileSystem.WRITE_DAC +Windows.Win32.Storage.FileSystem.WRITE_OWNER +Windows.Win32.Storage.FileSystem.WriteFileEx +Windows.Win32.System.Console.CONSOLE_MODE +Windows.Win32.System.Console.CONSOLE_READCONSOLE_CONTROL +Windows.Win32.System.Console.DISABLE_NEWLINE_AUTO_RETURN +Windows.Win32.System.Console.ENABLE_AUTO_POSITION +Windows.Win32.System.Console.ENABLE_ECHO_INPUT +Windows.Win32.System.Console.ENABLE_EXTENDED_FLAGS +Windows.Win32.System.Console.ENABLE_INSERT_MODE +Windows.Win32.System.Console.ENABLE_LINE_INPUT +Windows.Win32.System.Console.ENABLE_LVB_GRID_WORLDWIDE +Windows.Win32.System.Console.ENABLE_MOUSE_INPUT +Windows.Win32.System.Console.ENABLE_PROCESSED_INPUT +Windows.Win32.System.Console.ENABLE_PROCESSED_OUTPUT +Windows.Win32.System.Console.ENABLE_QUICK_EDIT_MODE +Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_INPUT +Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_PROCESSING +Windows.Win32.System.Console.ENABLE_WINDOW_INPUT +Windows.Win32.System.Console.ENABLE_WRAP_AT_EOL_OUTPUT +Windows.Win32.System.Console.GetConsoleMode +Windows.Win32.System.Console.GetStdHandle +Windows.Win32.System.Console.ReadConsoleW +Windows.Win32.System.Console.STD_ERROR_HANDLE +Windows.Win32.System.Console.STD_HANDLE +Windows.Win32.System.Console.STD_INPUT_HANDLE +Windows.Win32.System.Console.STD_OUTPUT_HANDLE +Windows.Win32.System.Console.WriteConsoleW +Windows.Win32.System.Diagnostics.Debug.AddVectoredExceptionHandler +Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128 +Windows.Win32.System.Diagnostics.Debug.CONTEXT +Windows.Win32.System.Diagnostics.Debug.CONTEXT +Windows.Win32.System.Diagnostics.Debug.CONTEXT +Windows.Win32.System.Diagnostics.Debug.EXCEPTION_POINTERS +Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD +Windows.Win32.System.Diagnostics.Debug.FACILITY_CODE +Windows.Win32.System.Diagnostics.Debug.FACILITY_NT_BIT +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_ALLOCATE_BUFFER +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_ARGUMENT_ARRAY +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_HMODULE +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_STRING +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_FROM_SYSTEM +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_IGNORE_INSERTS +Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_OPTIONS +Windows.Win32.System.Diagnostics.Debug.FormatMessageW +Windows.Win32.System.Diagnostics.Debug.M128A +Windows.Win32.System.Diagnostics.Debug.PVECTORED_EXCEPTION_HANDLER +Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT +Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT +Windows.Win32.System.Environment.FreeEnvironmentStringsW +Windows.Win32.System.Environment.GetCommandLineW +Windows.Win32.System.Environment.GetCurrentDirectoryW +Windows.Win32.System.Environment.GetEnvironmentStringsW +Windows.Win32.System.Environment.GetEnvironmentVariableW +Windows.Win32.System.Environment.SetCurrentDirectoryW +Windows.Win32.System.Environment.SetEnvironmentVariableW +Windows.Win32.System.IO.CancelIo +Windows.Win32.System.IO.DeviceIoControl +Windows.Win32.System.IO.GetOverlappedResult +Windows.Win32.System.IO.LPOVERLAPPED_COMPLETION_ROUTINE +Windows.Win32.System.IO.OVERLAPPED +Windows.Win32.System.Ioctl.FSCTL_GET_REPARSE_POINT +Windows.Win32.System.Ioctl.FSCTL_SET_REPARSE_POINT +Windows.Win32.System.Kernel.EXCEPTION_DISPOSITION +Windows.Win32.System.Kernel.ExceptionCollidedUnwind +Windows.Win32.System.Kernel.ExceptionContinueExecution +Windows.Win32.System.Kernel.ExceptionContinueSearch +Windows.Win32.System.Kernel.ExceptionNestedException +Windows.Win32.System.Kernel.FLOATING_SAVE_AREA +Windows.Win32.System.Kernel.FLOATING_SAVE_AREA +Windows.Win32.System.Kernel.OBJ_DONT_REPARSE +Windows.Win32.System.LibraryLoader.GetModuleFileNameW +Windows.Win32.System.LibraryLoader.GetModuleHandleA +Windows.Win32.System.LibraryLoader.GetModuleHandleW +Windows.Win32.System.LibraryLoader.GetProcAddress +Windows.Win32.System.Performance.QueryPerformanceCounter +Windows.Win32.System.Performance.QueryPerformanceFrequency +Windows.Win32.System.Pipes.CreateNamedPipeW +Windows.Win32.System.Pipes.NAMED_PIPE_MODE +Windows.Win32.System.Pipes.PIPE_ACCEPT_REMOTE_CLIENTS +Windows.Win32.System.Pipes.PIPE_CLIENT_END +Windows.Win32.System.Pipes.PIPE_NOWAIT +Windows.Win32.System.Pipes.PIPE_READMODE_BYTE +Windows.Win32.System.Pipes.PIPE_READMODE_MESSAGE +Windows.Win32.System.Pipes.PIPE_REJECT_REMOTE_CLIENTS +Windows.Win32.System.Pipes.PIPE_SERVER_END +Windows.Win32.System.Pipes.PIPE_TYPE_BYTE +Windows.Win32.System.Pipes.PIPE_TYPE_MESSAGE +Windows.Win32.System.Pipes.PIPE_WAIT +Windows.Win32.System.SystemInformation.GetSystemDirectoryW +Windows.Win32.System.SystemInformation.GetSystemInfo +Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime +Windows.Win32.System.SystemInformation.GetWindowsDirectoryW +Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE +Windows.Win32.System.SystemInformation.SYSTEM_INFO +Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH +Windows.Win32.System.SystemServices.DLL_THREAD_DETACH +Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS +Windows.Win32.System.SystemServices.IO_REPARSE_TAG_MOUNT_POINT +Windows.Win32.System.SystemServices.IO_REPARSE_TAG_SYMLINK +Windows.Win32.System.Threading.ABOVE_NORMAL_PRIORITY_CLASS +Windows.Win32.System.Threading.AcquireSRWLockExclusive +Windows.Win32.System.Threading.AcquireSRWLockShared +Windows.Win32.System.Threading.BELOW_NORMAL_PRIORITY_CLASS +Windows.Win32.System.Threading.CREATE_BREAKAWAY_FROM_JOB +Windows.Win32.System.Threading.CREATE_DEFAULT_ERROR_MODE +Windows.Win32.System.Threading.CREATE_FORCEDOS +Windows.Win32.System.Threading.CREATE_IGNORE_SYSTEM_DEFAULT +Windows.Win32.System.Threading.CREATE_NEW_CONSOLE +Windows.Win32.System.Threading.CREATE_NEW_PROCESS_GROUP +Windows.Win32.System.Threading.CREATE_NO_WINDOW +Windows.Win32.System.Threading.CREATE_PRESERVE_CODE_AUTHZ_LEVEL +Windows.Win32.System.Threading.CREATE_PROTECTED_PROCESS +Windows.Win32.System.Threading.CREATE_SECURE_PROCESS +Windows.Win32.System.Threading.CREATE_SEPARATE_WOW_VDM +Windows.Win32.System.Threading.CREATE_SHARED_WOW_VDM +Windows.Win32.System.Threading.CREATE_SUSPENDED +Windows.Win32.System.Threading.CREATE_UNICODE_ENVIRONMENT +Windows.Win32.System.Threading.CreateEventW +Windows.Win32.System.Threading.CreateProcessW +Windows.Win32.System.Threading.CreateThread +Windows.Win32.System.Threading.DEBUG_ONLY_THIS_PROCESS +Windows.Win32.System.Threading.DEBUG_PROCESS +Windows.Win32.System.Threading.DETACHED_PROCESS +Windows.Win32.System.Threading.ExitProcess +Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT +Windows.Win32.System.Threading.GetCurrentProcess +Windows.Win32.System.Threading.GetCurrentProcessId +Windows.Win32.System.Threading.GetCurrentThread +Windows.Win32.System.Threading.GetExitCodeProcess +Windows.Win32.System.Threading.GetProcessId +Windows.Win32.System.Threading.HIGH_PRIORITY_CLASS +Windows.Win32.System.Threading.IDLE_PRIORITY_CLASS +Windows.Win32.System.Threading.INFINITE +Windows.Win32.System.Threading.INHERIT_CALLER_PRIORITY +Windows.Win32.System.Threading.INHERIT_PARENT_AFFINITY +Windows.Win32.System.Threading.INIT_ONCE_INIT_FAILED +Windows.Win32.System.Threading.InitOnceBeginInitialize +Windows.Win32.System.Threading.InitOnceComplete +Windows.Win32.System.Threading.LPTHREAD_START_ROUTINE +Windows.Win32.System.Threading.NORMAL_PRIORITY_CLASS +Windows.Win32.System.Threading.OpenProcessToken +Windows.Win32.System.Threading.PROCESS_CREATION_FLAGS +Windows.Win32.System.Threading.PROCESS_INFORMATION +Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_BEGIN +Windows.Win32.System.Threading.PROCESS_MODE_BACKGROUND_END +Windows.Win32.System.Threading.PROFILE_KERNEL +Windows.Win32.System.Threading.PROFILE_SERVER +Windows.Win32.System.Threading.PROFILE_USER +Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS +Windows.Win32.System.Threading.ReleaseSRWLockExclusive +Windows.Win32.System.Threading.ReleaseSRWLockShared +Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE +Windows.Win32.System.Threading.RTL_RUN_ONCE +Windows.Win32.System.Threading.RTL_SRWLOCK +Windows.Win32.System.Threading.SetThreadStackGuarantee +Windows.Win32.System.Threading.Sleep +Windows.Win32.System.Threading.SleepConditionVariableSRW +Windows.Win32.System.Threading.SleepEx +Windows.Win32.System.Threading.STACK_SIZE_PARAM_IS_A_RESERVATION +Windows.Win32.System.Threading.STARTF_FORCEOFFFEEDBACK +Windows.Win32.System.Threading.STARTF_FORCEONFEEDBACK +Windows.Win32.System.Threading.STARTF_PREVENTPINNING +Windows.Win32.System.Threading.STARTF_RUNFULLSCREEN +Windows.Win32.System.Threading.STARTF_TITLEISAPPID +Windows.Win32.System.Threading.STARTF_TITLEISLINKNAME +Windows.Win32.System.Threading.STARTF_UNTRUSTEDSOURCE +Windows.Win32.System.Threading.STARTF_USECOUNTCHARS +Windows.Win32.System.Threading.STARTF_USEFILLATTRIBUTE +Windows.Win32.System.Threading.STARTF_USEHOTKEY +Windows.Win32.System.Threading.STARTF_USEPOSITION +Windows.Win32.System.Threading.STARTF_USESHOWWINDOW +Windows.Win32.System.Threading.STARTF_USESIZE +Windows.Win32.System.Threading.STARTF_USESTDHANDLES +Windows.Win32.System.Threading.STARTUPINFOW +Windows.Win32.System.Threading.STARTUPINFOW_FLAGS +Windows.Win32.System.Threading.SwitchToThread +Windows.Win32.System.Threading.TerminateProcess +Windows.Win32.System.Threading.THREAD_CREATE_RUN_IMMEDIATELY +Windows.Win32.System.Threading.THREAD_CREATE_SUSPENDED +Windows.Win32.System.Threading.THREAD_CREATION_FLAGS +Windows.Win32.System.Threading.TLS_OUT_OF_INDEXES +Windows.Win32.System.Threading.TlsAlloc +Windows.Win32.System.Threading.TlsFree +Windows.Win32.System.Threading.TlsGetValue +Windows.Win32.System.Threading.TlsSetValue +Windows.Win32.System.Threading.TryAcquireSRWLockExclusive +Windows.Win32.System.Threading.TryAcquireSRWLockShared +Windows.Win32.System.Threading.WaitForMultipleObjects +Windows.Win32.System.Threading.WaitForSingleObject +Windows.Win32.System.Threading.WakeAllConditionVariable +Windows.Win32.System.Threading.WakeConditionVariable +Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK +Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES +Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE +Windows.Win32.UI.Shell.GetUserProfileDirectoryW +// tidy-alphabetical-end + diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs new file mode 100644 index 00000000000..36a30f6ba56 --- /dev/null +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -0,0 +1,4276 @@ +// This file is autogenerated. +// +// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to +// regenerate the bindings. +// +// ignore-tidy-filelength +// Bindings generated by `windows-bindgen` 0.49.0 + +#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)] +#[link(name = "advapi32")] +extern "system" { + pub fn OpenProcessToken( + processhandle: HANDLE, + desiredaccess: TOKEN_ACCESS_MASK, + tokenhandle: *mut HANDLE, + ) -> BOOL; +} +#[link(name = "advapi32")] +extern "system" { + #[link_name = "SystemFunction036"] + pub fn RtlGenRandom(randombuffer: *mut ::core::ffi::c_void, randombufferlength: u32) + -> BOOLEAN; +} +#[link(name = "bcrypt")] +extern "system" { + pub fn BCryptGenRandom( + halgorithm: BCRYPT_ALG_HANDLE, + pbbuffer: *mut u8, + cbbuffer: u32, + dwflags: BCRYPTGENRANDOM_FLAGS, + ) -> NTSTATUS; +} +#[link(name = "kernel32")] +extern "system" { + pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn AddVectoredExceptionHandler( + first: u32, + handler: PVECTORED_EXCEPTION_HANDLER, + ) -> *mut ::core::ffi::c_void; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CancelIo(hfile: HANDLE) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CloseHandle(hobject: HANDLE) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CompareStringOrdinal( + lpstring1: PCWSTR, + cchcount1: i32, + lpstring2: PCWSTR, + cchcount2: i32, + bignorecase: BOOL, + ) -> COMPARESTRING_RESULT; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CopyFileExW( + lpexistingfilename: PCWSTR, + lpnewfilename: PCWSTR, + lpprogressroutine: LPPROGRESS_ROUTINE, + lpdata: *const ::core::ffi::c_void, + pbcancel: *mut i32, + dwcopyflags: u32, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateDirectoryW( + lppathname: PCWSTR, + lpsecurityattributes: *const SECURITY_ATTRIBUTES, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateEventW( + lpeventattributes: *const SECURITY_ATTRIBUTES, + bmanualreset: BOOL, + binitialstate: BOOL, + lpname: PCWSTR, + ) -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateFileW( + lpfilename: PCWSTR, + dwdesiredaccess: u32, + dwsharemode: FILE_SHARE_MODE, + lpsecurityattributes: *const SECURITY_ATTRIBUTES, + dwcreationdisposition: FILE_CREATION_DISPOSITION, + dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES, + htemplatefile: HANDLE, + ) -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateHardLinkW( + lpfilename: PCWSTR, + lpexistingfilename: PCWSTR, + lpsecurityattributes: *const SECURITY_ATTRIBUTES, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateNamedPipeW( + lpname: PCWSTR, + dwopenmode: FILE_FLAGS_AND_ATTRIBUTES, + dwpipemode: NAMED_PIPE_MODE, + nmaxinstances: u32, + noutbuffersize: u32, + ninbuffersize: u32, + ndefaulttimeout: u32, + lpsecurityattributes: *const SECURITY_ATTRIBUTES, + ) -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateProcessW( + lpapplicationname: PCWSTR, + lpcommandline: PWSTR, + lpprocessattributes: *const SECURITY_ATTRIBUTES, + lpthreadattributes: *const SECURITY_ATTRIBUTES, + binherithandles: BOOL, + dwcreationflags: PROCESS_CREATION_FLAGS, + lpenvironment: *const ::core::ffi::c_void, + lpcurrentdirectory: PCWSTR, + lpstartupinfo: *const STARTUPINFOW, + lpprocessinformation: *mut PROCESS_INFORMATION, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateSymbolicLinkW( + lpsymlinkfilename: PCWSTR, + lptargetfilename: PCWSTR, + dwflags: SYMBOLIC_LINK_FLAGS, + ) -> BOOLEAN; +} +#[link(name = "kernel32")] +extern "system" { + pub fn CreateThread( + lpthreadattributes: *const SECURITY_ATTRIBUTES, + dwstacksize: usize, + lpstartaddress: LPTHREAD_START_ROUTINE, + lpparameter: *const ::core::ffi::c_void, + dwcreationflags: THREAD_CREATION_FLAGS, + lpthreadid: *mut u32, + ) -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn DeleteFileW(lpfilename: PCWSTR) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn DeviceIoControl( + hdevice: HANDLE, + dwiocontrolcode: u32, + lpinbuffer: *const ::core::ffi::c_void, + ninbuffersize: u32, + lpoutbuffer: *mut ::core::ffi::c_void, + noutbuffersize: u32, + lpbytesreturned: *mut u32, + lpoverlapped: *mut OVERLAPPED, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn DuplicateHandle( + hsourceprocesshandle: HANDLE, + hsourcehandle: HANDLE, + htargetprocesshandle: HANDLE, + lptargethandle: *mut HANDLE, + dwdesiredaccess: u32, + binherithandle: BOOL, + dwoptions: DUPLICATE_HANDLE_OPTIONS, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn ExitProcess(uexitcode: u32) -> !; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FindClose(hfindfile: FindFileHandle) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FindFirstFileW( + lpfilename: PCWSTR, + lpfindfiledata: *mut WIN32_FIND_DATAW, + ) -> FindFileHandle; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FindNextFileW(hfindfile: FindFileHandle, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FlushFileBuffers(hfile: HANDLE) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FormatMessageW( + dwflags: FORMAT_MESSAGE_OPTIONS, + lpsource: *const ::core::ffi::c_void, + dwmessageid: u32, + dwlanguageid: u32, + lpbuffer: PWSTR, + nsize: u32, + arguments: *const *const i8, + ) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetCommandLineW() -> PCWSTR; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetConsoleMode(hconsolehandle: HANDLE, lpmode: *mut CONSOLE_MODE) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetCurrentDirectoryW(nbufferlength: u32, lpbuffer: PWSTR) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetCurrentProcess() -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetCurrentProcessId() -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetCurrentThread() -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetEnvironmentStringsW() -> PWSTR; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetEnvironmentVariableW(lpname: PCWSTR, lpbuffer: PWSTR, nsize: u32) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetExitCodeProcess(hprocess: HANDLE, lpexitcode: *mut u32) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFileAttributesW(lpfilename: PCWSTR) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFileInformationByHandle( + hfile: HANDLE, + lpfileinformation: *mut BY_HANDLE_FILE_INFORMATION, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFileInformationByHandleEx( + hfile: HANDLE, + fileinformationclass: FILE_INFO_BY_HANDLE_CLASS, + lpfileinformation: *mut ::core::ffi::c_void, + dwbuffersize: u32, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFileType(hfile: HANDLE) -> FILE_TYPE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFinalPathNameByHandleW( + hfile: HANDLE, + lpszfilepath: PWSTR, + cchfilepath: u32, + dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS, + ) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetFullPathNameW( + lpfilename: PCWSTR, + nbufferlength: u32, + lpbuffer: PWSTR, + lpfilepart: *mut PWSTR, + ) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetLastError() -> WIN32_ERROR; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetModuleFileNameW(hmodule: HMODULE, lpfilename: PWSTR, nsize: u32) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetModuleHandleW(lpmodulename: PCWSTR) -> HMODULE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetOverlappedResult( + hfile: HANDLE, + lpoverlapped: *const OVERLAPPED, + lpnumberofbytestransferred: *mut u32, + bwait: BOOL, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetProcessId(process: HANDLE) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetStdHandle(nstdhandle: STD_HANDLE) -> HANDLE; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn GetWindowsDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn InitOnceBeginInitialize( + lpinitonce: *mut RTL_RUN_ONCE, + dwflags: u32, + fpending: *mut BOOL, + lpcontext: *mut *mut ::core::ffi::c_void, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn InitOnceComplete( + lpinitonce: *mut RTL_RUN_ONCE, + dwflags: u32, + lpcontext: *const ::core::ffi::c_void, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn MoveFileExW( + lpexistingfilename: PCWSTR, + lpnewfilename: PCWSTR, + dwflags: MOVE_FILE_FLAGS, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn MultiByteToWideChar( + codepage: u32, + dwflags: MULTI_BYTE_TO_WIDE_CHAR_FLAGS, + lpmultibytestr: PCSTR, + cbmultibyte: i32, + lpwidecharstr: PWSTR, + cchwidechar: i32, + ) -> i32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn ReadConsoleW( + hconsoleinput: HANDLE, + lpbuffer: *mut ::core::ffi::c_void, + nnumberofcharstoread: u32, + lpnumberofcharsread: *mut u32, + pinputcontrol: *const CONSOLE_READCONSOLE_CONTROL, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn ReadFile( + hfile: HANDLE, + lpbuffer: *mut ::core::ffi::c_void, + nnumberofbytestoread: u32, + lpnumberofbytesread: *mut u32, + lpoverlapped: *mut OVERLAPPED, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn ReadFileEx( + hfile: HANDLE, + lpbuffer: *mut ::core::ffi::c_void, + nnumberofbytestoread: u32, + lpoverlapped: *mut OVERLAPPED, + lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetCurrentDirectoryW(lppathname: PCWSTR) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetEnvironmentVariableW(lpname: PCWSTR, lpvalue: PCWSTR) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetFileAttributesW( + lpfilename: PCWSTR, + dwfileattributes: FILE_FLAGS_AND_ATTRIBUTES, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetFileInformationByHandle( + hfile: HANDLE, + fileinformationclass: FILE_INFO_BY_HANDLE_CLASS, + lpfileinformation: *const ::core::ffi::c_void, + dwbuffersize: u32, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetFilePointerEx( + hfile: HANDLE, + lidistancetomove: i64, + lpnewfilepointer: *mut i64, + dwmovemethod: SET_FILE_POINTER_MOVE_METHOD, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetFileTime( + hfile: HANDLE, + lpcreationtime: *const FILETIME, + lplastaccesstime: *const FILETIME, + lplastwritetime: *const FILETIME, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetLastError(dwerrcode: WIN32_ERROR) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn Sleep(dwmilliseconds: u32) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn SleepConditionVariableSRW( + conditionvariable: *mut RTL_CONDITION_VARIABLE, + srwlock: *mut RTL_SRWLOCK, + dwmilliseconds: u32, + flags: u32, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn SwitchToThread() -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TerminateProcess(hprocess: HANDLE, uexitcode: u32) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TlsAlloc() -> u32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TlsFree(dwtlsindex: u32) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TlsGetValue(dwtlsindex: u32) -> *mut ::core::ffi::c_void; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const ::core::ffi::c_void) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN; +} +#[link(name = "kernel32")] +extern "system" { + pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN; +} +#[link(name = "kernel32")] +extern "system" { + pub fn WaitForMultipleObjects( + ncount: u32, + lphandles: *const HANDLE, + bwaitall: BOOL, + dwmilliseconds: u32, + ) -> WIN32_ERROR; +} +#[link(name = "kernel32")] +extern "system" { + pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR; +} +#[link(name = "kernel32")] +extern "system" { + pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> (); +} +#[link(name = "kernel32")] +extern "system" { + pub fn WideCharToMultiByte( + codepage: u32, + dwflags: u32, + lpwidecharstr: PCWSTR, + cchwidechar: i32, + lpmultibytestr: PSTR, + cbmultibyte: i32, + lpdefaultchar: PCSTR, + lpuseddefaultchar: *mut i32, + ) -> i32; +} +#[link(name = "kernel32")] +extern "system" { + pub fn WriteConsoleW( + hconsoleoutput: HANDLE, + lpbuffer: *const ::core::ffi::c_void, + nnumberofcharstowrite: u32, + lpnumberofcharswritten: *mut u32, + lpreserved: *const ::core::ffi::c_void, + ) -> BOOL; +} +#[link(name = "kernel32")] +extern "system" { + pub fn WriteFileEx( + hfile: HANDLE, + lpbuffer: *const u8, + nnumberofbytestowrite: u32, + lpoverlapped: *mut OVERLAPPED, + lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL; +} +#[link(name = "ntdll")] +extern "system" { + pub fn NtCreateFile( + filehandle: *mut HANDLE, + desiredaccess: FILE_ACCESS_RIGHTS, + objectattributes: *const OBJECT_ATTRIBUTES, + iostatusblock: *mut IO_STATUS_BLOCK, + allocationsize: *const i64, + fileattributes: FILE_FLAGS_AND_ATTRIBUTES, + shareaccess: FILE_SHARE_MODE, + createdisposition: NTCREATEFILE_CREATE_DISPOSITION, + createoptions: NTCREATEFILE_CREATE_OPTIONS, + eabuffer: *const ::core::ffi::c_void, + ealength: u32, + ) -> NTSTATUS; +} +#[link(name = "ntdll")] +extern "system" { + pub fn NtReadFile( + filehandle: HANDLE, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *const ::core::ffi::c_void, + iostatusblock: *mut IO_STATUS_BLOCK, + buffer: *mut ::core::ffi::c_void, + length: u32, + byteoffset: *const i64, + key: *const u32, + ) -> NTSTATUS; +} +#[link(name = "ntdll")] +extern "system" { + pub fn NtWriteFile( + filehandle: HANDLE, + event: HANDLE, + apcroutine: PIO_APC_ROUTINE, + apccontext: *const ::core::ffi::c_void, + iostatusblock: *mut IO_STATUS_BLOCK, + buffer: *const ::core::ffi::c_void, + length: u32, + byteoffset: *const i64, + key: *const u32, + ) -> NTSTATUS; +} +#[link(name = "ntdll")] +extern "system" { + pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32; +} +#[link(name = "userenv")] +extern "system" { + pub fn GetUserProfileDirectoryW( + htoken: HANDLE, + lpprofiledir: PWSTR, + lpcchsize: *mut u32, + ) -> BOOL; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSACleanup() -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSADuplicateSocketW( + s: SOCKET, + dwprocessid: u32, + lpprotocolinfo: *mut WSAPROTOCOL_INFOW, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSAGetLastError() -> WSA_ERROR; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSARecv( + s: SOCKET, + lpbuffers: *const WSABUF, + dwbuffercount: u32, + lpnumberofbytesrecvd: *mut u32, + lpflags: *mut u32, + lpoverlapped: *mut OVERLAPPED, + lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSASend( + s: SOCKET, + lpbuffers: *const WSABUF, + dwbuffercount: u32, + lpnumberofbytessent: *mut u32, + dwflags: u32, + lpoverlapped: *mut OVERLAPPED, + lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSASocketW( + af: i32, + r#type: i32, + protocol: i32, + lpprotocolinfo: *const WSAPROTOCOL_INFOW, + g: u32, + dwflags: u32, + ) -> SOCKET; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut i32) -> SOCKET; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn closesocket(s: SOCKET) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA) -> (); +} +#[link(name = "ws2_32")] +extern "system" { + pub fn getaddrinfo( + pnodename: PCSTR, + pservicename: PCSTR, + phints: *const ADDRINFOA, + ppresult: *mut *mut ADDRINFOA, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn getsockopt(s: SOCKET, level: i32, optname: i32, optval: PSTR, optlen: *mut i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn ioctlsocket(s: SOCKET, cmd: i32, argp: *mut u32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn listen(s: SOCKET, backlog: i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn recv(s: SOCKET, buf: PSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn recvfrom( + s: SOCKET, + buf: PSTR, + len: i32, + flags: i32, + from: *mut SOCKADDR, + fromlen: *mut i32, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn select( + nfds: i32, + readfds: *mut FD_SET, + writefds: *mut FD_SET, + exceptfds: *mut FD_SET, + timeout: *const TIMEVAL, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn send(s: SOCKET, buf: PCSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn sendto( + s: SOCKET, + buf: PCSTR, + len: i32, + flags: i32, + to: *const SOCKADDR, + tolen: i32, + ) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn setsockopt(s: SOCKET, level: i32, optname: i32, optval: PCSTR, optlen: i32) -> i32; +} +#[link(name = "ws2_32")] +extern "system" { + pub fn shutdown(s: SOCKET, how: WINSOCK_SHUTDOWN_HOW) -> i32; +} +pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32; +pub type ADDRESS_FAMILY = u16; +#[repr(C)] +pub struct ADDRINFOA { + pub ai_flags: i32, + pub ai_family: i32, + pub ai_socktype: i32, + pub ai_protocol: i32, + pub ai_addrlen: usize, + pub ai_canonname: PSTR, + pub ai_addr: *mut SOCKADDR, + pub ai_next: *mut ADDRINFOA, +} +impl ::core::marker::Copy for ADDRINFOA {} +impl ::core::clone::Clone for ADDRINFOA { + fn clone(&self) -> Self { + *self + } +} +pub const AF_INET: ADDRESS_FAMILY = 2u16; +pub const AF_INET6: ADDRESS_FAMILY = 23u16; +pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16; +#[repr(C)] +pub union ARM64_NT_NEON128 { + pub Anonymous: ARM64_NT_NEON128_0, + pub D: [f64; 2], + pub S: [f32; 4], + pub H: [u16; 8], + pub B: [u8; 16], +} +impl ::core::marker::Copy for ARM64_NT_NEON128 {} +impl ::core::clone::Clone for ARM64_NT_NEON128 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct ARM64_NT_NEON128_0 { + pub Low: u64, + pub High: i64, +} +impl ::core::marker::Copy for ARM64_NT_NEON128_0 {} +impl ::core::clone::Clone for ARM64_NT_NEON128_0 { + fn clone(&self) -> Self { + *self + } +} +pub type BCRYPTGENRANDOM_FLAGS = u32; +pub type BCRYPT_ALG_HANDLE = *mut ::core::ffi::c_void; +pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: BCRYPTGENRANDOM_FLAGS = 2u32; +pub const BELOW_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 16384u32; +pub type BOOL = i32; +pub type BOOLEAN = u8; +#[repr(C)] +pub struct BY_HANDLE_FILE_INFORMATION { + pub dwFileAttributes: u32, + pub ftCreationTime: FILETIME, + pub ftLastAccessTime: FILETIME, + pub ftLastWriteTime: FILETIME, + pub dwVolumeSerialNumber: u32, + pub nFileSizeHigh: u32, + pub nFileSizeLow: u32, + pub nNumberOfLinks: u32, + pub nFileIndexHigh: u32, + pub nFileIndexLow: u32, +} +impl ::core::marker::Copy for BY_HANDLE_FILE_INFORMATION {} +impl ::core::clone::Clone for BY_HANDLE_FILE_INFORMATION { + fn clone(&self) -> Self { + *self + } +} +pub const CALLBACK_CHUNK_FINISHED: LPPROGRESS_ROUTINE_CALLBACK_REASON = 0u32; +pub const CALLBACK_STREAM_SWITCH: LPPROGRESS_ROUTINE_CALLBACK_REASON = 1u32; +pub type COMPARESTRING_RESULT = u32; +pub type CONSOLE_MODE = u32; +#[repr(C)] +pub struct CONSOLE_READCONSOLE_CONTROL { + pub nLength: u32, + pub nInitialChars: u32, + pub dwCtrlWakeupMask: u32, + pub dwControlKeyState: u32, +} +impl ::core::marker::Copy for CONSOLE_READCONSOLE_CONTROL {} +impl ::core::clone::Clone for CONSOLE_READCONSOLE_CONTROL { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "aarch64")] +pub struct CONTEXT { + pub ContextFlags: u32, + pub Cpsr: u32, + pub Anonymous: CONTEXT_0, + pub Sp: u64, + pub Pc: u64, + pub V: [ARM64_NT_NEON128; 32], + pub Fpcr: u32, + pub Fpsr: u32, + pub Bcr: [u32; 8], + pub Bvr: [u64; 8], + pub Wcr: [u32; 2], + pub Wvr: [u64; 2], +} +#[cfg(target_arch = "aarch64")] +impl ::core::marker::Copy for CONTEXT {} +#[cfg(target_arch = "aarch64")] +impl ::core::clone::Clone for CONTEXT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "aarch64")] +pub union CONTEXT_0 { + pub Anonymous: CONTEXT_0_0, + pub X: [u64; 31], +} +#[cfg(target_arch = "aarch64")] +impl ::core::marker::Copy for CONTEXT_0 {} +#[cfg(target_arch = "aarch64")] +impl ::core::clone::Clone for CONTEXT_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "aarch64")] +pub struct CONTEXT_0_0 { + pub X0: u64, + pub X1: u64, + pub X2: u64, + pub X3: u64, + pub X4: u64, + pub X5: u64, + pub X6: u64, + pub X7: u64, + pub X8: u64, + pub X9: u64, + pub X10: u64, + pub X11: u64, + pub X12: u64, + pub X13: u64, + pub X14: u64, + pub X15: u64, + pub X16: u64, + pub X17: u64, + pub X18: u64, + pub X19: u64, + pub X20: u64, + pub X21: u64, + pub X22: u64, + pub X23: u64, + pub X24: u64, + pub X25: u64, + pub X26: u64, + pub X27: u64, + pub X28: u64, + pub Fp: u64, + pub Lr: u64, +} +#[cfg(target_arch = "aarch64")] +impl ::core::marker::Copy for CONTEXT_0_0 {} +#[cfg(target_arch = "aarch64")] +impl ::core::clone::Clone for CONTEXT_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86_64")] +pub struct CONTEXT { + pub P1Home: u64, + pub P2Home: u64, + pub P3Home: u64, + pub P4Home: u64, + pub P5Home: u64, + pub P6Home: u64, + pub ContextFlags: u32, + pub MxCsr: u32, + pub SegCs: u16, + pub SegDs: u16, + pub SegEs: u16, + pub SegFs: u16, + pub SegGs: u16, + pub SegSs: u16, + pub EFlags: u32, + pub Dr0: u64, + pub Dr1: u64, + pub Dr2: u64, + pub Dr3: u64, + pub Dr6: u64, + pub Dr7: u64, + pub Rax: u64, + pub Rcx: u64, + pub Rdx: u64, + pub Rbx: u64, + pub Rsp: u64, + pub Rbp: u64, + pub Rsi: u64, + pub Rdi: u64, + pub R8: u64, + pub R9: u64, + pub R10: u64, + pub R11: u64, + pub R12: u64, + pub R13: u64, + pub R14: u64, + pub R15: u64, + pub Rip: u64, + pub Anonymous: CONTEXT_0, + pub VectorRegister: [M128A; 26], + pub VectorControl: u64, + pub DebugControl: u64, + pub LastBranchToRip: u64, + pub LastBranchFromRip: u64, + pub LastExceptionToRip: u64, + pub LastExceptionFromRip: u64, +} +#[cfg(target_arch = "x86_64")] +impl ::core::marker::Copy for CONTEXT {} +#[cfg(target_arch = "x86_64")] +impl ::core::clone::Clone for CONTEXT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86_64")] +pub union CONTEXT_0 { + pub FltSave: XSAVE_FORMAT, + pub Anonymous: CONTEXT_0_0, +} +#[cfg(target_arch = "x86_64")] +impl ::core::marker::Copy for CONTEXT_0 {} +#[cfg(target_arch = "x86_64")] +impl ::core::clone::Clone for CONTEXT_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86_64")] +pub struct CONTEXT_0_0 { + pub Header: [M128A; 2], + pub Legacy: [M128A; 8], + pub Xmm0: M128A, + pub Xmm1: M128A, + pub Xmm2: M128A, + pub Xmm3: M128A, + pub Xmm4: M128A, + pub Xmm5: M128A, + pub Xmm6: M128A, + pub Xmm7: M128A, + pub Xmm8: M128A, + pub Xmm9: M128A, + pub Xmm10: M128A, + pub Xmm11: M128A, + pub Xmm12: M128A, + pub Xmm13: M128A, + pub Xmm14: M128A, + pub Xmm15: M128A, +} +#[cfg(target_arch = "x86_64")] +impl ::core::marker::Copy for CONTEXT_0_0 {} +#[cfg(target_arch = "x86_64")] +impl ::core::clone::Clone for CONTEXT_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86")] +pub struct CONTEXT { + pub ContextFlags: u32, + pub Dr0: u32, + pub Dr1: u32, + pub Dr2: u32, + pub Dr3: u32, + pub Dr6: u32, + pub Dr7: u32, + pub FloatSave: FLOATING_SAVE_AREA, + pub SegGs: u32, + pub SegFs: u32, + pub SegEs: u32, + pub SegDs: u32, + pub Edi: u32, + pub Esi: u32, + pub Ebx: u32, + pub Edx: u32, + pub Ecx: u32, + pub Eax: u32, + pub Ebp: u32, + pub Eip: u32, + pub SegCs: u32, + pub EFlags: u32, + pub Esp: u32, + pub SegSs: u32, + pub ExtendedRegisters: [u8; 512], +} +#[cfg(target_arch = "x86")] +impl ::core::marker::Copy for CONTEXT {} +#[cfg(target_arch = "x86")] +impl ::core::clone::Clone for CONTEXT { + fn clone(&self) -> Self { + *self + } +} +pub const CP_UTF8: u32 = 65001u32; +pub const CREATE_ALWAYS: FILE_CREATION_DISPOSITION = 2u32; +pub const CREATE_BREAKAWAY_FROM_JOB: PROCESS_CREATION_FLAGS = 16777216u32; +pub const CREATE_DEFAULT_ERROR_MODE: PROCESS_CREATION_FLAGS = 67108864u32; +pub const CREATE_FORCEDOS: PROCESS_CREATION_FLAGS = 8192u32; +pub const CREATE_IGNORE_SYSTEM_DEFAULT: PROCESS_CREATION_FLAGS = 2147483648u32; +pub const CREATE_NEW: FILE_CREATION_DISPOSITION = 1u32; +pub const CREATE_NEW_CONSOLE: PROCESS_CREATION_FLAGS = 16u32; +pub const CREATE_NEW_PROCESS_GROUP: PROCESS_CREATION_FLAGS = 512u32; +pub const CREATE_NO_WINDOW: PROCESS_CREATION_FLAGS = 134217728u32; +pub const CREATE_PRESERVE_CODE_AUTHZ_LEVEL: PROCESS_CREATION_FLAGS = 33554432u32; +pub const CREATE_PROTECTED_PROCESS: PROCESS_CREATION_FLAGS = 262144u32; +pub const CREATE_SECURE_PROCESS: PROCESS_CREATION_FLAGS = 4194304u32; +pub const CREATE_SEPARATE_WOW_VDM: PROCESS_CREATION_FLAGS = 2048u32; +pub const CREATE_SHARED_WOW_VDM: PROCESS_CREATION_FLAGS = 4096u32; +pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32; +pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32; +pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2u32; +pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3u32; +pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1u32; +pub const DEBUG_ONLY_THIS_PROCESS: PROCESS_CREATION_FLAGS = 2u32; +pub const DEBUG_PROCESS: PROCESS_CREATION_FLAGS = 1u32; +pub const DELETE: FILE_ACCESS_RIGHTS = 65536u32; +pub const DETACHED_PROCESS: PROCESS_CREATION_FLAGS = 8u32; +pub const DISABLE_NEWLINE_AUTO_RETURN: CONSOLE_MODE = 8u32; +pub const DLL_PROCESS_DETACH: u32 = 0u32; +pub const DLL_THREAD_DETACH: u32 = 3u32; +pub const DNS_ERROR_ADDRESS_REQUIRED: WIN32_ERROR = 9573u32; +pub const DNS_ERROR_ALIAS_LOOP: WIN32_ERROR = 9722u32; +pub const DNS_ERROR_AUTOZONE_ALREADY_EXISTS: WIN32_ERROR = 9610u32; +pub const DNS_ERROR_AXFR: WIN32_ERROR = 9752u32; +pub const DNS_ERROR_BACKGROUND_LOADING: WIN32_ERROR = 9568u32; +pub const DNS_ERROR_BAD_KEYMASTER: WIN32_ERROR = 9122u32; +pub const DNS_ERROR_BAD_PACKET: WIN32_ERROR = 9502u32; +pub const DNS_ERROR_CANNOT_FIND_ROOT_HINTS: WIN32_ERROR = 9564u32; +pub const DNS_ERROR_CLIENT_SUBNET_ALREADY_EXISTS: WIN32_ERROR = 9977u32; +pub const DNS_ERROR_CLIENT_SUBNET_DOES_NOT_EXIST: WIN32_ERROR = 9976u32; +pub const DNS_ERROR_CLIENT_SUBNET_IS_ACCESSED: WIN32_ERROR = 9975u32; +pub const DNS_ERROR_CNAME_COLLISION: WIN32_ERROR = 9709u32; +pub const DNS_ERROR_CNAME_LOOP: WIN32_ERROR = 9707u32; +pub const DNS_ERROR_DATAFILE_OPEN_FAILURE: WIN32_ERROR = 9653u32; +pub const DNS_ERROR_DATAFILE_PARSING: WIN32_ERROR = 9655u32; +pub const DNS_ERROR_DEFAULT_SCOPE: WIN32_ERROR = 9960u32; +pub const DNS_ERROR_DEFAULT_VIRTUALIZATION_INSTANCE: WIN32_ERROR = 9925u32; +pub const DNS_ERROR_DEFAULT_ZONESCOPE: WIN32_ERROR = 9953u32; +pub const DNS_ERROR_DELEGATION_REQUIRED: WIN32_ERROR = 9571u32; +pub const DNS_ERROR_DNAME_COLLISION: WIN32_ERROR = 9721u32; +pub const DNS_ERROR_DNSSEC_IS_DISABLED: WIN32_ERROR = 9125u32; +pub const DNS_ERROR_DP_ALREADY_ENLISTED: WIN32_ERROR = 9904u32; +pub const DNS_ERROR_DP_ALREADY_EXISTS: WIN32_ERROR = 9902u32; +pub const DNS_ERROR_DP_DOES_NOT_EXIST: WIN32_ERROR = 9901u32; +pub const DNS_ERROR_DP_FSMO_ERROR: WIN32_ERROR = 9906u32; +pub const DNS_ERROR_DP_NOT_AVAILABLE: WIN32_ERROR = 9905u32; +pub const DNS_ERROR_DP_NOT_ENLISTED: WIN32_ERROR = 9903u32; +pub const DNS_ERROR_DS_UNAVAILABLE: WIN32_ERROR = 9717u32; +pub const DNS_ERROR_DS_ZONE_ALREADY_EXISTS: WIN32_ERROR = 9718u32; +pub const DNS_ERROR_DWORD_VALUE_TOO_LARGE: WIN32_ERROR = 9567u32; +pub const DNS_ERROR_DWORD_VALUE_TOO_SMALL: WIN32_ERROR = 9566u32; +pub const DNS_ERROR_FILE_WRITEBACK_FAILED: WIN32_ERROR = 9654u32; +pub const DNS_ERROR_FORWARDER_ALREADY_EXISTS: WIN32_ERROR = 9619u32; +pub const DNS_ERROR_INCONSISTENT_ROOT_HINTS: WIN32_ERROR = 9565u32; +pub const DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME: WIN32_ERROR = 9924u32; +pub const DNS_ERROR_INVALID_CLIENT_SUBNET_NAME: WIN32_ERROR = 9984u32; +pub const DNS_ERROR_INVALID_DATA: WIN32_ERROR = 13u32; +pub const DNS_ERROR_INVALID_DATAFILE_NAME: WIN32_ERROR = 9652u32; +pub const DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET: WIN32_ERROR = 9115u32; +pub const DNS_ERROR_INVALID_IP_ADDRESS: WIN32_ERROR = 9552u32; +pub const DNS_ERROR_INVALID_KEY_SIZE: WIN32_ERROR = 9106u32; +pub const DNS_ERROR_INVALID_NAME: WIN32_ERROR = 123u32; +pub const DNS_ERROR_INVALID_NAME_CHAR: WIN32_ERROR = 9560u32; +pub const DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT: WIN32_ERROR = 9124u32; +pub const DNS_ERROR_INVALID_POLICY_TABLE: WIN32_ERROR = 9572u32; +pub const DNS_ERROR_INVALID_PROPERTY: WIN32_ERROR = 9553u32; +pub const DNS_ERROR_INVALID_ROLLOVER_PERIOD: WIN32_ERROR = 9114u32; +pub const DNS_ERROR_INVALID_SCOPE_NAME: WIN32_ERROR = 9958u32; +pub const DNS_ERROR_INVALID_SCOPE_OPERATION: WIN32_ERROR = 9961u32; +pub const DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD: WIN32_ERROR = 9123u32; +pub const DNS_ERROR_INVALID_TYPE: WIN32_ERROR = 9551u32; +pub const DNS_ERROR_INVALID_XML: WIN32_ERROR = 9126u32; +pub const DNS_ERROR_INVALID_ZONESCOPE_NAME: WIN32_ERROR = 9954u32; +pub const DNS_ERROR_INVALID_ZONE_OPERATION: WIN32_ERROR = 9603u32; +pub const DNS_ERROR_INVALID_ZONE_TYPE: WIN32_ERROR = 9611u32; +pub const DNS_ERROR_KEYMASTER_REQUIRED: WIN32_ERROR = 9101u32; +pub const DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION: WIN32_ERROR = 9108u32; +pub const DNS_ERROR_KSP_NOT_ACCESSIBLE: WIN32_ERROR = 9112u32; +pub const DNS_ERROR_LOAD_ZONESCOPE_FAILED: WIN32_ERROR = 9956u32; +pub const DNS_ERROR_NAME_DOES_NOT_EXIST: WIN32_ERROR = 9714u32; +pub const DNS_ERROR_NAME_NOT_IN_ZONE: WIN32_ERROR = 9706u32; +pub const DNS_ERROR_NBSTAT_INIT_FAILED: WIN32_ERROR = 9617u32; +pub const DNS_ERROR_NEED_SECONDARY_ADDRESSES: WIN32_ERROR = 9614u32; +pub const DNS_ERROR_NEED_WINS_SERVERS: WIN32_ERROR = 9616u32; +pub const DNS_ERROR_NODE_CREATION_FAILED: WIN32_ERROR = 9703u32; +pub const DNS_ERROR_NODE_IS_CNAME: WIN32_ERROR = 9708u32; +pub const DNS_ERROR_NODE_IS_DNAME: WIN32_ERROR = 9720u32; +pub const DNS_ERROR_NON_RFC_NAME: WIN32_ERROR = 9556u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD: WIN32_ERROR = 9119u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_RODC: WIN32_ERROR = 9569u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER: WIN32_ERROR = 9562u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE: WIN32_ERROR = 9102u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE: WIN32_ERROR = 9121u32; +pub const DNS_ERROR_NOT_ALLOWED_ON_ZSK: WIN32_ERROR = 9118u32; +pub const DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION: WIN32_ERROR = 9563u32; +pub const DNS_ERROR_NOT_ALLOWED_UNDER_DNAME: WIN32_ERROR = 9570u32; +pub const DNS_ERROR_NOT_ALLOWED_WITH_ZONESCOPES: WIN32_ERROR = 9955u32; +pub const DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS: WIN32_ERROR = 9104u32; +pub const DNS_ERROR_NOT_UNIQUE: WIN32_ERROR = 9555u32; +pub const DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE: WIN32_ERROR = 9719u32; +pub const DNS_ERROR_NO_CREATE_CACHE_DATA: WIN32_ERROR = 9713u32; +pub const DNS_ERROR_NO_DNS_SERVERS: WIN32_ERROR = 9852u32; +pub const DNS_ERROR_NO_MEMORY: WIN32_ERROR = 14u32; +pub const DNS_ERROR_NO_PACKET: WIN32_ERROR = 9503u32; +pub const DNS_ERROR_NO_TCPIP: WIN32_ERROR = 9851u32; +pub const DNS_ERROR_NO_VALID_TRUST_ANCHORS: WIN32_ERROR = 9127u32; +pub const DNS_ERROR_NO_ZONE_INFO: WIN32_ERROR = 9602u32; +pub const DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1: WIN32_ERROR = 9103u32; +pub const DNS_ERROR_NSEC3_NAME_COLLISION: WIN32_ERROR = 9129u32; +pub const DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1: WIN32_ERROR = 9130u32; +pub const DNS_ERROR_NUMERIC_NAME: WIN32_ERROR = 9561u32; +pub const DNS_ERROR_POLICY_ALREADY_EXISTS: WIN32_ERROR = 9971u32; +pub const DNS_ERROR_POLICY_DOES_NOT_EXIST: WIN32_ERROR = 9972u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA: WIN32_ERROR = 9973u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_CLIENT_SUBNET: WIN32_ERROR = 9990u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_FQDN: WIN32_ERROR = 9994u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_INTERFACE: WIN32_ERROR = 9993u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_NETWORK_PROTOCOL: WIN32_ERROR = 9992u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_QUERY_TYPE: WIN32_ERROR = 9995u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_TIME_OF_DAY: WIN32_ERROR = 9996u32; +pub const DNS_ERROR_POLICY_INVALID_CRITERIA_TRANSPORT_PROTOCOL: WIN32_ERROR = 9991u32; +pub const DNS_ERROR_POLICY_INVALID_NAME: WIN32_ERROR = 9982u32; +pub const DNS_ERROR_POLICY_INVALID_SETTINGS: WIN32_ERROR = 9974u32; +pub const DNS_ERROR_POLICY_INVALID_WEIGHT: WIN32_ERROR = 9981u32; +pub const DNS_ERROR_POLICY_LOCKED: WIN32_ERROR = 9980u32; +pub const DNS_ERROR_POLICY_MISSING_CRITERIA: WIN32_ERROR = 9983u32; +pub const DNS_ERROR_POLICY_PROCESSING_ORDER_INVALID: WIN32_ERROR = 9985u32; +pub const DNS_ERROR_POLICY_SCOPE_MISSING: WIN32_ERROR = 9986u32; +pub const DNS_ERROR_POLICY_SCOPE_NOT_ALLOWED: WIN32_ERROR = 9987u32; +pub const DNS_ERROR_PRIMARY_REQUIRES_DATAFILE: WIN32_ERROR = 9651u32; +pub const DNS_ERROR_RCODE: WIN32_ERROR = 9504u32; +pub const DNS_ERROR_RCODE_BADKEY: WIN32_ERROR = 9017u32; +pub const DNS_ERROR_RCODE_BADSIG: WIN32_ERROR = 9016u32; +pub const DNS_ERROR_RCODE_BADTIME: WIN32_ERROR = 9018u32; +pub const DNS_ERROR_RCODE_FORMAT_ERROR: WIN32_ERROR = 9001u32; +pub const DNS_ERROR_RCODE_NAME_ERROR: WIN32_ERROR = 9003u32; +pub const DNS_ERROR_RCODE_NOTAUTH: WIN32_ERROR = 9009u32; +pub const DNS_ERROR_RCODE_NOTZONE: WIN32_ERROR = 9010u32; +pub const DNS_ERROR_RCODE_NOT_IMPLEMENTED: WIN32_ERROR = 9004u32; +pub const DNS_ERROR_RCODE_NXRRSET: WIN32_ERROR = 9008u32; +pub const DNS_ERROR_RCODE_REFUSED: WIN32_ERROR = 9005u32; +pub const DNS_ERROR_RCODE_SERVER_FAILURE: WIN32_ERROR = 9002u32; +pub const DNS_ERROR_RCODE_YXDOMAIN: WIN32_ERROR = 9006u32; +pub const DNS_ERROR_RCODE_YXRRSET: WIN32_ERROR = 9007u32; +pub const DNS_ERROR_RECORD_ALREADY_EXISTS: WIN32_ERROR = 9711u32; +pub const DNS_ERROR_RECORD_DOES_NOT_EXIST: WIN32_ERROR = 9701u32; +pub const DNS_ERROR_RECORD_FORMAT: WIN32_ERROR = 9702u32; +pub const DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT: WIN32_ERROR = 9710u32; +pub const DNS_ERROR_RECORD_TIMED_OUT: WIN32_ERROR = 9705u32; +pub const DNS_ERROR_ROLLOVER_ALREADY_QUEUED: WIN32_ERROR = 9120u32; +pub const DNS_ERROR_ROLLOVER_IN_PROGRESS: WIN32_ERROR = 9116u32; +pub const DNS_ERROR_ROLLOVER_NOT_POKEABLE: WIN32_ERROR = 9128u32; +pub const DNS_ERROR_RRL_INVALID_IPV4_PREFIX: WIN32_ERROR = 9913u32; +pub const DNS_ERROR_RRL_INVALID_IPV6_PREFIX: WIN32_ERROR = 9914u32; +pub const DNS_ERROR_RRL_INVALID_LEAK_RATE: WIN32_ERROR = 9916u32; +pub const DNS_ERROR_RRL_INVALID_TC_RATE: WIN32_ERROR = 9915u32; +pub const DNS_ERROR_RRL_INVALID_WINDOW_SIZE: WIN32_ERROR = 9912u32; +pub const DNS_ERROR_RRL_LEAK_RATE_LESSTHAN_TC_RATE: WIN32_ERROR = 9917u32; +pub const DNS_ERROR_RRL_NOT_ENABLED: WIN32_ERROR = 9911u32; +pub const DNS_ERROR_SCOPE_ALREADY_EXISTS: WIN32_ERROR = 9963u32; +pub const DNS_ERROR_SCOPE_DOES_NOT_EXIST: WIN32_ERROR = 9959u32; +pub const DNS_ERROR_SCOPE_LOCKED: WIN32_ERROR = 9962u32; +pub const DNS_ERROR_SECONDARY_DATA: WIN32_ERROR = 9712u32; +pub const DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP: WIN32_ERROR = 9612u32; +pub const DNS_ERROR_SERVERSCOPE_IS_REFERENCED: WIN32_ERROR = 9988u32; +pub const DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE: WIN32_ERROR = 9107u32; +pub const DNS_ERROR_SOA_DELETE_INVALID: WIN32_ERROR = 9618u32; +pub const DNS_ERROR_STANDBY_KEY_NOT_PRESENT: WIN32_ERROR = 9117u32; +pub const DNS_ERROR_SUBNET_ALREADY_EXISTS: WIN32_ERROR = 9979u32; +pub const DNS_ERROR_SUBNET_DOES_NOT_EXIST: WIN32_ERROR = 9978u32; +pub const DNS_ERROR_TOO_MANY_SKDS: WIN32_ERROR = 9113u32; +pub const DNS_ERROR_TRY_AGAIN_LATER: WIN32_ERROR = 9554u32; +pub const DNS_ERROR_UNEXPECTED_CNG_ERROR: WIN32_ERROR = 9110u32; +pub const DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR: WIN32_ERROR = 9109u32; +pub const DNS_ERROR_UNKNOWN_RECORD_TYPE: WIN32_ERROR = 9704u32; +pub const DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION: WIN32_ERROR = 9111u32; +pub const DNS_ERROR_UNSECURE_PACKET: WIN32_ERROR = 9505u32; +pub const DNS_ERROR_UNSUPPORTED_ALGORITHM: WIN32_ERROR = 9105u32; +pub const DNS_ERROR_VIRTUALIZATION_INSTANCE_ALREADY_EXISTS: WIN32_ERROR = 9921u32; +pub const DNS_ERROR_VIRTUALIZATION_INSTANCE_DOES_NOT_EXIST: WIN32_ERROR = 9922u32; +pub const DNS_ERROR_VIRTUALIZATION_TREE_LOCKED: WIN32_ERROR = 9923u32; +pub const DNS_ERROR_WINS_INIT_FAILED: WIN32_ERROR = 9615u32; +pub const DNS_ERROR_ZONESCOPE_ALREADY_EXISTS: WIN32_ERROR = 9951u32; +pub const DNS_ERROR_ZONESCOPE_DOES_NOT_EXIST: WIN32_ERROR = 9952u32; +pub const DNS_ERROR_ZONESCOPE_FILE_WRITEBACK_FAILED: WIN32_ERROR = 9957u32; +pub const DNS_ERROR_ZONESCOPE_IS_REFERENCED: WIN32_ERROR = 9989u32; +pub const DNS_ERROR_ZONE_ALREADY_EXISTS: WIN32_ERROR = 9609u32; +pub const DNS_ERROR_ZONE_CONFIGURATION_ERROR: WIN32_ERROR = 9604u32; +pub const DNS_ERROR_ZONE_CREATION_FAILED: WIN32_ERROR = 9608u32; +pub const DNS_ERROR_ZONE_DOES_NOT_EXIST: WIN32_ERROR = 9601u32; +pub const DNS_ERROR_ZONE_HAS_NO_NS_RECORDS: WIN32_ERROR = 9606u32; +pub const DNS_ERROR_ZONE_HAS_NO_SOA_RECORD: WIN32_ERROR = 9605u32; +pub const DNS_ERROR_ZONE_IS_SHUTDOWN: WIN32_ERROR = 9621u32; +pub const DNS_ERROR_ZONE_LOCKED: WIN32_ERROR = 9607u32; +pub const DNS_ERROR_ZONE_LOCKED_FOR_SIGNING: WIN32_ERROR = 9622u32; +pub const DNS_ERROR_ZONE_NOT_SECONDARY: WIN32_ERROR = 9613u32; +pub const DNS_ERROR_ZONE_REQUIRES_MASTER_IP: WIN32_ERROR = 9620u32; +pub const DUPLICATE_CLOSE_SOURCE: DUPLICATE_HANDLE_OPTIONS = 1u32; +pub type DUPLICATE_HANDLE_OPTIONS = u32; +pub const DUPLICATE_SAME_ACCESS: DUPLICATE_HANDLE_OPTIONS = 2u32; +pub const ENABLE_AUTO_POSITION: CONSOLE_MODE = 256u32; +pub const ENABLE_ECHO_INPUT: CONSOLE_MODE = 4u32; +pub const ENABLE_EXTENDED_FLAGS: CONSOLE_MODE = 128u32; +pub const ENABLE_INSERT_MODE: CONSOLE_MODE = 32u32; +pub const ENABLE_LINE_INPUT: CONSOLE_MODE = 2u32; +pub const ENABLE_LVB_GRID_WORLDWIDE: CONSOLE_MODE = 16u32; +pub const ENABLE_MOUSE_INPUT: CONSOLE_MODE = 16u32; +pub const ENABLE_PROCESSED_INPUT: CONSOLE_MODE = 1u32; +pub const ENABLE_PROCESSED_OUTPUT: CONSOLE_MODE = 1u32; +pub const ENABLE_QUICK_EDIT_MODE: CONSOLE_MODE = 64u32; +pub const ENABLE_VIRTUAL_TERMINAL_INPUT: CONSOLE_MODE = 512u32; +pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING: CONSOLE_MODE = 4u32; +pub const ENABLE_WINDOW_INPUT: CONSOLE_MODE = 8u32; +pub const ENABLE_WRAP_AT_EOL_OUTPUT: CONSOLE_MODE = 2u32; +pub const ERROR_ABANDONED_WAIT_0: WIN32_ERROR = 735u32; +pub const ERROR_ABANDONED_WAIT_63: WIN32_ERROR = 736u32; +pub const ERROR_ABANDON_HIBERFILE: WIN32_ERROR = 787u32; +pub const ERROR_ABIOS_ERROR: WIN32_ERROR = 538u32; +pub const ERROR_ACCESS_AUDIT_BY_POLICY: WIN32_ERROR = 785u32; +pub const ERROR_ACCESS_DENIED: WIN32_ERROR = 5u32; +pub const ERROR_ACCESS_DENIED_APPDATA: WIN32_ERROR = 502u32; +pub const ERROR_ACCESS_DISABLED_BY_POLICY: WIN32_ERROR = 1260u32; +pub const ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY: WIN32_ERROR = 786u32; +pub const ERROR_ACCESS_DISABLED_WEBBLADE: WIN32_ERROR = 1277u32; +pub const ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER: WIN32_ERROR = 1278u32; +pub const ERROR_ACCOUNT_DISABLED: WIN32_ERROR = 1331u32; +pub const ERROR_ACCOUNT_EXPIRED: WIN32_ERROR = 1793u32; +pub const ERROR_ACCOUNT_LOCKED_OUT: WIN32_ERROR = 1909u32; +pub const ERROR_ACCOUNT_RESTRICTION: WIN32_ERROR = 1327u32; +pub const ERROR_ACPI_ERROR: WIN32_ERROR = 669u32; +pub const ERROR_ACTIVE_CONNECTIONS: WIN32_ERROR = 2402u32; +pub const ERROR_ADAP_HDW_ERR: WIN32_ERROR = 57u32; +pub const ERROR_ADDRESS_ALREADY_ASSOCIATED: WIN32_ERROR = 1227u32; +pub const ERROR_ADDRESS_NOT_ASSOCIATED: WIN32_ERROR = 1228u32; +pub const ERROR_ALERTED: WIN32_ERROR = 739u32; +pub const ERROR_ALIAS_EXISTS: WIN32_ERROR = 1379u32; +pub const ERROR_ALLOCATE_BUCKET: WIN32_ERROR = 602u32; +pub const ERROR_ALLOTTED_SPACE_EXCEEDED: WIN32_ERROR = 1344u32; +pub const ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1933u32; +pub const ERROR_ALREADY_ASSIGNED: WIN32_ERROR = 85u32; +pub const ERROR_ALREADY_EXISTS: WIN32_ERROR = 183u32; +pub const ERROR_ALREADY_FIBER: WIN32_ERROR = 1280u32; +pub const ERROR_ALREADY_HAS_STREAM_ID: WIN32_ERROR = 4444u32; +pub const ERROR_ALREADY_INITIALIZED: WIN32_ERROR = 1247u32; +pub const ERROR_ALREADY_REGISTERED: WIN32_ERROR = 1242u32; +pub const ERROR_ALREADY_RUNNING_LKG: WIN32_ERROR = 1074u32; +pub const ERROR_ALREADY_THREAD: WIN32_ERROR = 1281u32; +pub const ERROR_ALREADY_WAITING: WIN32_ERROR = 1904u32; +pub const ERROR_ALREADY_WIN32: WIN32_ERROR = 719u32; +pub const ERROR_API_UNAVAILABLE: WIN32_ERROR = 15841u32; +pub const ERROR_APPCONTAINER_REQUIRED: WIN32_ERROR = 4251u32; +pub const ERROR_APPEXEC_APP_COMPAT_BLOCK: WIN32_ERROR = 3068u32; +pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT: WIN32_ERROR = 3069u32; +pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_LICENSING: WIN32_ERROR = 3071u32; +pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_RESOURCES: WIN32_ERROR = 3072u32; +pub const ERROR_APPEXEC_CALLER_WAIT_TIMEOUT_TERMINATION: WIN32_ERROR = 3070u32; +pub const ERROR_APPEXEC_CONDITION_NOT_SATISFIED: WIN32_ERROR = 3060u32; +pub const ERROR_APPEXEC_HANDLE_INVALIDATED: WIN32_ERROR = 3061u32; +pub const ERROR_APPEXEC_HOST_ID_MISMATCH: WIN32_ERROR = 3066u32; +pub const ERROR_APPEXEC_INVALID_HOST_GENERATION: WIN32_ERROR = 3062u32; +pub const ERROR_APPEXEC_INVALID_HOST_STATE: WIN32_ERROR = 3064u32; +pub const ERROR_APPEXEC_NO_DONOR: WIN32_ERROR = 3065u32; +pub const ERROR_APPEXEC_UNEXPECTED_PROCESS_REGISTRATION: WIN32_ERROR = 3063u32; +pub const ERROR_APPEXEC_UNKNOWN_USER: WIN32_ERROR = 3067u32; +pub const ERROR_APPHELP_BLOCK: WIN32_ERROR = 1259u32; +pub const ERROR_APPX_FILE_NOT_ENCRYPTED: WIN32_ERROR = 409u32; +pub const ERROR_APP_HANG: WIN32_ERROR = 1298u32; +pub const ERROR_APP_INIT_FAILURE: WIN32_ERROR = 575u32; +pub const ERROR_APP_WRONG_OS: WIN32_ERROR = 1151u32; +pub const ERROR_ARBITRATION_UNHANDLED: WIN32_ERROR = 723u32; +pub const ERROR_ARENA_TRASHED: WIN32_ERROR = 7u32; +pub const ERROR_ARITHMETIC_OVERFLOW: WIN32_ERROR = 534u32; +pub const ERROR_ASSERTION_FAILURE: WIN32_ERROR = 668u32; +pub const ERROR_ATOMIC_LOCKS_NOT_SUPPORTED: WIN32_ERROR = 174u32; +pub const ERROR_AUDIT_FAILED: WIN32_ERROR = 606u32; +pub const ERROR_AUTHENTICATION_FIREWALL_FAILED: WIN32_ERROR = 1935u32; +pub const ERROR_AUTHIP_FAILURE: WIN32_ERROR = 1469u32; +pub const ERROR_AUTODATASEG_EXCEEDS_64k: WIN32_ERROR = 199u32; +pub const ERROR_BACKUP_CONTROLLER: WIN32_ERROR = 586u32; +pub const ERROR_BADDB: WIN32_ERROR = 1009u32; +pub const ERROR_BADKEY: WIN32_ERROR = 1010u32; +pub const ERROR_BADSTARTPOSITION: WIN32_ERROR = 778u32; +pub const ERROR_BAD_ACCESSOR_FLAGS: WIN32_ERROR = 773u32; +pub const ERROR_BAD_ARGUMENTS: WIN32_ERROR = 160u32; +pub const ERROR_BAD_COMMAND: WIN32_ERROR = 22u32; +pub const ERROR_BAD_COMPRESSION_BUFFER: WIN32_ERROR = 605u32; +pub const ERROR_BAD_CONFIGURATION: WIN32_ERROR = 1610u32; +pub const ERROR_BAD_CURRENT_DIRECTORY: WIN32_ERROR = 703u32; +pub const ERROR_BAD_DESCRIPTOR_FORMAT: WIN32_ERROR = 1361u32; +pub const ERROR_BAD_DEVICE: WIN32_ERROR = 1200u32; +pub const ERROR_BAD_DEVICE_PATH: WIN32_ERROR = 330u32; +pub const ERROR_BAD_DEV_TYPE: WIN32_ERROR = 66u32; +pub const ERROR_BAD_DLL_ENTRYPOINT: WIN32_ERROR = 609u32; +pub const ERROR_BAD_DRIVER_LEVEL: WIN32_ERROR = 119u32; +pub const ERROR_BAD_ENVIRONMENT: WIN32_ERROR = 10u32; +pub const ERROR_BAD_EXE_FORMAT: WIN32_ERROR = 193u32; +pub const ERROR_BAD_FILE_TYPE: WIN32_ERROR = 222u32; +pub const ERROR_BAD_FORMAT: WIN32_ERROR = 11u32; +pub const ERROR_BAD_FUNCTION_TABLE: WIN32_ERROR = 559u32; +pub const ERROR_BAD_IMPERSONATION_LEVEL: WIN32_ERROR = 1346u32; +pub const ERROR_BAD_INHERITANCE_ACL: WIN32_ERROR = 1340u32; +pub const ERROR_BAD_LENGTH: WIN32_ERROR = 24u32; +pub const ERROR_BAD_LOGON_SESSION_STATE: WIN32_ERROR = 1365u32; +pub const ERROR_BAD_MCFG_TABLE: WIN32_ERROR = 791u32; +pub const ERROR_BAD_NETPATH: WIN32_ERROR = 53u32; +pub const ERROR_BAD_NET_NAME: WIN32_ERROR = 67u32; +pub const ERROR_BAD_NET_RESP: WIN32_ERROR = 58u32; +pub const ERROR_BAD_PATHNAME: WIN32_ERROR = 161u32; +pub const ERROR_BAD_PIPE: WIN32_ERROR = 230u32; +pub const ERROR_BAD_PROFILE: WIN32_ERROR = 1206u32; +pub const ERROR_BAD_PROVIDER: WIN32_ERROR = 1204u32; +pub const ERROR_BAD_QUERY_SYNTAX: WIN32_ERROR = 1615u32; +pub const ERROR_BAD_RECOVERY_POLICY: WIN32_ERROR = 6012u32; +pub const ERROR_BAD_REM_ADAP: WIN32_ERROR = 60u32; +pub const ERROR_BAD_SERVICE_ENTRYPOINT: WIN32_ERROR = 610u32; +pub const ERROR_BAD_STACK: WIN32_ERROR = 543u32; +pub const ERROR_BAD_THREADID_ADDR: WIN32_ERROR = 159u32; +pub const ERROR_BAD_TOKEN_TYPE: WIN32_ERROR = 1349u32; +pub const ERROR_BAD_UNIT: WIN32_ERROR = 20u32; +pub const ERROR_BAD_USERNAME: WIN32_ERROR = 2202u32; +pub const ERROR_BAD_USER_PROFILE: WIN32_ERROR = 1253u32; +pub const ERROR_BAD_VALIDATION_CLASS: WIN32_ERROR = 1348u32; +pub const ERROR_BEGINNING_OF_MEDIA: WIN32_ERROR = 1102u32; +pub const ERROR_BEYOND_VDL: WIN32_ERROR = 1289u32; +pub const ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT: WIN32_ERROR = 585u32; +pub const ERROR_BLOCKED_BY_PARENTAL_CONTROLS: WIN32_ERROR = 346u32; +pub const ERROR_BLOCK_SHARED: WIN32_ERROR = 514u32; +pub const ERROR_BLOCK_SOURCE_WEAK_REFERENCE_INVALID: WIN32_ERROR = 512u32; +pub const ERROR_BLOCK_TARGET_WEAK_REFERENCE_INVALID: WIN32_ERROR = 513u32; +pub const ERROR_BLOCK_TOO_MANY_REFERENCES: WIN32_ERROR = 347u32; +pub const ERROR_BLOCK_WEAK_REFERENCE_INVALID: WIN32_ERROR = 511u32; +pub const ERROR_BOOT_ALREADY_ACCEPTED: WIN32_ERROR = 1076u32; +pub const ERROR_BROKEN_PIPE: WIN32_ERROR = 109u32; +pub const ERROR_BUFFER_ALL_ZEROS: WIN32_ERROR = 754u32; +pub const ERROR_BUFFER_OVERFLOW: WIN32_ERROR = 111u32; +pub const ERROR_BUSY: WIN32_ERROR = 170u32; +pub const ERROR_BUSY_DRIVE: WIN32_ERROR = 142u32; +pub const ERROR_BUS_RESET: WIN32_ERROR = 1111u32; +pub const ERROR_BYPASSIO_FLT_NOT_SUPPORTED: WIN32_ERROR = 506u32; +pub const ERROR_CACHE_PAGE_LOCKED: WIN32_ERROR = 752u32; +pub const ERROR_CALLBACK_INVOKE_INLINE: WIN32_ERROR = 812u32; +pub const ERROR_CALLBACK_POP_STACK: WIN32_ERROR = 768u32; +pub const ERROR_CALLBACK_SUPPLIED_INVALID_DATA: WIN32_ERROR = 1273u32; +pub const ERROR_CALL_NOT_IMPLEMENTED: WIN32_ERROR = 120u32; +pub const ERROR_CANCELLED: WIN32_ERROR = 1223u32; +pub const ERROR_CANCEL_VIOLATION: WIN32_ERROR = 173u32; +pub const ERROR_CANNOT_BREAK_OPLOCK: WIN32_ERROR = 802u32; +pub const ERROR_CANNOT_COPY: WIN32_ERROR = 266u32; +pub const ERROR_CANNOT_DETECT_DRIVER_FAILURE: WIN32_ERROR = 1080u32; +pub const ERROR_CANNOT_DETECT_PROCESS_ABORT: WIN32_ERROR = 1081u32; +pub const ERROR_CANNOT_FIND_WND_CLASS: WIN32_ERROR = 1407u32; +pub const ERROR_CANNOT_GRANT_REQUESTED_OPLOCK: WIN32_ERROR = 801u32; +pub const ERROR_CANNOT_IMPERSONATE: WIN32_ERROR = 1368u32; +pub const ERROR_CANNOT_LOAD_REGISTRY_FILE: WIN32_ERROR = 589u32; +pub const ERROR_CANNOT_MAKE: WIN32_ERROR = 82u32; +pub const ERROR_CANNOT_OPEN_PROFILE: WIN32_ERROR = 1205u32; +pub const ERROR_CANTFETCHBACKWARDS: WIN32_ERROR = 770u32; +pub const ERROR_CANTOPEN: WIN32_ERROR = 1011u32; +pub const ERROR_CANTREAD: WIN32_ERROR = 1012u32; +pub const ERROR_CANTSCROLLBACKWARDS: WIN32_ERROR = 771u32; +pub const ERROR_CANTWRITE: WIN32_ERROR = 1013u32; +pub const ERROR_CANT_ACCESS_DOMAIN_INFO: WIN32_ERROR = 1351u32; +pub const ERROR_CANT_ACCESS_FILE: WIN32_ERROR = 1920u32; +pub const ERROR_CANT_CLEAR_ENCRYPTION_FLAG: WIN32_ERROR = 432u32; +pub const ERROR_CANT_DISABLE_MANDATORY: WIN32_ERROR = 1310u32; +pub const ERROR_CANT_ENABLE_DENY_ONLY: WIN32_ERROR = 629u32; +pub const ERROR_CANT_OPEN_ANONYMOUS: WIN32_ERROR = 1347u32; +pub const ERROR_CANT_RESOLVE_FILENAME: WIN32_ERROR = 1921u32; +pub const ERROR_CANT_TERMINATE_SELF: WIN32_ERROR = 555u32; +pub const ERROR_CANT_WAIT: WIN32_ERROR = 554u32; +pub const ERROR_CAN_NOT_COMPLETE: WIN32_ERROR = 1003u32; +pub const ERROR_CAPAUTHZ_CHANGE_TYPE: WIN32_ERROR = 451u32; +pub const ERROR_CAPAUTHZ_DB_CORRUPTED: WIN32_ERROR = 455u32; +pub const ERROR_CAPAUTHZ_NOT_AUTHORIZED: WIN32_ERROR = 453u32; +pub const ERROR_CAPAUTHZ_NOT_DEVUNLOCKED: WIN32_ERROR = 450u32; +pub const ERROR_CAPAUTHZ_NOT_PROVISIONED: WIN32_ERROR = 452u32; +pub const ERROR_CAPAUTHZ_NO_POLICY: WIN32_ERROR = 454u32; +pub const ERROR_CAPAUTHZ_SCCD_DEV_MODE_REQUIRED: WIN32_ERROR = 459u32; +pub const ERROR_CAPAUTHZ_SCCD_INVALID_CATALOG: WIN32_ERROR = 456u32; +pub const ERROR_CAPAUTHZ_SCCD_NO_AUTH_ENTITY: WIN32_ERROR = 457u32; +pub const ERROR_CAPAUTHZ_SCCD_NO_CAPABILITY_MATCH: WIN32_ERROR = 460u32; +pub const ERROR_CAPAUTHZ_SCCD_PARSE_ERROR: WIN32_ERROR = 458u32; +pub const ERROR_CARDBUS_NOT_SUPPORTED: WIN32_ERROR = 724u32; +pub const ERROR_CASE_DIFFERING_NAMES_IN_DIR: WIN32_ERROR = 424u32; +pub const ERROR_CASE_SENSITIVE_PATH: WIN32_ERROR = 442u32; +pub const ERROR_CERTIFICATE_VALIDATION_PREFERENCE_CONFLICT: WIN32_ERROR = 817u32; +pub const ERROR_CHECKING_FILE_SYSTEM: WIN32_ERROR = 712u32; +pub const ERROR_CHECKOUT_REQUIRED: WIN32_ERROR = 221u32; +pub const ERROR_CHILD_MUST_BE_VOLATILE: WIN32_ERROR = 1021u32; +pub const ERROR_CHILD_NOT_COMPLETE: WIN32_ERROR = 129u32; +pub const ERROR_CHILD_PROCESS_BLOCKED: WIN32_ERROR = 367u32; +pub const ERROR_CHILD_WINDOW_MENU: WIN32_ERROR = 1436u32; +pub const ERROR_CIMFS_IMAGE_CORRUPT: WIN32_ERROR = 470u32; +pub const ERROR_CIMFS_IMAGE_VERSION_NOT_SUPPORTED: WIN32_ERROR = 471u32; +pub const ERROR_CIRCULAR_DEPENDENCY: WIN32_ERROR = 1059u32; +pub const ERROR_CLASS_ALREADY_EXISTS: WIN32_ERROR = 1410u32; +pub const ERROR_CLASS_DOES_NOT_EXIST: WIN32_ERROR = 1411u32; +pub const ERROR_CLASS_HAS_WINDOWS: WIN32_ERROR = 1412u32; +pub const ERROR_CLIENT_SERVER_PARAMETERS_INVALID: WIN32_ERROR = 597u32; +pub const ERROR_CLIPBOARD_NOT_OPEN: WIN32_ERROR = 1418u32; +pub const ERROR_CLOUD_FILE_ACCESS_DENIED: WIN32_ERROR = 395u32; +pub const ERROR_CLOUD_FILE_ALREADY_CONNECTED: WIN32_ERROR = 378u32; +pub const ERROR_CLOUD_FILE_AUTHENTICATION_FAILED: WIN32_ERROR = 386u32; +pub const ERROR_CLOUD_FILE_CONNECTED_PROVIDER_ONLY: WIN32_ERROR = 382u32; +pub const ERROR_CLOUD_FILE_DEHYDRATION_DISALLOWED: WIN32_ERROR = 434u32; +pub const ERROR_CLOUD_FILE_INCOMPATIBLE_HARDLINKS: WIN32_ERROR = 396u32; +pub const ERROR_CLOUD_FILE_INSUFFICIENT_RESOURCES: WIN32_ERROR = 387u32; +pub const ERROR_CLOUD_FILE_INVALID_REQUEST: WIN32_ERROR = 380u32; +pub const ERROR_CLOUD_FILE_IN_USE: WIN32_ERROR = 391u32; +pub const ERROR_CLOUD_FILE_METADATA_CORRUPT: WIN32_ERROR = 363u32; +pub const ERROR_CLOUD_FILE_METADATA_TOO_LARGE: WIN32_ERROR = 364u32; +pub const ERROR_CLOUD_FILE_NETWORK_UNAVAILABLE: WIN32_ERROR = 388u32; +pub const ERROR_CLOUD_FILE_NOT_IN_SYNC: WIN32_ERROR = 377u32; +pub const ERROR_CLOUD_FILE_NOT_SUPPORTED: WIN32_ERROR = 379u32; +pub const ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT: WIN32_ERROR = 390u32; +pub const ERROR_CLOUD_FILE_PINNED: WIN32_ERROR = 392u32; +pub const ERROR_CLOUD_FILE_PROPERTY_BLOB_CHECKSUM_MISMATCH: WIN32_ERROR = 366u32; +pub const ERROR_CLOUD_FILE_PROPERTY_BLOB_TOO_LARGE: WIN32_ERROR = 365u32; +pub const ERROR_CLOUD_FILE_PROPERTY_CORRUPT: WIN32_ERROR = 394u32; +pub const ERROR_CLOUD_FILE_PROPERTY_LOCK_CONFLICT: WIN32_ERROR = 397u32; +pub const ERROR_CLOUD_FILE_PROPERTY_VERSION_NOT_SUPPORTED: WIN32_ERROR = 375u32; +pub const ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING: WIN32_ERROR = 362u32; +pub const ERROR_CLOUD_FILE_PROVIDER_TERMINATED: WIN32_ERROR = 404u32; +pub const ERROR_CLOUD_FILE_READ_ONLY_VOLUME: WIN32_ERROR = 381u32; +pub const ERROR_CLOUD_FILE_REQUEST_ABORTED: WIN32_ERROR = 393u32; +pub const ERROR_CLOUD_FILE_REQUEST_CANCELED: WIN32_ERROR = 398u32; +pub const ERROR_CLOUD_FILE_REQUEST_TIMEOUT: WIN32_ERROR = 426u32; +pub const ERROR_CLOUD_FILE_SYNC_ROOT_METADATA_CORRUPT: WIN32_ERROR = 358u32; +pub const ERROR_CLOUD_FILE_TOO_MANY_PROPERTY_BLOBS: WIN32_ERROR = 374u32; +pub const ERROR_CLOUD_FILE_UNSUCCESSFUL: WIN32_ERROR = 389u32; +pub const ERROR_CLOUD_FILE_US_MESSAGE_TIMEOUT: WIN32_ERROR = 475u32; +pub const ERROR_CLOUD_FILE_VALIDATION_FAILED: WIN32_ERROR = 383u32; +pub const ERROR_COMMITMENT_LIMIT: WIN32_ERROR = 1455u32; +pub const ERROR_COMMITMENT_MINIMUM: WIN32_ERROR = 635u32; +pub const ERROR_COMPRESSED_FILE_NOT_SUPPORTED: WIN32_ERROR = 335u32; +pub const ERROR_COMPRESSION_DISABLED: WIN32_ERROR = 769u32; +pub const ERROR_COMPRESSION_NOT_BENEFICIAL: WIN32_ERROR = 344u32; +pub const ERROR_CONNECTED_OTHER_PASSWORD: WIN32_ERROR = 2108u32; +pub const ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT: WIN32_ERROR = 2109u32; +pub const ERROR_CONNECTION_ABORTED: WIN32_ERROR = 1236u32; +pub const ERROR_CONNECTION_ACTIVE: WIN32_ERROR = 1230u32; +pub const ERROR_CONNECTION_COUNT_LIMIT: WIN32_ERROR = 1238u32; +pub const ERROR_CONNECTION_INVALID: WIN32_ERROR = 1229u32; +pub const ERROR_CONNECTION_REFUSED: WIN32_ERROR = 1225u32; +pub const ERROR_CONNECTION_UNAVAIL: WIN32_ERROR = 1201u32; +pub const ERROR_CONTAINER_ASSIGNED: WIN32_ERROR = 1504u32; +pub const ERROR_CONTENT_BLOCKED: WIN32_ERROR = 1296u32; +pub const ERROR_CONTEXT_EXPIRED: WIN32_ERROR = 1931u32; +pub const ERROR_CONTINUE: WIN32_ERROR = 1246u32; +pub const ERROR_CONTROL_C_EXIT: WIN32_ERROR = 572u32; +pub const ERROR_CONTROL_ID_NOT_FOUND: WIN32_ERROR = 1421u32; +pub const ERROR_CONVERT_TO_LARGE: WIN32_ERROR = 600u32; +pub const ERROR_CORRUPT_LOG_CLEARED: WIN32_ERROR = 798u32; +pub const ERROR_CORRUPT_LOG_CORRUPTED: WIN32_ERROR = 795u32; +pub const ERROR_CORRUPT_LOG_DELETED_FULL: WIN32_ERROR = 797u32; +pub const ERROR_CORRUPT_LOG_OVERFULL: WIN32_ERROR = 794u32; +pub const ERROR_CORRUPT_LOG_UNAVAILABLE: WIN32_ERROR = 796u32; +pub const ERROR_CORRUPT_SYSTEM_FILE: WIN32_ERROR = 634u32; +pub const ERROR_COULD_NOT_INTERPRET: WIN32_ERROR = 552u32; +pub const ERROR_COUNTER_TIMEOUT: WIN32_ERROR = 1121u32; +pub const ERROR_CPU_SET_INVALID: WIN32_ERROR = 813u32; +pub const ERROR_CRASH_DUMP: WIN32_ERROR = 753u32; +pub const ERROR_CRC: WIN32_ERROR = 23u32; +pub const ERROR_CREATE_FAILED: WIN32_ERROR = 1631u32; +pub const ERROR_CROSS_PARTITION_VIOLATION: WIN32_ERROR = 1661u32; +pub const ERROR_CSCSHARE_OFFLINE: WIN32_ERROR = 1262u32; +pub const ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE: WIN32_ERROR = 6019u32; +pub const ERROR_CS_ENCRYPTION_FILE_NOT_CSE: WIN32_ERROR = 6021u32; +pub const ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE: WIN32_ERROR = 6017u32; +pub const ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE: WIN32_ERROR = 6020u32; +pub const ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER: WIN32_ERROR = 6018u32; +pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: WIN32_ERROR = 7040u32; +pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: WIN32_ERROR = 7012u32; +pub const ERROR_CURRENT_DIRECTORY: WIN32_ERROR = 16u32; +pub const ERROR_CURRENT_DOMAIN_NOT_ALLOWED: WIN32_ERROR = 1399u32; +pub const ERROR_DATABASE_DOES_NOT_EXIST: WIN32_ERROR = 1065u32; +pub const ERROR_DATATYPE_MISMATCH: WIN32_ERROR = 1629u32; +pub const ERROR_DATA_CHECKSUM_ERROR: WIN32_ERROR = 323u32; +pub const ERROR_DATA_NOT_ACCEPTED: WIN32_ERROR = 592u32; +pub const ERROR_DAX_MAPPING_EXISTS: WIN32_ERROR = 361u32; +pub const ERROR_DBG_COMMAND_EXCEPTION: WIN32_ERROR = 697u32; +pub const ERROR_DBG_CONTINUE: WIN32_ERROR = 767u32; +pub const ERROR_DBG_CONTROL_BREAK: WIN32_ERROR = 696u32; +pub const ERROR_DBG_CONTROL_C: WIN32_ERROR = 693u32; +pub const ERROR_DBG_EXCEPTION_HANDLED: WIN32_ERROR = 766u32; +pub const ERROR_DBG_EXCEPTION_NOT_HANDLED: WIN32_ERROR = 688u32; +pub const ERROR_DBG_PRINTEXCEPTION_C: WIN32_ERROR = 694u32; +pub const ERROR_DBG_REPLY_LATER: WIN32_ERROR = 689u32; +pub const ERROR_DBG_RIPEXCEPTION: WIN32_ERROR = 695u32; +pub const ERROR_DBG_TERMINATE_PROCESS: WIN32_ERROR = 692u32; +pub const ERROR_DBG_TERMINATE_THREAD: WIN32_ERROR = 691u32; +pub const ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE: WIN32_ERROR = 690u32; +pub const ERROR_DC_NOT_FOUND: WIN32_ERROR = 1425u32; +pub const ERROR_DDE_FAIL: WIN32_ERROR = 1156u32; +pub const ERROR_DEBUGGER_INACTIVE: WIN32_ERROR = 1284u32; +pub const ERROR_DEBUG_ATTACH_FAILED: WIN32_ERROR = 590u32; +pub const ERROR_DECRYPTION_FAILED: WIN32_ERROR = 6001u32; +pub const ERROR_DELAY_LOAD_FAILED: WIN32_ERROR = 1285u32; +pub const ERROR_DELETE_PENDING: WIN32_ERROR = 303u32; +pub const ERROR_DEPENDENT_SERVICES_RUNNING: WIN32_ERROR = 1051u32; +pub const ERROR_DESTINATION_ELEMENT_FULL: WIN32_ERROR = 1161u32; +pub const ERROR_DESTROY_OBJECT_OF_OTHER_THREAD: WIN32_ERROR = 1435u32; +pub const ERROR_DEVICE_ALREADY_ATTACHED: WIN32_ERROR = 548u32; +pub const ERROR_DEVICE_ALREADY_REMEMBERED: WIN32_ERROR = 1202u32; +pub const ERROR_DEVICE_DOOR_OPEN: WIN32_ERROR = 1166u32; +pub const ERROR_DEVICE_ENUMERATION_ERROR: WIN32_ERROR = 648u32; +pub const ERROR_DEVICE_FEATURE_NOT_SUPPORTED: WIN32_ERROR = 316u32; +pub const ERROR_DEVICE_HARDWARE_ERROR: WIN32_ERROR = 483u32; +pub const ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL: WIN32_ERROR = 355u32; +pub const ERROR_DEVICE_IN_MAINTENANCE: WIN32_ERROR = 359u32; +pub const ERROR_DEVICE_IN_USE: WIN32_ERROR = 2404u32; +pub const ERROR_DEVICE_NOT_CONNECTED: WIN32_ERROR = 1167u32; +pub const ERROR_DEVICE_NOT_PARTITIONED: WIN32_ERROR = 1107u32; +pub const ERROR_DEVICE_NO_RESOURCES: WIN32_ERROR = 322u32; +pub const ERROR_DEVICE_REINITIALIZATION_NEEDED: WIN32_ERROR = 1164u32; +pub const ERROR_DEVICE_REMOVED: WIN32_ERROR = 1617u32; +pub const ERROR_DEVICE_REQUIRES_CLEANING: WIN32_ERROR = 1165u32; +pub const ERROR_DEVICE_RESET_REQUIRED: WIN32_ERROR = 507u32; +pub const ERROR_DEVICE_SUPPORT_IN_PROGRESS: WIN32_ERROR = 171u32; +pub const ERROR_DEVICE_UNREACHABLE: WIN32_ERROR = 321u32; +pub const ERROR_DEV_NOT_EXIST: WIN32_ERROR = 55u32; +pub const ERROR_DHCP_ADDRESS_CONFLICT: WIN32_ERROR = 4100u32; +pub const ERROR_DIFFERENT_SERVICE_ACCOUNT: WIN32_ERROR = 1079u32; +pub const ERROR_DIRECTORY: WIN32_ERROR = 267u32; +pub const ERROR_DIRECTORY_NOT_SUPPORTED: WIN32_ERROR = 336u32; +pub const ERROR_DIRECT_ACCESS_HANDLE: WIN32_ERROR = 130u32; +pub const ERROR_DIR_EFS_DISALLOWED: WIN32_ERROR = 6010u32; +pub const ERROR_DIR_NOT_EMPTY: WIN32_ERROR = 145u32; +pub const ERROR_DIR_NOT_ROOT: WIN32_ERROR = 144u32; +pub const ERROR_DISCARDED: WIN32_ERROR = 157u32; +pub const ERROR_DISK_CHANGE: WIN32_ERROR = 107u32; +pub const ERROR_DISK_CORRUPT: WIN32_ERROR = 1393u32; +pub const ERROR_DISK_FULL: WIN32_ERROR = 112u32; +pub const ERROR_DISK_OPERATION_FAILED: WIN32_ERROR = 1127u32; +pub const ERROR_DISK_QUOTA_EXCEEDED: WIN32_ERROR = 1295u32; +pub const ERROR_DISK_RECALIBRATE_FAILED: WIN32_ERROR = 1126u32; +pub const ERROR_DISK_REPAIR_DISABLED: WIN32_ERROR = 780u32; +pub const ERROR_DISK_REPAIR_REDIRECTED: WIN32_ERROR = 792u32; +pub const ERROR_DISK_REPAIR_UNSUCCESSFUL: WIN32_ERROR = 793u32; +pub const ERROR_DISK_RESET_FAILED: WIN32_ERROR = 1128u32; +pub const ERROR_DISK_RESOURCES_EXHAUSTED: WIN32_ERROR = 314u32; +pub const ERROR_DISK_TOO_FRAGMENTED: WIN32_ERROR = 302u32; +pub const ERROR_DLL_INIT_FAILED: WIN32_ERROR = 1114u32; +pub const ERROR_DLL_INIT_FAILED_LOGOFF: WIN32_ERROR = 624u32; +pub const ERROR_DLL_MIGHT_BE_INCOMPATIBLE: WIN32_ERROR = 687u32; +pub const ERROR_DLL_MIGHT_BE_INSECURE: WIN32_ERROR = 686u32; +pub const ERROR_DLL_NOT_FOUND: WIN32_ERROR = 1157u32; +pub const ERROR_DLP_POLICY_DENIES_OPERATION: WIN32_ERROR = 446u32; +pub const ERROR_DLP_POLICY_SILENTLY_FAIL: WIN32_ERROR = 449u32; +pub const ERROR_DLP_POLICY_WARNS_AGAINST_OPERATION: WIN32_ERROR = 445u32; +pub const ERROR_DOMAIN_CONTROLLER_EXISTS: WIN32_ERROR = 1250u32; +pub const ERROR_DOMAIN_CONTROLLER_NOT_FOUND: WIN32_ERROR = 1908u32; +pub const ERROR_DOMAIN_CTRLR_CONFIG_ERROR: WIN32_ERROR = 581u32; +pub const ERROR_DOMAIN_EXISTS: WIN32_ERROR = 1356u32; +pub const ERROR_DOMAIN_LIMIT_EXCEEDED: WIN32_ERROR = 1357u32; +pub const ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION: WIN32_ERROR = 8644u32; +pub const ERROR_DOMAIN_TRUST_INCONSISTENT: WIN32_ERROR = 1810u32; +pub const ERROR_DOWNGRADE_DETECTED: WIN32_ERROR = 1265u32; +pub const ERROR_DPL_NOT_SUPPORTED_FOR_USER: WIN32_ERROR = 423u32; +pub const ERROR_DRIVERS_LEAKING_LOCKED_PAGES: WIN32_ERROR = 729u32; +pub const ERROR_DRIVER_BLOCKED: WIN32_ERROR = 1275u32; +pub const ERROR_DRIVER_CANCEL_TIMEOUT: WIN32_ERROR = 594u32; +pub const ERROR_DRIVER_DATABASE_ERROR: WIN32_ERROR = 652u32; +pub const ERROR_DRIVER_FAILED_PRIOR_UNLOAD: WIN32_ERROR = 654u32; +pub const ERROR_DRIVER_FAILED_SLEEP: WIN32_ERROR = 633u32; +pub const ERROR_DRIVER_PROCESS_TERMINATED: WIN32_ERROR = 1291u32; +pub const ERROR_DRIVE_LOCKED: WIN32_ERROR = 108u32; +pub const ERROR_DS_ADD_REPLICA_INHIBITED: WIN32_ERROR = 8302u32; +pub const ERROR_DS_ADMIN_LIMIT_EXCEEDED: WIN32_ERROR = 8228u32; +pub const ERROR_DS_AFFECTS_MULTIPLE_DSAS: WIN32_ERROR = 8249u32; +pub const ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: WIN32_ERROR = 8578u32; +pub const ERROR_DS_ALIASED_OBJ_MISSING: WIN32_ERROR = 8334u32; +pub const ERROR_DS_ALIAS_DEREF_PROBLEM: WIN32_ERROR = 8244u32; +pub const ERROR_DS_ALIAS_POINTS_TO_ALIAS: WIN32_ERROR = 8336u32; +pub const ERROR_DS_ALIAS_PROBLEM: WIN32_ERROR = 8241u32; +pub const ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS: WIN32_ERROR = 8205u32; +pub const ERROR_DS_ATTRIBUTE_OWNED_BY_SAM: WIN32_ERROR = 8346u32; +pub const ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED: WIN32_ERROR = 8204u32; +pub const ERROR_DS_ATT_ALREADY_EXISTS: WIN32_ERROR = 8318u32; +pub const ERROR_DS_ATT_IS_NOT_ON_OBJ: WIN32_ERROR = 8310u32; +pub const ERROR_DS_ATT_NOT_DEF_FOR_CLASS: WIN32_ERROR = 8317u32; +pub const ERROR_DS_ATT_NOT_DEF_IN_SCHEMA: WIN32_ERROR = 8303u32; +pub const ERROR_DS_ATT_SCHEMA_REQ_ID: WIN32_ERROR = 8399u32; +pub const ERROR_DS_ATT_SCHEMA_REQ_SYNTAX: WIN32_ERROR = 8416u32; +pub const ERROR_DS_ATT_VAL_ALREADY_EXISTS: WIN32_ERROR = 8323u32; +pub const ERROR_DS_AUDIT_FAILURE: WIN32_ERROR = 8625u32; +pub const ERROR_DS_AUTHORIZATION_FAILED: WIN32_ERROR = 8599u32; +pub const ERROR_DS_AUTH_METHOD_NOT_SUPPORTED: WIN32_ERROR = 8231u32; +pub const ERROR_DS_AUTH_UNKNOWN: WIN32_ERROR = 8234u32; +pub const ERROR_DS_AUX_CLS_TEST_FAIL: WIN32_ERROR = 8389u32; +pub const ERROR_DS_BACKLINK_WITHOUT_LINK: WIN32_ERROR = 8482u32; +pub const ERROR_DS_BAD_ATT_SCHEMA_SYNTAX: WIN32_ERROR = 8400u32; +pub const ERROR_DS_BAD_HIERARCHY_FILE: WIN32_ERROR = 8425u32; +pub const ERROR_DS_BAD_INSTANCE_TYPE: WIN32_ERROR = 8313u32; +pub const ERROR_DS_BAD_NAME_SYNTAX: WIN32_ERROR = 8335u32; +pub const ERROR_DS_BAD_RDN_ATT_ID_SYNTAX: WIN32_ERROR = 8392u32; +pub const ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED: WIN32_ERROR = 8426u32; +pub const ERROR_DS_BUSY: WIN32_ERROR = 8206u32; +pub const ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD: WIN32_ERROR = 8585u32; +pub const ERROR_DS_CANT_ADD_ATT_VALUES: WIN32_ERROR = 8320u32; +pub const ERROR_DS_CANT_ADD_SYSTEM_ONLY: WIN32_ERROR = 8358u32; +pub const ERROR_DS_CANT_ADD_TO_GC: WIN32_ERROR = 8550u32; +pub const ERROR_DS_CANT_CACHE_ATT: WIN32_ERROR = 8401u32; +pub const ERROR_DS_CANT_CACHE_CLASS: WIN32_ERROR = 8402u32; +pub const ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC: WIN32_ERROR = 8553u32; +pub const ERROR_DS_CANT_CREATE_UNDER_SCHEMA: WIN32_ERROR = 8510u32; +pub const ERROR_DS_CANT_DELETE: WIN32_ERROR = 8398u32; +pub const ERROR_DS_CANT_DELETE_DSA_OBJ: WIN32_ERROR = 8340u32; +pub const ERROR_DS_CANT_DEL_MASTER_CROSSREF: WIN32_ERROR = 8375u32; +pub const ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC: WIN32_ERROR = 8604u32; +pub const ERROR_DS_CANT_DEREF_ALIAS: WIN32_ERROR = 8337u32; +pub const ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN: WIN32_ERROR = 8603u32; +pub const ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF: WIN32_ERROR = 8589u32; +pub const ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN: WIN32_ERROR = 8537u32; +pub const ERROR_DS_CANT_FIND_DSA_OBJ: WIN32_ERROR = 8419u32; +pub const ERROR_DS_CANT_FIND_EXPECTED_NC: WIN32_ERROR = 8420u32; +pub const ERROR_DS_CANT_FIND_NC_IN_CACHE: WIN32_ERROR = 8421u32; +pub const ERROR_DS_CANT_MIX_MASTER_AND_REPS: WIN32_ERROR = 8331u32; +pub const ERROR_DS_CANT_MOD_OBJ_CLASS: WIN32_ERROR = 8215u32; +pub const ERROR_DS_CANT_MOD_PRIMARYGROUPID: WIN32_ERROR = 8506u32; +pub const ERROR_DS_CANT_MOD_SYSTEM_ONLY: WIN32_ERROR = 8369u32; +pub const ERROR_DS_CANT_MOVE_ACCOUNT_GROUP: WIN32_ERROR = 8498u32; +pub const ERROR_DS_CANT_MOVE_APP_BASIC_GROUP: WIN32_ERROR = 8608u32; +pub const ERROR_DS_CANT_MOVE_APP_QUERY_GROUP: WIN32_ERROR = 8609u32; +pub const ERROR_DS_CANT_MOVE_DELETED_OBJECT: WIN32_ERROR = 8489u32; +pub const ERROR_DS_CANT_MOVE_RESOURCE_GROUP: WIN32_ERROR = 8499u32; +pub const ERROR_DS_CANT_ON_NON_LEAF: WIN32_ERROR = 8213u32; +pub const ERROR_DS_CANT_ON_RDN: WIN32_ERROR = 8214u32; +pub const ERROR_DS_CANT_REMOVE_ATT_CACHE: WIN32_ERROR = 8403u32; +pub const ERROR_DS_CANT_REMOVE_CLASS_CACHE: WIN32_ERROR = 8404u32; +pub const ERROR_DS_CANT_REM_MISSING_ATT: WIN32_ERROR = 8324u32; +pub const ERROR_DS_CANT_REM_MISSING_ATT_VAL: WIN32_ERROR = 8325u32; +pub const ERROR_DS_CANT_REPLACE_HIDDEN_REC: WIN32_ERROR = 8424u32; +pub const ERROR_DS_CANT_RETRIEVE_ATTS: WIN32_ERROR = 8481u32; +pub const ERROR_DS_CANT_RETRIEVE_CHILD: WIN32_ERROR = 8422u32; +pub const ERROR_DS_CANT_RETRIEVE_DN: WIN32_ERROR = 8405u32; +pub const ERROR_DS_CANT_RETRIEVE_INSTANCE: WIN32_ERROR = 8407u32; +pub const ERROR_DS_CANT_RETRIEVE_SD: WIN32_ERROR = 8526u32; +pub const ERROR_DS_CANT_START: WIN32_ERROR = 8531u32; +pub const ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ: WIN32_ERROR = 8560u32; +pub const ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS: WIN32_ERROR = 8493u32; +pub const ERROR_DS_CHILDREN_EXIST: WIN32_ERROR = 8332u32; +pub const ERROR_DS_CLASS_MUST_BE_CONCRETE: WIN32_ERROR = 8359u32; +pub const ERROR_DS_CLASS_NOT_DSA: WIN32_ERROR = 8343u32; +pub const ERROR_DS_CLIENT_LOOP: WIN32_ERROR = 8259u32; +pub const ERROR_DS_CODE_INCONSISTENCY: WIN32_ERROR = 8408u32; +pub const ERROR_DS_COMPARE_FALSE: WIN32_ERROR = 8229u32; +pub const ERROR_DS_COMPARE_TRUE: WIN32_ERROR = 8230u32; +pub const ERROR_DS_CONFIDENTIALITY_REQUIRED: WIN32_ERROR = 8237u32; +pub const ERROR_DS_CONFIG_PARAM_MISSING: WIN32_ERROR = 8427u32; +pub const ERROR_DS_CONSTRAINT_VIOLATION: WIN32_ERROR = 8239u32; +pub const ERROR_DS_CONSTRUCTED_ATT_MOD: WIN32_ERROR = 8475u32; +pub const ERROR_DS_CONTROL_NOT_FOUND: WIN32_ERROR = 8258u32; +pub const ERROR_DS_COULDNT_CONTACT_FSMO: WIN32_ERROR = 8367u32; +pub const ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE: WIN32_ERROR = 8503u32; +pub const ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE: WIN32_ERROR = 8502u32; +pub const ERROR_DS_COULDNT_UPDATE_SPNS: WIN32_ERROR = 8525u32; +pub const ERROR_DS_COUNTING_AB_INDICES_FAILED: WIN32_ERROR = 8428u32; +pub const ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD: WIN32_ERROR = 8491u32; +pub const ERROR_DS_CROSS_DOM_MOVE_ERROR: WIN32_ERROR = 8216u32; +pub const ERROR_DS_CROSS_NC_DN_RENAME: WIN32_ERROR = 8368u32; +pub const ERROR_DS_CROSS_REF_BUSY: WIN32_ERROR = 8602u32; +pub const ERROR_DS_CROSS_REF_EXISTS: WIN32_ERROR = 8374u32; +pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE: WIN32_ERROR = 8495u32; +pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2: WIN32_ERROR = 8586u32; +pub const ERROR_DS_DATABASE_ERROR: WIN32_ERROR = 8409u32; +pub const ERROR_DS_DECODING_ERROR: WIN32_ERROR = 8253u32; +pub const ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED: WIN32_ERROR = 8536u32; +pub const ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST: WIN32_ERROR = 8535u32; +pub const ERROR_DS_DIFFERENT_REPL_EPOCHS: WIN32_ERROR = 8593u32; +pub const ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER: WIN32_ERROR = 8615u32; +pub const ERROR_DS_DISALLOWED_NC_REDIRECT: WIN32_ERROR = 8640u32; +pub const ERROR_DS_DNS_LOOKUP_FAILURE: WIN32_ERROR = 8524u32; +pub const ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST: WIN32_ERROR = 8634u32; +pub const ERROR_DS_DOMAIN_RENAME_IN_PROGRESS: WIN32_ERROR = 8612u32; +pub const ERROR_DS_DOMAIN_VERSION_TOO_HIGH: WIN32_ERROR = 8564u32; +pub const ERROR_DS_DOMAIN_VERSION_TOO_LOW: WIN32_ERROR = 8566u32; +pub const ERROR_DS_DRA_ABANDON_SYNC: WIN32_ERROR = 8462u32; +pub const ERROR_DS_DRA_ACCESS_DENIED: WIN32_ERROR = 8453u32; +pub const ERROR_DS_DRA_BAD_DN: WIN32_ERROR = 8439u32; +pub const ERROR_DS_DRA_BAD_INSTANCE_TYPE: WIN32_ERROR = 8445u32; +pub const ERROR_DS_DRA_BAD_NC: WIN32_ERROR = 8440u32; +pub const ERROR_DS_DRA_BUSY: WIN32_ERROR = 8438u32; +pub const ERROR_DS_DRA_CONNECTION_FAILED: WIN32_ERROR = 8444u32; +pub const ERROR_DS_DRA_CORRUPT_UTD_VECTOR: WIN32_ERROR = 8629u32; +pub const ERROR_DS_DRA_DB_ERROR: WIN32_ERROR = 8451u32; +pub const ERROR_DS_DRA_DN_EXISTS: WIN32_ERROR = 8441u32; +pub const ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT: WIN32_ERROR = 8544u32; +pub const ERROR_DS_DRA_EXTN_CONNECTION_FAILED: WIN32_ERROR = 8466u32; +pub const ERROR_DS_DRA_GENERIC: WIN32_ERROR = 8436u32; +pub const ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET: WIN32_ERROR = 8464u32; +pub const ERROR_DS_DRA_INCONSISTENT_DIT: WIN32_ERROR = 8443u32; +pub const ERROR_DS_DRA_INTERNAL_ERROR: WIN32_ERROR = 8442u32; +pub const ERROR_DS_DRA_INVALID_PARAMETER: WIN32_ERROR = 8437u32; +pub const ERROR_DS_DRA_MAIL_PROBLEM: WIN32_ERROR = 8447u32; +pub const ERROR_DS_DRA_MISSING_KRBTGT_SECRET: WIN32_ERROR = 8633u32; +pub const ERROR_DS_DRA_MISSING_PARENT: WIN32_ERROR = 8460u32; +pub const ERROR_DS_DRA_NAME_COLLISION: WIN32_ERROR = 8458u32; +pub const ERROR_DS_DRA_NOT_SUPPORTED: WIN32_ERROR = 8454u32; +pub const ERROR_DS_DRA_NO_REPLICA: WIN32_ERROR = 8452u32; +pub const ERROR_DS_DRA_OBJ_IS_REP_SOURCE: WIN32_ERROR = 8450u32; +pub const ERROR_DS_DRA_OBJ_NC_MISMATCH: WIN32_ERROR = 8545u32; +pub const ERROR_DS_DRA_OUT_OF_MEM: WIN32_ERROR = 8446u32; +pub const ERROR_DS_DRA_OUT_SCHEDULE_WINDOW: WIN32_ERROR = 8617u32; +pub const ERROR_DS_DRA_PREEMPTED: WIN32_ERROR = 8461u32; +pub const ERROR_DS_DRA_RECYCLED_TARGET: WIN32_ERROR = 8639u32; +pub const ERROR_DS_DRA_REF_ALREADY_EXISTS: WIN32_ERROR = 8448u32; +pub const ERROR_DS_DRA_REF_NOT_FOUND: WIN32_ERROR = 8449u32; +pub const ERROR_DS_DRA_REPL_PENDING: WIN32_ERROR = 8477u32; +pub const ERROR_DS_DRA_RPC_CANCELLED: WIN32_ERROR = 8455u32; +pub const ERROR_DS_DRA_SCHEMA_CONFLICT: WIN32_ERROR = 8543u32; +pub const ERROR_DS_DRA_SCHEMA_INFO_SHIP: WIN32_ERROR = 8542u32; +pub const ERROR_DS_DRA_SCHEMA_MISMATCH: WIN32_ERROR = 8418u32; +pub const ERROR_DS_DRA_SECRETS_DENIED: WIN32_ERROR = 8630u32; +pub const ERROR_DS_DRA_SHUTDOWN: WIN32_ERROR = 8463u32; +pub const ERROR_DS_DRA_SINK_DISABLED: WIN32_ERROR = 8457u32; +pub const ERROR_DS_DRA_SOURCE_DISABLED: WIN32_ERROR = 8456u32; +pub const ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA: WIN32_ERROR = 8465u32; +pub const ERROR_DS_DRA_SOURCE_REINSTALLED: WIN32_ERROR = 8459u32; +pub const ERROR_DS_DRS_EXTENSIONS_CHANGED: WIN32_ERROR = 8594u32; +pub const ERROR_DS_DSA_MUST_BE_INT_MASTER: WIN32_ERROR = 8342u32; +pub const ERROR_DS_DST_DOMAIN_NOT_NATIVE: WIN32_ERROR = 8496u32; +pub const ERROR_DS_DST_NC_MISMATCH: WIN32_ERROR = 8486u32; +pub const ERROR_DS_DS_REQUIRED: WIN32_ERROR = 8478u32; +pub const ERROR_DS_DUPLICATE_ID_FOUND: WIN32_ERROR = 8605u32; +pub const ERROR_DS_DUP_LDAP_DISPLAY_NAME: WIN32_ERROR = 8382u32; +pub const ERROR_DS_DUP_LINK_ID: WIN32_ERROR = 8468u32; +pub const ERROR_DS_DUP_MAPI_ID: WIN32_ERROR = 8380u32; +pub const ERROR_DS_DUP_MSDS_INTID: WIN32_ERROR = 8597u32; +pub const ERROR_DS_DUP_OID: WIN32_ERROR = 8379u32; +pub const ERROR_DS_DUP_RDN: WIN32_ERROR = 8378u32; +pub const ERROR_DS_DUP_SCHEMA_ID_GUID: WIN32_ERROR = 8381u32; +pub const ERROR_DS_ENCODING_ERROR: WIN32_ERROR = 8252u32; +pub const ERROR_DS_EPOCH_MISMATCH: WIN32_ERROR = 8483u32; +pub const ERROR_DS_EXISTING_AD_CHILD_NC: WIN32_ERROR = 8613u32; +pub const ERROR_DS_EXISTS_IN_AUX_CLS: WIN32_ERROR = 8393u32; +pub const ERROR_DS_EXISTS_IN_MAY_HAVE: WIN32_ERROR = 8386u32; +pub const ERROR_DS_EXISTS_IN_MUST_HAVE: WIN32_ERROR = 8385u32; +pub const ERROR_DS_EXISTS_IN_POSS_SUP: WIN32_ERROR = 8395u32; +pub const ERROR_DS_EXISTS_IN_RDNATTID: WIN32_ERROR = 8598u32; +pub const ERROR_DS_EXISTS_IN_SUB_CLS: WIN32_ERROR = 8394u32; +pub const ERROR_DS_FILTER_UNKNOWN: WIN32_ERROR = 8254u32; +pub const ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS: WIN32_ERROR = 8555u32; +pub const ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST: WIN32_ERROR = 8635u32; +pub const ERROR_DS_FOREST_VERSION_TOO_HIGH: WIN32_ERROR = 8563u32; +pub const ERROR_DS_FOREST_VERSION_TOO_LOW: WIN32_ERROR = 8565u32; +pub const ERROR_DS_GCVERIFY_ERROR: WIN32_ERROR = 8417u32; +pub const ERROR_DS_GC_NOT_AVAILABLE: WIN32_ERROR = 8217u32; +pub const ERROR_DS_GC_REQUIRED: WIN32_ERROR = 8547u32; +pub const ERROR_DS_GENERIC_ERROR: WIN32_ERROR = 8341u32; +pub const ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: WIN32_ERROR = 8519u32; +pub const ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: WIN32_ERROR = 8516u32; +pub const ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: WIN32_ERROR = 8517u32; +pub const ERROR_DS_GOVERNSID_MISSING: WIN32_ERROR = 8410u32; +pub const ERROR_DS_GROUP_CONVERSION_ERROR: WIN32_ERROR = 8607u32; +pub const ERROR_DS_HAVE_PRIMARY_MEMBERS: WIN32_ERROR = 8521u32; +pub const ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED: WIN32_ERROR = 8429u32; +pub const ERROR_DS_HIERARCHY_TABLE_TOO_DEEP: WIN32_ERROR = 8628u32; +pub const ERROR_DS_HIGH_ADLDS_FFL: WIN32_ERROR = 8641u32; +pub const ERROR_DS_HIGH_DSA_VERSION: WIN32_ERROR = 8642u32; +pub const ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD: WIN32_ERROR = 8507u32; +pub const ERROR_DS_ILLEGAL_MOD_OPERATION: WIN32_ERROR = 8311u32; +pub const ERROR_DS_ILLEGAL_SUPERIOR: WIN32_ERROR = 8345u32; +pub const ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION: WIN32_ERROR = 8492u32; +pub const ERROR_DS_INAPPROPRIATE_AUTH: WIN32_ERROR = 8233u32; +pub const ERROR_DS_INAPPROPRIATE_MATCHING: WIN32_ERROR = 8238u32; +pub const ERROR_DS_INCOMPATIBLE_CONTROLS_USED: WIN32_ERROR = 8574u32; +pub const ERROR_DS_INCOMPATIBLE_VERSION: WIN32_ERROR = 8567u32; +pub const ERROR_DS_INCORRECT_ROLE_OWNER: WIN32_ERROR = 8210u32; +pub const ERROR_DS_INIT_FAILURE: WIN32_ERROR = 8532u32; +pub const ERROR_DS_INIT_FAILURE_CONSOLE: WIN32_ERROR = 8561u32; +pub const ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE: WIN32_ERROR = 8512u32; +pub const ERROR_DS_INSTALL_NO_SRC_SCH_VERSION: WIN32_ERROR = 8511u32; +pub const ERROR_DS_INSTALL_SCHEMA_MISMATCH: WIN32_ERROR = 8467u32; +pub const ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT: WIN32_ERROR = 8606u32; +pub const ERROR_DS_INSUFF_ACCESS_RIGHTS: WIN32_ERROR = 8344u32; +pub const ERROR_DS_INTERNAL_FAILURE: WIN32_ERROR = 8430u32; +pub const ERROR_DS_INVALID_ATTRIBUTE_SYNTAX: WIN32_ERROR = 8203u32; +pub const ERROR_DS_INVALID_DMD: WIN32_ERROR = 8360u32; +pub const ERROR_DS_INVALID_DN_SYNTAX: WIN32_ERROR = 8242u32; +pub const ERROR_DS_INVALID_GROUP_TYPE: WIN32_ERROR = 8513u32; +pub const ERROR_DS_INVALID_LDAP_DISPLAY_NAME: WIN32_ERROR = 8479u32; +pub const ERROR_DS_INVALID_NAME_FOR_SPN: WIN32_ERROR = 8554u32; +pub const ERROR_DS_INVALID_ROLE_OWNER: WIN32_ERROR = 8366u32; +pub const ERROR_DS_INVALID_SCRIPT: WIN32_ERROR = 8600u32; +pub const ERROR_DS_INVALID_SEARCH_FLAG: WIN32_ERROR = 8500u32; +pub const ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE: WIN32_ERROR = 8626u32; +pub const ERROR_DS_INVALID_SEARCH_FLAG_TUPLE: WIN32_ERROR = 8627u32; +pub const ERROR_DS_IS_LEAF: WIN32_ERROR = 8243u32; +pub const ERROR_DS_KEY_NOT_UNIQUE: WIN32_ERROR = 8527u32; +pub const ERROR_DS_LDAP_SEND_QUEUE_FULL: WIN32_ERROR = 8616u32; +pub const ERROR_DS_LINK_ID_NOT_AVAILABLE: WIN32_ERROR = 8577u32; +pub const ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: WIN32_ERROR = 8520u32; +pub const ERROR_DS_LOCAL_ERROR: WIN32_ERROR = 8251u32; +pub const ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: WIN32_ERROR = 8548u32; +pub const ERROR_DS_LOOP_DETECT: WIN32_ERROR = 8246u32; +pub const ERROR_DS_LOW_ADLDS_FFL: WIN32_ERROR = 8643u32; +pub const ERROR_DS_LOW_DSA_VERSION: WIN32_ERROR = 8568u32; +pub const ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4: WIN32_ERROR = 8572u32; +pub const ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: WIN32_ERROR = 8557u32; +pub const ERROR_DS_MAPI_ID_NOT_AVAILABLE: WIN32_ERROR = 8632u32; +pub const ERROR_DS_MASTERDSA_REQUIRED: WIN32_ERROR = 8314u32; +pub const ERROR_DS_MAX_OBJ_SIZE_EXCEEDED: WIN32_ERROR = 8304u32; +pub const ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY: WIN32_ERROR = 8201u32; +pub const ERROR_DS_MISSING_EXPECTED_ATT: WIN32_ERROR = 8411u32; +pub const ERROR_DS_MISSING_FOREST_TRUST: WIN32_ERROR = 8649u32; +pub const ERROR_DS_MISSING_FSMO_SETTINGS: WIN32_ERROR = 8434u32; +pub const ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER: WIN32_ERROR = 8497u32; +pub const ERROR_DS_MISSING_REQUIRED_ATT: WIN32_ERROR = 8316u32; +pub const ERROR_DS_MISSING_SUPREF: WIN32_ERROR = 8406u32; +pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG: WIN32_ERROR = 8581u32; +pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE: WIN32_ERROR = 8579u32; +pub const ERROR_DS_MODIFYDN_WRONG_GRANDPARENT: WIN32_ERROR = 8582u32; +pub const ERROR_DS_MUST_BE_RUN_ON_DST_DC: WIN32_ERROR = 8558u32; +pub const ERROR_DS_NAME_ERROR_DOMAIN_ONLY: WIN32_ERROR = 8473u32; +pub const ERROR_DS_NAME_ERROR_NOT_FOUND: WIN32_ERROR = 8470u32; +pub const ERROR_DS_NAME_ERROR_NOT_UNIQUE: WIN32_ERROR = 8471u32; +pub const ERROR_DS_NAME_ERROR_NO_MAPPING: WIN32_ERROR = 8472u32; +pub const ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING: WIN32_ERROR = 8474u32; +pub const ERROR_DS_NAME_ERROR_RESOLVING: WIN32_ERROR = 8469u32; +pub const ERROR_DS_NAME_ERROR_TRUST_REFERRAL: WIN32_ERROR = 8583u32; +pub const ERROR_DS_NAME_NOT_UNIQUE: WIN32_ERROR = 8571u32; +pub const ERROR_DS_NAME_REFERENCE_INVALID: WIN32_ERROR = 8373u32; +pub const ERROR_DS_NAME_TOO_LONG: WIN32_ERROR = 8348u32; +pub const ERROR_DS_NAME_TOO_MANY_PARTS: WIN32_ERROR = 8347u32; +pub const ERROR_DS_NAME_TYPE_UNKNOWN: WIN32_ERROR = 8351u32; +pub const ERROR_DS_NAME_UNPARSEABLE: WIN32_ERROR = 8350u32; +pub const ERROR_DS_NAME_VALUE_TOO_LONG: WIN32_ERROR = 8349u32; +pub const ERROR_DS_NAMING_MASTER_GC: WIN32_ERROR = 8523u32; +pub const ERROR_DS_NAMING_VIOLATION: WIN32_ERROR = 8247u32; +pub const ERROR_DS_NCNAME_MISSING_CR_REF: WIN32_ERROR = 8412u32; +pub const ERROR_DS_NCNAME_MUST_BE_NC: WIN32_ERROR = 8357u32; +pub const ERROR_DS_NC_MUST_HAVE_NC_PARENT: WIN32_ERROR = 8494u32; +pub const ERROR_DS_NC_STILL_HAS_DSAS: WIN32_ERROR = 8546u32; +pub const ERROR_DS_NONEXISTENT_MAY_HAVE: WIN32_ERROR = 8387u32; +pub const ERROR_DS_NONEXISTENT_MUST_HAVE: WIN32_ERROR = 8388u32; +pub const ERROR_DS_NONEXISTENT_POSS_SUP: WIN32_ERROR = 8390u32; +pub const ERROR_DS_NONSAFE_SCHEMA_CHANGE: WIN32_ERROR = 8508u32; +pub const ERROR_DS_NON_ASQ_SEARCH: WIN32_ERROR = 8624u32; +pub const ERROR_DS_NON_BASE_SEARCH: WIN32_ERROR = 8480u32; +pub const ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX: WIN32_ERROR = 8377u32; +pub const ERROR_DS_NOT_AN_OBJECT: WIN32_ERROR = 8352u32; +pub const ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC: WIN32_ERROR = 8487u32; +pub const ERROR_DS_NOT_CLOSEST: WIN32_ERROR = 8588u32; +pub const ERROR_DS_NOT_INSTALLED: WIN32_ERROR = 8200u32; +pub const ERROR_DS_NOT_ON_BACKLINK: WIN32_ERROR = 8362u32; +pub const ERROR_DS_NOT_SUPPORTED: WIN32_ERROR = 8256u32; +pub const ERROR_DS_NOT_SUPPORTED_SORT_ORDER: WIN32_ERROR = 8570u32; +pub const ERROR_DS_NO_ATTRIBUTE_OR_VALUE: WIN32_ERROR = 8202u32; +pub const ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN: WIN32_ERROR = 8569u32; +pub const ERROR_DS_NO_CHAINED_EVAL: WIN32_ERROR = 8328u32; +pub const ERROR_DS_NO_CHAINING: WIN32_ERROR = 8327u32; +pub const ERROR_DS_NO_CHECKPOINT_WITH_PDC: WIN32_ERROR = 8551u32; +pub const ERROR_DS_NO_CROSSREF_FOR_NC: WIN32_ERROR = 8363u32; +pub const ERROR_DS_NO_DELETED_NAME: WIN32_ERROR = 8355u32; +pub const ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS: WIN32_ERROR = 8549u32; +pub const ERROR_DS_NO_MORE_RIDS: WIN32_ERROR = 8209u32; +pub const ERROR_DS_NO_MSDS_INTID: WIN32_ERROR = 8596u32; +pub const ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: WIN32_ERROR = 8514u32; +pub const ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: WIN32_ERROR = 8515u32; +pub const ERROR_DS_NO_NTDSA_OBJECT: WIN32_ERROR = 8623u32; +pub const ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC: WIN32_ERROR = 8580u32; +pub const ERROR_DS_NO_PARENT_OBJECT: WIN32_ERROR = 8329u32; +pub const ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION: WIN32_ERROR = 8533u32; +pub const ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA: WIN32_ERROR = 8306u32; +pub const ERROR_DS_NO_REF_DOMAIN: WIN32_ERROR = 8575u32; +pub const ERROR_DS_NO_REQUESTED_ATTS_FOUND: WIN32_ERROR = 8308u32; +pub const ERROR_DS_NO_RESULTS_RETURNED: WIN32_ERROR = 8257u32; +pub const ERROR_DS_NO_RIDS_ALLOCATED: WIN32_ERROR = 8208u32; +pub const ERROR_DS_NO_SERVER_OBJECT: WIN32_ERROR = 8622u32; +pub const ERROR_DS_NO_SUCH_OBJECT: WIN32_ERROR = 8240u32; +pub const ERROR_DS_NO_TREE_DELETE_ABOVE_NC: WIN32_ERROR = 8501u32; +pub const ERROR_DS_NTDSCRIPT_PROCESS_ERROR: WIN32_ERROR = 8592u32; +pub const ERROR_DS_NTDSCRIPT_SYNTAX_ERROR: WIN32_ERROR = 8591u32; +pub const ERROR_DS_OBJECT_BEING_REMOVED: WIN32_ERROR = 8339u32; +pub const ERROR_DS_OBJECT_CLASS_REQUIRED: WIN32_ERROR = 8315u32; +pub const ERROR_DS_OBJECT_RESULTS_TOO_LARGE: WIN32_ERROR = 8248u32; +pub const ERROR_DS_OBJ_CLASS_NOT_DEFINED: WIN32_ERROR = 8371u32; +pub const ERROR_DS_OBJ_CLASS_NOT_SUBCLASS: WIN32_ERROR = 8372u32; +pub const ERROR_DS_OBJ_CLASS_VIOLATION: WIN32_ERROR = 8212u32; +pub const ERROR_DS_OBJ_GUID_EXISTS: WIN32_ERROR = 8361u32; +pub const ERROR_DS_OBJ_NOT_FOUND: WIN32_ERROR = 8333u32; +pub const ERROR_DS_OBJ_STRING_NAME_EXISTS: WIN32_ERROR = 8305u32; +pub const ERROR_DS_OBJ_TOO_LARGE: WIN32_ERROR = 8312u32; +pub const ERROR_DS_OFFSET_RANGE_ERROR: WIN32_ERROR = 8262u32; +pub const ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS: WIN32_ERROR = 8637u32; +pub const ERROR_DS_OID_NOT_FOUND: WIN32_ERROR = 8638u32; +pub const ERROR_DS_OPERATIONS_ERROR: WIN32_ERROR = 8224u32; +pub const ERROR_DS_OUT_OF_SCOPE: WIN32_ERROR = 8338u32; +pub const ERROR_DS_OUT_OF_VERSION_STORE: WIN32_ERROR = 8573u32; +pub const ERROR_DS_PARAM_ERROR: WIN32_ERROR = 8255u32; +pub const ERROR_DS_PARENT_IS_AN_ALIAS: WIN32_ERROR = 8330u32; +pub const ERROR_DS_PDC_OPERATION_IN_PROGRESS: WIN32_ERROR = 8490u32; +pub const ERROR_DS_PER_ATTRIBUTE_AUTHZ_FAILED_DURING_ADD: WIN32_ERROR = 8652u32; +pub const ERROR_DS_POLICY_NOT_KNOWN: WIN32_ERROR = 8618u32; +pub const ERROR_DS_PROTOCOL_ERROR: WIN32_ERROR = 8225u32; +pub const ERROR_DS_RANGE_CONSTRAINT: WIN32_ERROR = 8322u32; +pub const ERROR_DS_RDN_DOESNT_MATCH_SCHEMA: WIN32_ERROR = 8307u32; +pub const ERROR_DS_RECALCSCHEMA_FAILED: WIN32_ERROR = 8396u32; +pub const ERROR_DS_REFERRAL: WIN32_ERROR = 8235u32; +pub const ERROR_DS_REFERRAL_LIMIT_EXCEEDED: WIN32_ERROR = 8260u32; +pub const ERROR_DS_REFUSING_FSMO_ROLES: WIN32_ERROR = 8433u32; +pub const ERROR_DS_REMOTE_CROSSREF_OP_FAILED: WIN32_ERROR = 8601u32; +pub const ERROR_DS_REPLICATOR_ONLY: WIN32_ERROR = 8370u32; +pub const ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR: WIN32_ERROR = 8595u32; +pub const ERROR_DS_REPL_LIFETIME_EXCEEDED: WIN32_ERROR = 8614u32; +pub const ERROR_DS_RESERVED_LINK_ID: WIN32_ERROR = 8576u32; +pub const ERROR_DS_RESERVED_MAPI_ID: WIN32_ERROR = 8631u32; +pub const ERROR_DS_RIDMGR_DISABLED: WIN32_ERROR = 8263u32; +pub const ERROR_DS_RIDMGR_INIT_ERROR: WIN32_ERROR = 8211u32; +pub const ERROR_DS_ROLE_NOT_VERIFIED: WIN32_ERROR = 8610u32; +pub const ERROR_DS_ROOT_CANT_BE_SUBREF: WIN32_ERROR = 8326u32; +pub const ERROR_DS_ROOT_MUST_BE_NC: WIN32_ERROR = 8301u32; +pub const ERROR_DS_ROOT_REQUIRES_CLASS_TOP: WIN32_ERROR = 8432u32; +pub const ERROR_DS_SAM_INIT_FAILURE: WIN32_ERROR = 8504u32; +pub const ERROR_DS_SAM_INIT_FAILURE_CONSOLE: WIN32_ERROR = 8562u32; +pub const ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY: WIN32_ERROR = 8530u32; +pub const ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD: WIN32_ERROR = 8529u32; +pub const ERROR_DS_SCHEMA_ALLOC_FAILED: WIN32_ERROR = 8415u32; +pub const ERROR_DS_SCHEMA_NOT_LOADED: WIN32_ERROR = 8414u32; +pub const ERROR_DS_SCHEMA_UPDATE_DISALLOWED: WIN32_ERROR = 8509u32; +pub const ERROR_DS_SECURITY_CHECKING_ERROR: WIN32_ERROR = 8413u32; +pub const ERROR_DS_SECURITY_ILLEGAL_MODIFY: WIN32_ERROR = 8423u32; +pub const ERROR_DS_SEC_DESC_INVALID: WIN32_ERROR = 8354u32; +pub const ERROR_DS_SEC_DESC_TOO_SHORT: WIN32_ERROR = 8353u32; +pub const ERROR_DS_SEMANTIC_ATT_TEST: WIN32_ERROR = 8383u32; +pub const ERROR_DS_SENSITIVE_GROUP_VIOLATION: WIN32_ERROR = 8505u32; +pub const ERROR_DS_SERVER_DOWN: WIN32_ERROR = 8250u32; +pub const ERROR_DS_SHUTTING_DOWN: WIN32_ERROR = 8364u32; +pub const ERROR_DS_SINGLE_USER_MODE_FAILED: WIN32_ERROR = 8590u32; +pub const ERROR_DS_SINGLE_VALUE_CONSTRAINT: WIN32_ERROR = 8321u32; +pub const ERROR_DS_SIZELIMIT_EXCEEDED: WIN32_ERROR = 8227u32; +pub const ERROR_DS_SORT_CONTROL_MISSING: WIN32_ERROR = 8261u32; +pub const ERROR_DS_SOURCE_AUDITING_NOT_ENABLED: WIN32_ERROR = 8552u32; +pub const ERROR_DS_SOURCE_DOMAIN_IN_FOREST: WIN32_ERROR = 8534u32; +pub const ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST: WIN32_ERROR = 8647u32; +pub const ERROR_DS_SRC_AND_DST_NC_IDENTICAL: WIN32_ERROR = 8485u32; +pub const ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH: WIN32_ERROR = 8540u32; +pub const ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER: WIN32_ERROR = 8559u32; +pub const ERROR_DS_SRC_GUID_MISMATCH: WIN32_ERROR = 8488u32; +pub const ERROR_DS_SRC_NAME_MISMATCH: WIN32_ERROR = 8484u32; +pub const ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER: WIN32_ERROR = 8538u32; +pub const ERROR_DS_SRC_SID_EXISTS_IN_FOREST: WIN32_ERROR = 8539u32; +pub const ERROR_DS_STRING_SD_CONVERSION_FAILED: WIN32_ERROR = 8522u32; +pub const ERROR_DS_STRONG_AUTH_REQUIRED: WIN32_ERROR = 8232u32; +pub const ERROR_DS_SUBREF_MUST_HAVE_PARENT: WIN32_ERROR = 8356u32; +pub const ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD: WIN32_ERROR = 8376u32; +pub const ERROR_DS_SUB_CLS_TEST_FAIL: WIN32_ERROR = 8391u32; +pub const ERROR_DS_SYNTAX_MISMATCH: WIN32_ERROR = 8384u32; +pub const ERROR_DS_THREAD_LIMIT_EXCEEDED: WIN32_ERROR = 8587u32; +pub const ERROR_DS_TIMELIMIT_EXCEEDED: WIN32_ERROR = 8226u32; +pub const ERROR_DS_TREE_DELETE_NOT_FINISHED: WIN32_ERROR = 8397u32; +pub const ERROR_DS_UNABLE_TO_SURRENDER_ROLES: WIN32_ERROR = 8435u32; +pub const ERROR_DS_UNAVAILABLE: WIN32_ERROR = 8207u32; +pub const ERROR_DS_UNAVAILABLE_CRIT_EXTENSION: WIN32_ERROR = 8236u32; +pub const ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED: WIN32_ERROR = 8645u32; +pub const ERROR_DS_UNICODEPWD_NOT_IN_QUOTES: WIN32_ERROR = 8556u32; +pub const ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: WIN32_ERROR = 8518u32; +pub const ERROR_DS_UNKNOWN_ERROR: WIN32_ERROR = 8431u32; +pub const ERROR_DS_UNKNOWN_OPERATION: WIN32_ERROR = 8365u32; +pub const ERROR_DS_UNWILLING_TO_PERFORM: WIN32_ERROR = 8245u32; +pub const ERROR_DS_UPN_VALUE_NOT_UNIQUE_IN_FOREST: WIN32_ERROR = 8648u32; +pub const ERROR_DS_USER_BUFFER_TO_SMALL: WIN32_ERROR = 8309u32; +pub const ERROR_DS_VALUE_KEY_NOT_UNIQUE: WIN32_ERROR = 8650u32; +pub const ERROR_DS_VERSION_CHECK_FAILURE: WIN32_ERROR = 643u32; +pub const ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL: WIN32_ERROR = 8611u32; +pub const ERROR_DS_WRONG_LINKED_ATT_SYNTAX: WIN32_ERROR = 8528u32; +pub const ERROR_DS_WRONG_OM_OBJ_CLASS: WIN32_ERROR = 8476u32; +pub const ERROR_DUPLICATE_PRIVILEGES: WIN32_ERROR = 311u32; +pub const ERROR_DUPLICATE_SERVICE_NAME: WIN32_ERROR = 1078u32; +pub const ERROR_DUP_DOMAINNAME: WIN32_ERROR = 1221u32; +pub const ERROR_DUP_NAME: WIN32_ERROR = 52u32; +pub const ERROR_DYNAMIC_CODE_BLOCKED: WIN32_ERROR = 1655u32; +pub const ERROR_DYNLINK_FROM_INVALID_RING: WIN32_ERROR = 196u32; +pub const ERROR_EAS_DIDNT_FIT: WIN32_ERROR = 275u32; +pub const ERROR_EAS_NOT_SUPPORTED: WIN32_ERROR = 282u32; +pub const ERROR_EA_ACCESS_DENIED: WIN32_ERROR = 994u32; +pub const ERROR_EA_FILE_CORRUPT: WIN32_ERROR = 276u32; +pub const ERROR_EA_LIST_INCONSISTENT: WIN32_ERROR = 255u32; +pub const ERROR_EA_TABLE_FULL: WIN32_ERROR = 277u32; +pub const ERROR_EDP_DPL_POLICY_CANT_BE_SATISFIED: WIN32_ERROR = 357u32; +pub const ERROR_EDP_POLICY_DENIES_OPERATION: WIN32_ERROR = 356u32; +pub const ERROR_EFS_ALG_BLOB_TOO_BIG: WIN32_ERROR = 6013u32; +pub const ERROR_EFS_DISABLED: WIN32_ERROR = 6015u32; +pub const ERROR_EFS_SERVER_NOT_TRUSTED: WIN32_ERROR = 6011u32; +pub const ERROR_EFS_VERSION_NOT_SUPPORT: WIN32_ERROR = 6016u32; +pub const ERROR_ELEVATION_REQUIRED: WIN32_ERROR = 740u32; +pub const ERROR_ENCLAVE_FAILURE: WIN32_ERROR = 349u32; +pub const ERROR_ENCLAVE_NOT_TERMINATED: WIN32_ERROR = 814u32; +pub const ERROR_ENCLAVE_VIOLATION: WIN32_ERROR = 815u32; +pub const ERROR_ENCRYPTED_FILE_NOT_SUPPORTED: WIN32_ERROR = 489u32; +pub const ERROR_ENCRYPTED_IO_NOT_POSSIBLE: WIN32_ERROR = 808u32; +pub const ERROR_ENCRYPTING_METADATA_DISALLOWED: WIN32_ERROR = 431u32; +pub const ERROR_ENCRYPTION_DISABLED: WIN32_ERROR = 430u32; +pub const ERROR_ENCRYPTION_FAILED: WIN32_ERROR = 6000u32; +pub const ERROR_ENCRYPTION_POLICY_DENIES_OPERATION: WIN32_ERROR = 6022u32; +pub const ERROR_END_OF_MEDIA: WIN32_ERROR = 1100u32; +pub const ERROR_ENVVAR_NOT_FOUND: WIN32_ERROR = 203u32; +pub const ERROR_EOM_OVERFLOW: WIN32_ERROR = 1129u32; +pub const ERROR_ERRORS_ENCOUNTERED: WIN32_ERROR = 774u32; +pub const ERROR_EVALUATION_EXPIRATION: WIN32_ERROR = 622u32; +pub const ERROR_EVENTLOG_CANT_START: WIN32_ERROR = 1501u32; +pub const ERROR_EVENTLOG_FILE_CHANGED: WIN32_ERROR = 1503u32; +pub const ERROR_EVENTLOG_FILE_CORRUPT: WIN32_ERROR = 1500u32; +pub const ERROR_EVENT_DONE: WIN32_ERROR = 710u32; +pub const ERROR_EVENT_PENDING: WIN32_ERROR = 711u32; +pub const ERROR_EXCEPTION_IN_SERVICE: WIN32_ERROR = 1064u32; +pub const ERROR_EXCL_SEM_ALREADY_OWNED: WIN32_ERROR = 101u32; +pub const ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY: WIN32_ERROR = 217u32; +pub const ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY: WIN32_ERROR = 218u32; +pub const ERROR_EXE_MACHINE_TYPE_MISMATCH: WIN32_ERROR = 216u32; +pub const ERROR_EXE_MARKED_INVALID: WIN32_ERROR = 192u32; +pub const ERROR_EXTENDED_ERROR: WIN32_ERROR = 1208u32; +pub const ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN: WIN32_ERROR = 343u32; +pub const ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED: WIN32_ERROR = 399u32; +pub const ERROR_EXTRANEOUS_INFORMATION: WIN32_ERROR = 677u32; +pub const ERROR_FAILED_DRIVER_ENTRY: WIN32_ERROR = 647u32; +pub const ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: WIN32_ERROR = 1063u32; +pub const ERROR_FAIL_FAST_EXCEPTION: WIN32_ERROR = 1653u32; +pub const ERROR_FAIL_I24: WIN32_ERROR = 83u32; +pub const ERROR_FAIL_NOACTION_REBOOT: WIN32_ERROR = 350u32; +pub const ERROR_FAIL_RESTART: WIN32_ERROR = 352u32; +pub const ERROR_FAIL_SHUTDOWN: WIN32_ERROR = 351u32; +pub const ERROR_FATAL_APP_EXIT: WIN32_ERROR = 713u32; +pub const ERROR_FILEMARK_DETECTED: WIN32_ERROR = 1101u32; +pub const ERROR_FILENAME_EXCED_RANGE: WIN32_ERROR = 206u32; +pub const ERROR_FILE_CHECKED_OUT: WIN32_ERROR = 220u32; +pub const ERROR_FILE_CORRUPT: WIN32_ERROR = 1392u32; +pub const ERROR_FILE_ENCRYPTED: WIN32_ERROR = 6002u32; +pub const ERROR_FILE_EXISTS: WIN32_ERROR = 80u32; +pub const ERROR_FILE_HANDLE_REVOKED: WIN32_ERROR = 806u32; +pub const ERROR_FILE_INVALID: WIN32_ERROR = 1006u32; +pub const ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED: WIN32_ERROR = 326u32; +pub const ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS: WIN32_ERROR = 809u32; +pub const ERROR_FILE_NOT_ENCRYPTED: WIN32_ERROR = 6007u32; +pub const ERROR_FILE_NOT_FOUND: WIN32_ERROR = 2u32; +pub const ERROR_FILE_NOT_SUPPORTED: WIN32_ERROR = 425u32; +pub const ERROR_FILE_OFFLINE: WIN32_ERROR = 4350u32; +pub const ERROR_FILE_PROTECTED_UNDER_DPL: WIN32_ERROR = 406u32; +pub const ERROR_FILE_READ_ONLY: WIN32_ERROR = 6009u32; +pub const ERROR_FILE_SNAP_INVALID_PARAMETER: WIN32_ERROR = 440u32; +pub const ERROR_FILE_SNAP_IN_PROGRESS: WIN32_ERROR = 435u32; +pub const ERROR_FILE_SNAP_IO_NOT_COORDINATED: WIN32_ERROR = 438u32; +pub const ERROR_FILE_SNAP_MODIFY_NOT_SUPPORTED: WIN32_ERROR = 437u32; +pub const ERROR_FILE_SNAP_UNEXPECTED_ERROR: WIN32_ERROR = 439u32; +pub const ERROR_FILE_SNAP_USER_SECTION_NOT_SUPPORTED: WIN32_ERROR = 436u32; +pub const ERROR_FILE_SYSTEM_LIMITATION: WIN32_ERROR = 665u32; +pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_BUSY: WIN32_ERROR = 371u32; +pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION: WIN32_ERROR = 385u32; +pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_METADATA_CORRUPT: WIN32_ERROR = 370u32; +pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_PROVIDER_UNKNOWN: WIN32_ERROR = 372u32; +pub const ERROR_FILE_SYSTEM_VIRTUALIZATION_UNAVAILABLE: WIN32_ERROR = 369u32; +pub const ERROR_FILE_TOO_LARGE: WIN32_ERROR = 223u32; +pub const ERROR_FIRMWARE_UPDATED: WIN32_ERROR = 728u32; +pub const ERROR_FLOAT_MULTIPLE_FAULTS: WIN32_ERROR = 630u32; +pub const ERROR_FLOAT_MULTIPLE_TRAPS: WIN32_ERROR = 631u32; +pub const ERROR_FLOPPY_BAD_REGISTERS: WIN32_ERROR = 1125u32; +pub const ERROR_FLOPPY_ID_MARK_NOT_FOUND: WIN32_ERROR = 1122u32; +pub const ERROR_FLOPPY_UNKNOWN_ERROR: WIN32_ERROR = 1124u32; +pub const ERROR_FLOPPY_VOLUME: WIN32_ERROR = 584u32; +pub const ERROR_FLOPPY_WRONG_CYLINDER: WIN32_ERROR = 1123u32; +pub const ERROR_FORMS_AUTH_REQUIRED: WIN32_ERROR = 224u32; +pub const ERROR_FOUND_OUT_OF_SCOPE: WIN32_ERROR = 601u32; +pub const ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY: WIN32_ERROR = 762u32; +pub const ERROR_FS_DRIVER_REQUIRED: WIN32_ERROR = 588u32; +pub const ERROR_FS_METADATA_INCONSISTENT: WIN32_ERROR = 510u32; +pub const ERROR_FT_DI_SCAN_REQUIRED: WIN32_ERROR = 339u32; +pub const ERROR_FT_READ_FAILURE: WIN32_ERROR = 415u32; +pub const ERROR_FT_READ_FROM_COPY_FAILURE: WIN32_ERROR = 818u32; +pub const ERROR_FT_READ_RECOVERY_FROM_BACKUP: WIN32_ERROR = 704u32; +pub const ERROR_FT_WRITE_FAILURE: WIN32_ERROR = 338u32; +pub const ERROR_FT_WRITE_RECOVERY: WIN32_ERROR = 705u32; +pub const ERROR_FULLSCREEN_MODE: WIN32_ERROR = 1007u32; +pub const ERROR_FUNCTION_FAILED: WIN32_ERROR = 1627u32; +pub const ERROR_FUNCTION_NOT_CALLED: WIN32_ERROR = 1626u32; +pub const ERROR_GDI_HANDLE_LEAK: WIN32_ERROR = 373u32; +pub const ERROR_GENERIC_NOT_MAPPED: WIN32_ERROR = 1360u32; +pub const ERROR_GEN_FAILURE: WIN32_ERROR = 31u32; +pub const ERROR_GLOBAL_ONLY_HOOK: WIN32_ERROR = 1429u32; +pub const ERROR_GRACEFUL_DISCONNECT: WIN32_ERROR = 1226u32; +pub const ERROR_GROUP_EXISTS: WIN32_ERROR = 1318u32; +pub const ERROR_GUID_SUBSTITUTION_MADE: WIN32_ERROR = 680u32; +pub const ERROR_HANDLES_CLOSED: WIN32_ERROR = 676u32; +pub const ERROR_HANDLE_DISK_FULL: WIN32_ERROR = 39u32; +pub const ERROR_HANDLE_EOF: WIN32_ERROR = 38u32; +pub const ERROR_HANDLE_REVOKED: WIN32_ERROR = 811u32; +pub const ERROR_HAS_SYSTEM_CRITICAL_FILES: WIN32_ERROR = 488u32; +pub const ERROR_HIBERNATED: WIN32_ERROR = 726u32; +pub const ERROR_HIBERNATION_FAILURE: WIN32_ERROR = 656u32; +pub const ERROR_HOOK_NEEDS_HMOD: WIN32_ERROR = 1428u32; +pub const ERROR_HOOK_NOT_INSTALLED: WIN32_ERROR = 1431u32; +pub const ERROR_HOOK_TYPE_NOT_ALLOWED: WIN32_ERROR = 1458u32; +pub const ERROR_HOST_DOWN: WIN32_ERROR = 1256u32; +pub const ERROR_HOST_UNREACHABLE: WIN32_ERROR = 1232u32; +pub const ERROR_HOTKEY_ALREADY_REGISTERED: WIN32_ERROR = 1409u32; +pub const ERROR_HOTKEY_NOT_REGISTERED: WIN32_ERROR = 1419u32; +pub const ERROR_HWNDS_HAVE_DIFF_PARENT: WIN32_ERROR = 1441u32; +pub const ERROR_ILLEGAL_CHARACTER: WIN32_ERROR = 582u32; +pub const ERROR_ILLEGAL_DLL_RELOCATION: WIN32_ERROR = 623u32; +pub const ERROR_ILLEGAL_ELEMENT_ADDRESS: WIN32_ERROR = 1162u32; +pub const ERROR_ILLEGAL_FLOAT_CONTEXT: WIN32_ERROR = 579u32; +pub const ERROR_ILL_FORMED_PASSWORD: WIN32_ERROR = 1324u32; +pub const ERROR_IMAGE_AT_DIFFERENT_BASE: WIN32_ERROR = 807u32; +pub const ERROR_IMAGE_MACHINE_TYPE_MISMATCH: WIN32_ERROR = 706u32; +pub const ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE: WIN32_ERROR = 720u32; +pub const ERROR_IMAGE_NOT_AT_BASE: WIN32_ERROR = 700u32; +pub const ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT: WIN32_ERROR = 308u32; +pub const ERROR_IMPLEMENTATION_LIMIT: WIN32_ERROR = 1292u32; +pub const ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE: WIN32_ERROR = 1297u32; +pub const ERROR_INCOMPATIBLE_SERVICE_SID_TYPE: WIN32_ERROR = 1290u32; +pub const ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING: WIN32_ERROR = 304u32; +pub const ERROR_INCORRECT_ACCOUNT_TYPE: WIN32_ERROR = 8646u32; +pub const ERROR_INCORRECT_ADDRESS: WIN32_ERROR = 1241u32; +pub const ERROR_INCORRECT_SIZE: WIN32_ERROR = 1462u32; +pub const ERROR_INDEX_ABSENT: WIN32_ERROR = 1611u32; +pub const ERROR_INDEX_OUT_OF_BOUNDS: WIN32_ERROR = 474u32; +pub const ERROR_INFLOOP_IN_RELOC_CHAIN: WIN32_ERROR = 202u32; +pub const ERROR_INSTALL_ALREADY_RUNNING: WIN32_ERROR = 1618u32; +pub const ERROR_INSTALL_FAILURE: WIN32_ERROR = 1603u32; +pub const ERROR_INSTALL_LANGUAGE_UNSUPPORTED: WIN32_ERROR = 1623u32; +pub const ERROR_INSTALL_LOG_FAILURE: WIN32_ERROR = 1622u32; +pub const ERROR_INSTALL_NOTUSED: WIN32_ERROR = 1634u32; +pub const ERROR_INSTALL_PACKAGE_INVALID: WIN32_ERROR = 1620u32; +pub const ERROR_INSTALL_PACKAGE_OPEN_FAILED: WIN32_ERROR = 1619u32; +pub const ERROR_INSTALL_PACKAGE_REJECTED: WIN32_ERROR = 1625u32; +pub const ERROR_INSTALL_PACKAGE_VERSION: WIN32_ERROR = 1613u32; +pub const ERROR_INSTALL_PLATFORM_UNSUPPORTED: WIN32_ERROR = 1633u32; +pub const ERROR_INSTALL_REJECTED: WIN32_ERROR = 1654u32; +pub const ERROR_INSTALL_REMOTE_DISALLOWED: WIN32_ERROR = 1640u32; +pub const ERROR_INSTALL_REMOTE_PROHIBITED: WIN32_ERROR = 1645u32; +pub const ERROR_INSTALL_SERVICE_FAILURE: WIN32_ERROR = 1601u32; +pub const ERROR_INSTALL_SERVICE_SAFEBOOT: WIN32_ERROR = 1652u32; +pub const ERROR_INSTALL_SOURCE_ABSENT: WIN32_ERROR = 1612u32; +pub const ERROR_INSTALL_SUSPEND: WIN32_ERROR = 1604u32; +pub const ERROR_INSTALL_TEMP_UNWRITABLE: WIN32_ERROR = 1632u32; +pub const ERROR_INSTALL_TRANSFORM_FAILURE: WIN32_ERROR = 1624u32; +pub const ERROR_INSTALL_TRANSFORM_REJECTED: WIN32_ERROR = 1644u32; +pub const ERROR_INSTALL_UI_FAILURE: WIN32_ERROR = 1621u32; +pub const ERROR_INSTALL_USEREXIT: WIN32_ERROR = 1602u32; +pub const ERROR_INSTRUCTION_MISALIGNMENT: WIN32_ERROR = 549u32; +pub const ERROR_INSUFFICIENT_BUFFER: WIN32_ERROR = 122u32; +pub const ERROR_INSUFFICIENT_LOGON_INFO: WIN32_ERROR = 608u32; +pub const ERROR_INSUFFICIENT_POWER: WIN32_ERROR = 639u32; +pub const ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE: WIN32_ERROR = 781u32; +pub const ERROR_INSUFFICIENT_VIRTUAL_ADDR_RESOURCES: WIN32_ERROR = 473u32; +pub const ERROR_INTERMIXED_KERNEL_EA_OPERATION: WIN32_ERROR = 324u32; +pub const ERROR_INTERNAL_DB_CORRUPTION: WIN32_ERROR = 1358u32; +pub const ERROR_INTERNAL_DB_ERROR: WIN32_ERROR = 1383u32; +pub const ERROR_INTERNAL_ERROR: WIN32_ERROR = 1359u32; +pub const ERROR_INTERRUPT_STILL_CONNECTED: WIN32_ERROR = 764u32; +pub const ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED: WIN32_ERROR = 763u32; +pub const ERROR_INVALID_ACCEL_HANDLE: WIN32_ERROR = 1403u32; +pub const ERROR_INVALID_ACCESS: WIN32_ERROR = 12u32; +pub const ERROR_INVALID_ACCOUNT_NAME: WIN32_ERROR = 1315u32; +pub const ERROR_INVALID_ACE_CONDITION: WIN32_ERROR = 805u32; +pub const ERROR_INVALID_ACL: WIN32_ERROR = 1336u32; +pub const ERROR_INVALID_ADDRESS: WIN32_ERROR = 487u32; +pub const ERROR_INVALID_AT_INTERRUPT_TIME: WIN32_ERROR = 104u32; +pub const ERROR_INVALID_BLOCK: WIN32_ERROR = 9u32; +pub const ERROR_INVALID_BLOCK_LENGTH: WIN32_ERROR = 1106u32; +pub const ERROR_INVALID_CAP: WIN32_ERROR = 320u32; +pub const ERROR_INVALID_CATEGORY: WIN32_ERROR = 117u32; +pub const ERROR_INVALID_COMBOBOX_MESSAGE: WIN32_ERROR = 1422u32; +pub const ERROR_INVALID_COMMAND_LINE: WIN32_ERROR = 1639u32; +pub const ERROR_INVALID_COMPUTERNAME: WIN32_ERROR = 1210u32; +pub const ERROR_INVALID_CRUNTIME_PARAMETER: WIN32_ERROR = 1288u32; +pub const ERROR_INVALID_CURSOR_HANDLE: WIN32_ERROR = 1402u32; +pub const ERROR_INVALID_DATA: WIN32_ERROR = 13u32; +pub const ERROR_INVALID_DATATYPE: WIN32_ERROR = 1804u32; +pub const ERROR_INVALID_DEVICE_OBJECT_PARAMETER: WIN32_ERROR = 650u32; +pub const ERROR_INVALID_DLL: WIN32_ERROR = 1154u32; +pub const ERROR_INVALID_DOMAINNAME: WIN32_ERROR = 1212u32; +pub const ERROR_INVALID_DOMAIN_ROLE: WIN32_ERROR = 1354u32; +pub const ERROR_INVALID_DOMAIN_STATE: WIN32_ERROR = 1353u32; +pub const ERROR_INVALID_DRIVE: WIN32_ERROR = 15u32; +pub const ERROR_INVALID_DWP_HANDLE: WIN32_ERROR = 1405u32; +pub const ERROR_INVALID_EA_HANDLE: WIN32_ERROR = 278u32; +pub const ERROR_INVALID_EA_NAME: WIN32_ERROR = 254u32; +pub const ERROR_INVALID_EDIT_HEIGHT: WIN32_ERROR = 1424u32; +pub const ERROR_INVALID_ENVIRONMENT: WIN32_ERROR = 1805u32; +pub const ERROR_INVALID_EVENTNAME: WIN32_ERROR = 1211u32; +pub const ERROR_INVALID_EVENT_COUNT: WIN32_ERROR = 151u32; +pub const ERROR_INVALID_EXCEPTION_HANDLER: WIN32_ERROR = 310u32; +pub const ERROR_INVALID_EXE_SIGNATURE: WIN32_ERROR = 191u32; +pub const ERROR_INVALID_FIELD: WIN32_ERROR = 1616u32; +pub const ERROR_INVALID_FIELD_IN_PARAMETER_LIST: WIN32_ERROR = 328u32; +pub const ERROR_INVALID_FILTER_PROC: WIN32_ERROR = 1427u32; +pub const ERROR_INVALID_FLAGS: WIN32_ERROR = 1004u32; +pub const ERROR_INVALID_FLAG_NUMBER: WIN32_ERROR = 186u32; +pub const ERROR_INVALID_FORM_NAME: WIN32_ERROR = 1902u32; +pub const ERROR_INVALID_FORM_SIZE: WIN32_ERROR = 1903u32; +pub const ERROR_INVALID_FUNCTION: WIN32_ERROR = 1u32; +pub const ERROR_INVALID_GROUPNAME: WIN32_ERROR = 1209u32; +pub const ERROR_INVALID_GROUP_ATTRIBUTES: WIN32_ERROR = 1345u32; +pub const ERROR_INVALID_GW_COMMAND: WIN32_ERROR = 1443u32; +pub const ERROR_INVALID_HANDLE: WIN32_ERROR = 6u32; +pub const ERROR_INVALID_HANDLE_STATE: WIN32_ERROR = 1609u32; +pub const ERROR_INVALID_HOOK_FILTER: WIN32_ERROR = 1426u32; +pub const ERROR_INVALID_HOOK_HANDLE: WIN32_ERROR = 1404u32; +pub const ERROR_INVALID_HW_PROFILE: WIN32_ERROR = 619u32; +pub const ERROR_INVALID_ICON_HANDLE: WIN32_ERROR = 1414u32; +pub const ERROR_INVALID_ID_AUTHORITY: WIN32_ERROR = 1343u32; +pub const ERROR_INVALID_IMAGE_HASH: WIN32_ERROR = 577u32; +pub const ERROR_INVALID_IMPORT_OF_NON_DLL: WIN32_ERROR = 1276u32; +pub const ERROR_INVALID_INDEX: WIN32_ERROR = 1413u32; +pub const ERROR_INVALID_KERNEL_INFO_VERSION: WIN32_ERROR = 340u32; +pub const ERROR_INVALID_KEYBOARD_HANDLE: WIN32_ERROR = 1457u32; +pub const ERROR_INVALID_LABEL: WIN32_ERROR = 1299u32; +pub const ERROR_INVALID_LB_MESSAGE: WIN32_ERROR = 1432u32; +pub const ERROR_INVALID_LDT_DESCRIPTOR: WIN32_ERROR = 564u32; +pub const ERROR_INVALID_LDT_OFFSET: WIN32_ERROR = 563u32; +pub const ERROR_INVALID_LDT_SIZE: WIN32_ERROR = 561u32; +pub const ERROR_INVALID_LEVEL: WIN32_ERROR = 124u32; +pub const ERROR_INVALID_LIST_FORMAT: WIN32_ERROR = 153u32; +pub const ERROR_INVALID_LOCK_RANGE: WIN32_ERROR = 307u32; +pub const ERROR_INVALID_LOGON_HOURS: WIN32_ERROR = 1328u32; +pub const ERROR_INVALID_LOGON_TYPE: WIN32_ERROR = 1367u32; +pub const ERROR_INVALID_MEMBER: WIN32_ERROR = 1388u32; +pub const ERROR_INVALID_MENU_HANDLE: WIN32_ERROR = 1401u32; +pub const ERROR_INVALID_MESSAGE: WIN32_ERROR = 1002u32; +pub const ERROR_INVALID_MESSAGEDEST: WIN32_ERROR = 1218u32; +pub const ERROR_INVALID_MESSAGENAME: WIN32_ERROR = 1217u32; +pub const ERROR_INVALID_MINALLOCSIZE: WIN32_ERROR = 195u32; +pub const ERROR_INVALID_MODULETYPE: WIN32_ERROR = 190u32; +pub const ERROR_INVALID_MONITOR_HANDLE: WIN32_ERROR = 1461u32; +pub const ERROR_INVALID_MSGBOX_STYLE: WIN32_ERROR = 1438u32; +pub const ERROR_INVALID_NAME: WIN32_ERROR = 123u32; +pub const ERROR_INVALID_NETNAME: WIN32_ERROR = 1214u32; +pub const ERROR_INVALID_OPLOCK_PROTOCOL: WIN32_ERROR = 301u32; +pub const ERROR_INVALID_ORDINAL: WIN32_ERROR = 182u32; +pub const ERROR_INVALID_OWNER: WIN32_ERROR = 1307u32; +pub const ERROR_INVALID_PACKAGE_SID_LENGTH: WIN32_ERROR = 4253u32; +pub const ERROR_INVALID_PARAMETER: WIN32_ERROR = 87u32; +pub const ERROR_INVALID_PASSWORD: WIN32_ERROR = 86u32; +pub const ERROR_INVALID_PASSWORDNAME: WIN32_ERROR = 1216u32; +pub const ERROR_INVALID_PATCH_XML: WIN32_ERROR = 1650u32; +pub const ERROR_INVALID_PEP_INFO_VERSION: WIN32_ERROR = 341u32; +pub const ERROR_INVALID_PLUGPLAY_DEVICE_PATH: WIN32_ERROR = 620u32; +pub const ERROR_INVALID_PORT_ATTRIBUTES: WIN32_ERROR = 545u32; +pub const ERROR_INVALID_PRIMARY_GROUP: WIN32_ERROR = 1308u32; +pub const ERROR_INVALID_PRINTER_COMMAND: WIN32_ERROR = 1803u32; +pub const ERROR_INVALID_PRINTER_NAME: WIN32_ERROR = 1801u32; +pub const ERROR_INVALID_PRINTER_STATE: WIN32_ERROR = 1906u32; +pub const ERROR_INVALID_PRIORITY: WIN32_ERROR = 1800u32; +pub const ERROR_INVALID_QUOTA_LOWER: WIN32_ERROR = 547u32; +pub const ERROR_INVALID_REPARSE_DATA: WIN32_ERROR = 4392u32; +pub const ERROR_INVALID_SCROLLBAR_RANGE: WIN32_ERROR = 1448u32; +pub const ERROR_INVALID_SECURITY_DESCR: WIN32_ERROR = 1338u32; +pub const ERROR_INVALID_SEGDPL: WIN32_ERROR = 198u32; +pub const ERROR_INVALID_SEGMENT_NUMBER: WIN32_ERROR = 180u32; +pub const ERROR_INVALID_SEPARATOR_FILE: WIN32_ERROR = 1799u32; +pub const ERROR_INVALID_SERVER_STATE: WIN32_ERROR = 1352u32; +pub const ERROR_INVALID_SERVICENAME: WIN32_ERROR = 1213u32; +pub const ERROR_INVALID_SERVICE_ACCOUNT: WIN32_ERROR = 1057u32; +pub const ERROR_INVALID_SERVICE_CONTROL: WIN32_ERROR = 1052u32; +pub const ERROR_INVALID_SERVICE_LOCK: WIN32_ERROR = 1071u32; +pub const ERROR_INVALID_SHARENAME: WIN32_ERROR = 1215u32; +pub const ERROR_INVALID_SHOWWIN_COMMAND: WIN32_ERROR = 1449u32; +pub const ERROR_INVALID_SID: WIN32_ERROR = 1337u32; +pub const ERROR_INVALID_SIGNAL_NUMBER: WIN32_ERROR = 209u32; +pub const ERROR_INVALID_SPI_VALUE: WIN32_ERROR = 1439u32; +pub const ERROR_INVALID_STACKSEG: WIN32_ERROR = 189u32; +pub const ERROR_INVALID_STARTING_CODESEG: WIN32_ERROR = 188u32; +pub const ERROR_INVALID_SUB_AUTHORITY: WIN32_ERROR = 1335u32; +pub const ERROR_INVALID_TABLE: WIN32_ERROR = 1628u32; +pub const ERROR_INVALID_TARGET_HANDLE: WIN32_ERROR = 114u32; +pub const ERROR_INVALID_TASK_INDEX: WIN32_ERROR = 1551u32; +pub const ERROR_INVALID_TASK_NAME: WIN32_ERROR = 1550u32; +pub const ERROR_INVALID_THREAD_ID: WIN32_ERROR = 1444u32; +pub const ERROR_INVALID_TIME: WIN32_ERROR = 1901u32; +pub const ERROR_INVALID_TOKEN: WIN32_ERROR = 315u32; +pub const ERROR_INVALID_UNWIND_TARGET: WIN32_ERROR = 544u32; +pub const ERROR_INVALID_USER_BUFFER: WIN32_ERROR = 1784u32; +pub const ERROR_INVALID_USER_PRINCIPAL_NAME: WIN32_ERROR = 8636u32; +pub const ERROR_INVALID_VARIANT: WIN32_ERROR = 604u32; +pub const ERROR_INVALID_VERIFY_SWITCH: WIN32_ERROR = 118u32; +pub const ERROR_INVALID_WINDOW_HANDLE: WIN32_ERROR = 1400u32; +pub const ERROR_INVALID_WORKSTATION: WIN32_ERROR = 1329u32; +pub const ERROR_IOPL_NOT_ENABLED: WIN32_ERROR = 197u32; +pub const ERROR_IO_DEVICE: WIN32_ERROR = 1117u32; +pub const ERROR_IO_INCOMPLETE: WIN32_ERROR = 996u32; +pub const ERROR_IO_PENDING: WIN32_ERROR = 997u32; +pub const ERROR_IO_PRIVILEGE_FAILED: WIN32_ERROR = 571u32; +pub const ERROR_IO_REISSUE_AS_CACHED: WIN32_ERROR = 3950u32; +pub const ERROR_IPSEC_IKE_TIMED_OUT: WIN32_ERROR = 13805u32; +pub const ERROR_IP_ADDRESS_CONFLICT1: WIN32_ERROR = 611u32; +pub const ERROR_IP_ADDRESS_CONFLICT2: WIN32_ERROR = 612u32; +pub const ERROR_IRQ_BUSY: WIN32_ERROR = 1119u32; +pub const ERROR_IS_JOINED: WIN32_ERROR = 134u32; +pub const ERROR_IS_JOIN_PATH: WIN32_ERROR = 147u32; +pub const ERROR_IS_JOIN_TARGET: WIN32_ERROR = 133u32; +pub const ERROR_IS_SUBSTED: WIN32_ERROR = 135u32; +pub const ERROR_IS_SUBST_PATH: WIN32_ERROR = 146u32; +pub const ERROR_IS_SUBST_TARGET: WIN32_ERROR = 149u32; +pub const ERROR_ITERATED_DATA_EXCEEDS_64k: WIN32_ERROR = 194u32; +pub const ERROR_JOB_NO_CONTAINER: WIN32_ERROR = 1505u32; +pub const ERROR_JOIN_TO_JOIN: WIN32_ERROR = 138u32; +pub const ERROR_JOIN_TO_SUBST: WIN32_ERROR = 140u32; +pub const ERROR_JOURNAL_DELETE_IN_PROGRESS: WIN32_ERROR = 1178u32; +pub const ERROR_JOURNAL_ENTRY_DELETED: WIN32_ERROR = 1181u32; +pub const ERROR_JOURNAL_HOOK_SET: WIN32_ERROR = 1430u32; +pub const ERROR_JOURNAL_NOT_ACTIVE: WIN32_ERROR = 1179u32; +pub const ERROR_KERNEL_APC: WIN32_ERROR = 738u32; +pub const ERROR_KEY_DELETED: WIN32_ERROR = 1018u32; +pub const ERROR_KEY_HAS_CHILDREN: WIN32_ERROR = 1020u32; +pub const ERROR_KM_DRIVER_BLOCKED: WIN32_ERROR = 1930u32; +pub const ERROR_LABEL_TOO_LONG: WIN32_ERROR = 154u32; +pub const ERROR_LAST_ADMIN: WIN32_ERROR = 1322u32; +pub const ERROR_LB_WITHOUT_TABSTOPS: WIN32_ERROR = 1434u32; +pub const ERROR_LICENSE_QUOTA_EXCEEDED: WIN32_ERROR = 1395u32; +pub const ERROR_LINUX_SUBSYSTEM_NOT_PRESENT: WIN32_ERROR = 414u32; +pub const ERROR_LINUX_SUBSYSTEM_UPDATE_REQUIRED: WIN32_ERROR = 444u32; +pub const ERROR_LISTBOX_ID_NOT_FOUND: WIN32_ERROR = 1416u32; +pub const ERROR_LM_CROSS_ENCRYPTION_REQUIRED: WIN32_ERROR = 1390u32; +pub const ERROR_LOCAL_POLICY_MODIFICATION_NOT_SUPPORTED: WIN32_ERROR = 8653u32; +pub const ERROR_LOCAL_USER_SESSION_KEY: WIN32_ERROR = 1303u32; +pub const ERROR_LOCKED: WIN32_ERROR = 212u32; +pub const ERROR_LOCK_FAILED: WIN32_ERROR = 167u32; +pub const ERROR_LOCK_VIOLATION: WIN32_ERROR = 33u32; +pub const ERROR_LOGIN_TIME_RESTRICTION: WIN32_ERROR = 1239u32; +pub const ERROR_LOGIN_WKSTA_RESTRICTION: WIN32_ERROR = 1240u32; +pub const ERROR_LOGON_FAILURE: WIN32_ERROR = 1326u32; +pub const ERROR_LOGON_NOT_GRANTED: WIN32_ERROR = 1380u32; +pub const ERROR_LOGON_SERVER_CONFLICT: WIN32_ERROR = 568u32; +pub const ERROR_LOGON_SESSION_COLLISION: WIN32_ERROR = 1366u32; +pub const ERROR_LOGON_SESSION_EXISTS: WIN32_ERROR = 1363u32; +pub const ERROR_LOGON_TYPE_NOT_GRANTED: WIN32_ERROR = 1385u32; +pub const ERROR_LOG_FILE_FULL: WIN32_ERROR = 1502u32; +pub const ERROR_LOG_HARD_ERROR: WIN32_ERROR = 718u32; +pub const ERROR_LONGJUMP: WIN32_ERROR = 682u32; +pub const ERROR_LOST_MODE_LOGON_RESTRICTION: WIN32_ERROR = 1939u32; +pub const ERROR_LOST_WRITEBEHIND_DATA: WIN32_ERROR = 596u32; +pub const ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR: WIN32_ERROR = 790u32; +pub const ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED: WIN32_ERROR = 788u32; +pub const ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR: WIN32_ERROR = 789u32; +pub const ERROR_LUIDS_EXHAUSTED: WIN32_ERROR = 1334u32; +pub const ERROR_MACHINE_LOCKED: WIN32_ERROR = 1271u32; +pub const ERROR_MAGAZINE_NOT_PRESENT: WIN32_ERROR = 1163u32; +pub const ERROR_MAPPED_ALIGNMENT: WIN32_ERROR = 1132u32; +pub const ERROR_MARKED_TO_DISALLOW_WRITES: WIN32_ERROR = 348u32; +pub const ERROR_MARSHALL_OVERFLOW: WIN32_ERROR = 603u32; +pub const ERROR_MAX_SESSIONS_REACHED: WIN32_ERROR = 353u32; +pub const ERROR_MAX_THRDS_REACHED: WIN32_ERROR = 164u32; +pub const ERROR_MCA_EXCEPTION: WIN32_ERROR = 784u32; +pub const ERROR_MCA_OCCURED: WIN32_ERROR = 651u32; +pub const ERROR_MEDIA_CHANGED: WIN32_ERROR = 1110u32; +pub const ERROR_MEDIA_CHECK: WIN32_ERROR = 679u32; +pub const ERROR_MEMBERS_PRIMARY_GROUP: WIN32_ERROR = 1374u32; +pub const ERROR_MEMBER_IN_ALIAS: WIN32_ERROR = 1378u32; +pub const ERROR_MEMBER_IN_GROUP: WIN32_ERROR = 1320u32; +pub const ERROR_MEMBER_NOT_IN_ALIAS: WIN32_ERROR = 1377u32; +pub const ERROR_MEMBER_NOT_IN_GROUP: WIN32_ERROR = 1321u32; +pub const ERROR_MEMORY_HARDWARE: WIN32_ERROR = 779u32; +pub const ERROR_MENU_ITEM_NOT_FOUND: WIN32_ERROR = 1456u32; +pub const ERROR_MESSAGE_SYNC_ONLY: WIN32_ERROR = 1159u32; +pub const ERROR_META_EXPANSION_TOO_LONG: WIN32_ERROR = 208u32; +pub const ERROR_MISSING_SYSTEMFILE: WIN32_ERROR = 573u32; +pub const ERROR_MOD_NOT_FOUND: WIN32_ERROR = 126u32; +pub const ERROR_MORE_DATA: WIN32_ERROR = 234u32; +pub const ERROR_MORE_WRITES: WIN32_ERROR = 1120u32; +pub const ERROR_MOUNT_POINT_NOT_RESOLVED: WIN32_ERROR = 649u32; +pub const ERROR_MP_PROCESSOR_MISMATCH: WIN32_ERROR = 725u32; +pub const ERROR_MR_MID_NOT_FOUND: WIN32_ERROR = 317u32; +pub const ERROR_MULTIPLE_FAULT_VIOLATION: WIN32_ERROR = 640u32; +pub const ERROR_MUTANT_LIMIT_EXCEEDED: WIN32_ERROR = 587u32; +pub const ERROR_MUTUAL_AUTH_FAILED: WIN32_ERROR = 1397u32; +pub const ERROR_NEGATIVE_SEEK: WIN32_ERROR = 131u32; +pub const ERROR_NESTING_NOT_ALLOWED: WIN32_ERROR = 215u32; +pub const ERROR_NETLOGON_NOT_STARTED: WIN32_ERROR = 1792u32; +pub const ERROR_NETNAME_DELETED: WIN32_ERROR = 64u32; +pub const ERROR_NETWORK_ACCESS_DENIED: WIN32_ERROR = 65u32; +pub const ERROR_NETWORK_ACCESS_DENIED_EDP: WIN32_ERROR = 354u32; +pub const ERROR_NETWORK_BUSY: WIN32_ERROR = 54u32; +pub const ERROR_NETWORK_UNREACHABLE: WIN32_ERROR = 1231u32; +pub const ERROR_NET_OPEN_FAILED: WIN32_ERROR = 570u32; +pub const ERROR_NET_WRITE_FAULT: WIN32_ERROR = 88u32; +pub const ERROR_NOACCESS: WIN32_ERROR = 998u32; +pub const ERROR_NOINTERFACE: WIN32_ERROR = 632u32; +pub const ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: WIN32_ERROR = 1807u32; +pub const ERROR_NOLOGON_SERVER_TRUST_ACCOUNT: WIN32_ERROR = 1809u32; +pub const ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT: WIN32_ERROR = 1808u32; +pub const ERROR_NONE_MAPPED: WIN32_ERROR = 1332u32; +pub const ERROR_NONPAGED_SYSTEM_RESOURCES: WIN32_ERROR = 1451u32; +pub const ERROR_NON_ACCOUNT_SID: WIN32_ERROR = 1257u32; +pub const ERROR_NON_DOMAIN_SID: WIN32_ERROR = 1258u32; +pub const ERROR_NON_MDICHILD_WINDOW: WIN32_ERROR = 1445u32; +pub const ERROR_NOTHING_TO_TERMINATE: WIN32_ERROR = 758u32; +pub const ERROR_NOTIFICATION_GUID_ALREADY_DEFINED: WIN32_ERROR = 309u32; +pub const ERROR_NOTIFY_CLEANUP: WIN32_ERROR = 745u32; +pub const ERROR_NOTIFY_ENUM_DIR: WIN32_ERROR = 1022u32; +pub const ERROR_NOT_ALLOWED_ON_SYSTEM_FILE: WIN32_ERROR = 313u32; +pub const ERROR_NOT_ALL_ASSIGNED: WIN32_ERROR = 1300u32; +pub const ERROR_NOT_APPCONTAINER: WIN32_ERROR = 4250u32; +pub const ERROR_NOT_AUTHENTICATED: WIN32_ERROR = 1244u32; +pub const ERROR_NOT_A_CLOUD_FILE: WIN32_ERROR = 376u32; +pub const ERROR_NOT_A_CLOUD_SYNC_ROOT: WIN32_ERROR = 405u32; +pub const ERROR_NOT_A_DAX_VOLUME: WIN32_ERROR = 420u32; +pub const ERROR_NOT_A_REPARSE_POINT: WIN32_ERROR = 4390u32; +pub const ERROR_NOT_CAPABLE: WIN32_ERROR = 775u32; +pub const ERROR_NOT_CHILD_WINDOW: WIN32_ERROR = 1442u32; +pub const ERROR_NOT_CONNECTED: WIN32_ERROR = 2250u32; +pub const ERROR_NOT_CONTAINER: WIN32_ERROR = 1207u32; +pub const ERROR_NOT_DAX_MAPPABLE: WIN32_ERROR = 421u32; +pub const ERROR_NOT_DOS_DISK: WIN32_ERROR = 26u32; +pub const ERROR_NOT_ENOUGH_MEMORY: WIN32_ERROR = 8u32; +pub const ERROR_NOT_ENOUGH_QUOTA: WIN32_ERROR = 1816u32; +pub const ERROR_NOT_ENOUGH_SERVER_MEMORY: WIN32_ERROR = 1130u32; +pub const ERROR_NOT_EXPORT_FORMAT: WIN32_ERROR = 6008u32; +pub const ERROR_NOT_FOUND: WIN32_ERROR = 1168u32; +pub const ERROR_NOT_GUI_PROCESS: WIN32_ERROR = 1471u32; +pub const ERROR_NOT_JOINED: WIN32_ERROR = 136u32; +pub const ERROR_NOT_LOCKED: WIN32_ERROR = 158u32; +pub const ERROR_NOT_LOGGED_ON: WIN32_ERROR = 1245u32; +pub const ERROR_NOT_LOGON_PROCESS: WIN32_ERROR = 1362u32; +pub const ERROR_NOT_OWNER: WIN32_ERROR = 288u32; +pub const ERROR_NOT_READY: WIN32_ERROR = 21u32; +pub const ERROR_NOT_READ_FROM_COPY: WIN32_ERROR = 337u32; +pub const ERROR_NOT_REDUNDANT_STORAGE: WIN32_ERROR = 333u32; +pub const ERROR_NOT_REGISTRY_FILE: WIN32_ERROR = 1017u32; +pub const ERROR_NOT_SAFEBOOT_SERVICE: WIN32_ERROR = 1084u32; +pub const ERROR_NOT_SAFE_MODE_DRIVER: WIN32_ERROR = 646u32; +pub const ERROR_NOT_SAME_DEVICE: WIN32_ERROR = 17u32; +pub const ERROR_NOT_SAME_OBJECT: WIN32_ERROR = 1656u32; +pub const ERROR_NOT_SUBSTED: WIN32_ERROR = 137u32; +pub const ERROR_NOT_SUPPORTED: WIN32_ERROR = 50u32; +pub const ERROR_NOT_SUPPORTED_IN_APPCONTAINER: WIN32_ERROR = 4252u32; +pub const ERROR_NOT_SUPPORTED_ON_DAX: WIN32_ERROR = 360u32; +pub const ERROR_NOT_SUPPORTED_ON_SBS: WIN32_ERROR = 1254u32; +pub const ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER: WIN32_ERROR = 8584u32; +pub const ERROR_NOT_SUPPORTED_WITH_AUDITING: WIN32_ERROR = 499u32; +pub const ERROR_NOT_SUPPORTED_WITH_BTT: WIN32_ERROR = 429u32; +pub const ERROR_NOT_SUPPORTED_WITH_BYPASSIO: WIN32_ERROR = 493u32; +pub const ERROR_NOT_SUPPORTED_WITH_CACHED_HANDLE: WIN32_ERROR = 509u32; +pub const ERROR_NOT_SUPPORTED_WITH_COMPRESSION: WIN32_ERROR = 496u32; +pub const ERROR_NOT_SUPPORTED_WITH_DEDUPLICATION: WIN32_ERROR = 498u32; +pub const ERROR_NOT_SUPPORTED_WITH_ENCRYPTION: WIN32_ERROR = 495u32; +pub const ERROR_NOT_SUPPORTED_WITH_MONITORING: WIN32_ERROR = 503u32; +pub const ERROR_NOT_SUPPORTED_WITH_REPLICATION: WIN32_ERROR = 497u32; +pub const ERROR_NOT_SUPPORTED_WITH_SNAPSHOT: WIN32_ERROR = 504u32; +pub const ERROR_NOT_SUPPORTED_WITH_VIRTUALIZATION: WIN32_ERROR = 505u32; +pub const ERROR_NOT_TINY_STREAM: WIN32_ERROR = 598u32; +pub const ERROR_NO_ACE_CONDITION: WIN32_ERROR = 804u32; +pub const ERROR_NO_ASSOCIATION: WIN32_ERROR = 1155u32; +pub const ERROR_NO_BYPASSIO_DRIVER_SUPPORT: WIN32_ERROR = 494u32; +pub const ERROR_NO_CALLBACK_ACTIVE: WIN32_ERROR = 614u32; +pub const ERROR_NO_DATA: WIN32_ERROR = 232u32; +pub const ERROR_NO_DATA_DETECTED: WIN32_ERROR = 1104u32; +pub const ERROR_NO_EFS: WIN32_ERROR = 6004u32; +pub const ERROR_NO_EVENT_PAIR: WIN32_ERROR = 580u32; +pub const ERROR_NO_GUID_TRANSLATION: WIN32_ERROR = 560u32; +pub const ERROR_NO_IMPERSONATION_TOKEN: WIN32_ERROR = 1309u32; +pub const ERROR_NO_INHERITANCE: WIN32_ERROR = 1391u32; +pub const ERROR_NO_LOGON_SERVERS: WIN32_ERROR = 1311u32; +pub const ERROR_NO_LOG_SPACE: WIN32_ERROR = 1019u32; +pub const ERROR_NO_MATCH: WIN32_ERROR = 1169u32; +pub const ERROR_NO_MEDIA_IN_DRIVE: WIN32_ERROR = 1112u32; +pub const ERROR_NO_MORE_DEVICES: WIN32_ERROR = 1248u32; +pub const ERROR_NO_MORE_FILES: WIN32_ERROR = 18u32; +pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32; +pub const ERROR_NO_MORE_MATCHES: WIN32_ERROR = 626u32; +pub const ERROR_NO_MORE_SEARCH_HANDLES: WIN32_ERROR = 113u32; +pub const ERROR_NO_MORE_USER_HANDLES: WIN32_ERROR = 1158u32; +pub const ERROR_NO_NETWORK: WIN32_ERROR = 1222u32; +pub const ERROR_NO_NET_OR_BAD_PATH: WIN32_ERROR = 1203u32; +pub const ERROR_NO_NVRAM_RESOURCES: WIN32_ERROR = 1470u32; +pub const ERROR_NO_PAGEFILE: WIN32_ERROR = 578u32; +pub const ERROR_NO_PHYSICALLY_ALIGNED_FREE_SPACE_FOUND: WIN32_ERROR = 408u32; +pub const ERROR_NO_PROC_SLOTS: WIN32_ERROR = 89u32; +pub const ERROR_NO_PROMOTION_ACTIVE: WIN32_ERROR = 8222u32; +pub const ERROR_NO_QUOTAS_FOR_ACCOUNT: WIN32_ERROR = 1302u32; +pub const ERROR_NO_RANGES_PROCESSED: WIN32_ERROR = 312u32; +pub const ERROR_NO_RECOVERY_POLICY: WIN32_ERROR = 6003u32; +pub const ERROR_NO_RECOVERY_PROGRAM: WIN32_ERROR = 1082u32; +pub const ERROR_NO_SCROLLBARS: WIN32_ERROR = 1447u32; +pub const ERROR_NO_SECRETS: WIN32_ERROR = 8620u32; +pub const ERROR_NO_SECURITY_ON_OBJECT: WIN32_ERROR = 1350u32; +pub const ERROR_NO_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1116u32; +pub const ERROR_NO_SIGNAL_SENT: WIN32_ERROR = 205u32; +pub const ERROR_NO_SITENAME: WIN32_ERROR = 1919u32; +pub const ERROR_NO_SITE_SETTINGS_OBJECT: WIN32_ERROR = 8619u32; +pub const ERROR_NO_SPOOL_SPACE: WIN32_ERROR = 62u32; +pub const ERROR_NO_SUCH_ALIAS: WIN32_ERROR = 1376u32; +pub const ERROR_NO_SUCH_DEVICE: WIN32_ERROR = 433u32; +pub const ERROR_NO_SUCH_DOMAIN: WIN32_ERROR = 1355u32; +pub const ERROR_NO_SUCH_GROUP: WIN32_ERROR = 1319u32; +pub const ERROR_NO_SUCH_LOGON_SESSION: WIN32_ERROR = 1312u32; +pub const ERROR_NO_SUCH_MEMBER: WIN32_ERROR = 1387u32; +pub const ERROR_NO_SUCH_PACKAGE: WIN32_ERROR = 1364u32; +pub const ERROR_NO_SUCH_PRIVILEGE: WIN32_ERROR = 1313u32; +pub const ERROR_NO_SUCH_SITE: WIN32_ERROR = 1249u32; +pub const ERROR_NO_SUCH_USER: WIN32_ERROR = 1317u32; +pub const ERROR_NO_SYSTEM_MENU: WIN32_ERROR = 1437u32; +pub const ERROR_NO_SYSTEM_RESOURCES: WIN32_ERROR = 1450u32; +pub const ERROR_NO_TASK_QUEUE: WIN32_ERROR = 427u32; +pub const ERROR_NO_TOKEN: WIN32_ERROR = 1008u32; +pub const ERROR_NO_TRACKING_SERVICE: WIN32_ERROR = 1172u32; +pub const ERROR_NO_TRUST_LSA_SECRET: WIN32_ERROR = 1786u32; +pub const ERROR_NO_TRUST_SAM_ACCOUNT: WIN32_ERROR = 1787u32; +pub const ERROR_NO_UNICODE_TRANSLATION: WIN32_ERROR = 1113u32; +pub const ERROR_NO_USER_KEYS: WIN32_ERROR = 6006u32; +pub const ERROR_NO_USER_SESSION_KEY: WIN32_ERROR = 1394u32; +pub const ERROR_NO_VOLUME_ID: WIN32_ERROR = 1173u32; +pub const ERROR_NO_VOLUME_LABEL: WIN32_ERROR = 125u32; +pub const ERROR_NO_WILDCARD_CHARACTERS: WIN32_ERROR = 1417u32; +pub const ERROR_NO_WORK_DONE: WIN32_ERROR = 235u32; +pub const ERROR_NO_WRITABLE_DC_FOUND: WIN32_ERROR = 8621u32; +pub const ERROR_NO_YIELD_PERFORMED: WIN32_ERROR = 721u32; +pub const ERROR_NTLM_BLOCKED: WIN32_ERROR = 1937u32; +pub const ERROR_NT_CROSS_ENCRYPTION_REQUIRED: WIN32_ERROR = 1386u32; +pub const ERROR_NULL_LM_PASSWORD: WIN32_ERROR = 1304u32; +pub const ERROR_OBJECT_IS_IMMUTABLE: WIN32_ERROR = 4449u32; +pub const ERROR_OBJECT_NAME_EXISTS: WIN32_ERROR = 698u32; +pub const ERROR_OBJECT_NOT_EXTERNALLY_BACKED: WIN32_ERROR = 342u32; +pub const ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED: WIN32_ERROR = 4442u32; +pub const ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED: WIN32_ERROR = 4440u32; +pub const ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED: WIN32_ERROR = 4443u32; +pub const ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED: WIN32_ERROR = 4441u32; +pub const ERROR_OFFSET_ALIGNMENT_VIOLATION: WIN32_ERROR = 327u32; +pub const ERROR_OLD_WIN_VERSION: WIN32_ERROR = 1150u32; +pub const ERROR_ONLY_IF_CONNECTED: WIN32_ERROR = 1251u32; +pub const ERROR_OPEN_FAILED: WIN32_ERROR = 110u32; +pub const ERROR_OPEN_FILES: WIN32_ERROR = 2401u32; +pub const ERROR_OPERATION_ABORTED: WIN32_ERROR = 995u32; +pub const ERROR_OPERATION_IN_PROGRESS: WIN32_ERROR = 329u32; +pub const ERROR_OPLOCK_BREAK_IN_PROGRESS: WIN32_ERROR = 742u32; +pub const ERROR_OPLOCK_HANDLE_CLOSED: WIN32_ERROR = 803u32; +pub const ERROR_OPLOCK_NOT_GRANTED: WIN32_ERROR = 300u32; +pub const ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE: WIN32_ERROR = 800u32; +pub const ERROR_ORPHAN_NAME_EXHAUSTED: WIN32_ERROR = 799u32; +pub const ERROR_OUTOFMEMORY: WIN32_ERROR = 14u32; +pub const ERROR_OUT_OF_PAPER: WIN32_ERROR = 28u32; +pub const ERROR_OUT_OF_STRUCTURES: WIN32_ERROR = 84u32; +pub const ERROR_OVERRIDE_NOCHANGES: WIN32_ERROR = 1252u32; +pub const ERROR_PAGED_SYSTEM_RESOURCES: WIN32_ERROR = 1452u32; +pub const ERROR_PAGEFILE_CREATE_FAILED: WIN32_ERROR = 576u32; +pub const ERROR_PAGEFILE_NOT_SUPPORTED: WIN32_ERROR = 491u32; +pub const ERROR_PAGEFILE_QUOTA: WIN32_ERROR = 1454u32; +pub const ERROR_PAGEFILE_QUOTA_EXCEEDED: WIN32_ERROR = 567u32; +pub const ERROR_PAGE_FAULT_COPY_ON_WRITE: WIN32_ERROR = 749u32; +pub const ERROR_PAGE_FAULT_DEMAND_ZERO: WIN32_ERROR = 748u32; +pub const ERROR_PAGE_FAULT_GUARD_PAGE: WIN32_ERROR = 750u32; +pub const ERROR_PAGE_FAULT_PAGING_FILE: WIN32_ERROR = 751u32; +pub const ERROR_PAGE_FAULT_TRANSITION: WIN32_ERROR = 747u32; +pub const ERROR_PARAMETER_QUOTA_EXCEEDED: WIN32_ERROR = 1283u32; +pub const ERROR_PARTIAL_COPY: WIN32_ERROR = 299u32; +pub const ERROR_PARTITION_FAILURE: WIN32_ERROR = 1105u32; +pub const ERROR_PARTITION_TERMINATING: WIN32_ERROR = 1184u32; +pub const ERROR_PASSWORD_CHANGE_REQUIRED: WIN32_ERROR = 1938u32; +pub const ERROR_PASSWORD_EXPIRED: WIN32_ERROR = 1330u32; +pub const ERROR_PASSWORD_MUST_CHANGE: WIN32_ERROR = 1907u32; +pub const ERROR_PASSWORD_RESTRICTION: WIN32_ERROR = 1325u32; +pub const ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT: WIN32_ERROR = 1651u32; +pub const ERROR_PATCH_NO_SEQUENCE: WIN32_ERROR = 1648u32; +pub const ERROR_PATCH_PACKAGE_INVALID: WIN32_ERROR = 1636u32; +pub const ERROR_PATCH_PACKAGE_OPEN_FAILED: WIN32_ERROR = 1635u32; +pub const ERROR_PATCH_PACKAGE_REJECTED: WIN32_ERROR = 1643u32; +pub const ERROR_PATCH_PACKAGE_UNSUPPORTED: WIN32_ERROR = 1637u32; +pub const ERROR_PATCH_REMOVAL_DISALLOWED: WIN32_ERROR = 1649u32; +pub const ERROR_PATCH_REMOVAL_UNSUPPORTED: WIN32_ERROR = 1646u32; +pub const ERROR_PATCH_TARGET_NOT_FOUND: WIN32_ERROR = 1642u32; +pub const ERROR_PATH_BUSY: WIN32_ERROR = 148u32; +pub const ERROR_PATH_NOT_FOUND: WIN32_ERROR = 3u32; +pub const ERROR_PER_USER_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1932u32; +pub const ERROR_PIPE_BUSY: WIN32_ERROR = 231u32; +pub const ERROR_PIPE_CONNECTED: WIN32_ERROR = 535u32; +pub const ERROR_PIPE_LISTENING: WIN32_ERROR = 536u32; +pub const ERROR_PIPE_LOCAL: WIN32_ERROR = 229u32; +pub const ERROR_PIPE_NOT_CONNECTED: WIN32_ERROR = 233u32; +pub const ERROR_PKINIT_FAILURE: WIN32_ERROR = 1263u32; +pub const ERROR_PLUGPLAY_QUERY_VETOED: WIN32_ERROR = 683u32; +pub const ERROR_PNP_BAD_MPS_TABLE: WIN32_ERROR = 671u32; +pub const ERROR_PNP_INVALID_ID: WIN32_ERROR = 674u32; +pub const ERROR_PNP_IRQ_TRANSLATION_FAILED: WIN32_ERROR = 673u32; +pub const ERROR_PNP_QUERY_REMOVE_DEVICE_TIMEOUT: WIN32_ERROR = 480u32; +pub const ERROR_PNP_QUERY_REMOVE_RELATED_DEVICE_TIMEOUT: WIN32_ERROR = 481u32; +pub const ERROR_PNP_QUERY_REMOVE_UNRELATED_DEVICE_TIMEOUT: WIN32_ERROR = 482u32; +pub const ERROR_PNP_REBOOT_REQUIRED: WIN32_ERROR = 638u32; +pub const ERROR_PNP_RESTART_ENUMERATION: WIN32_ERROR = 636u32; +pub const ERROR_PNP_TRANSLATION_FAILED: WIN32_ERROR = 672u32; +pub const ERROR_POINT_NOT_FOUND: WIN32_ERROR = 1171u32; +pub const ERROR_POLICY_OBJECT_NOT_FOUND: WIN32_ERROR = 8219u32; +pub const ERROR_POLICY_ONLY_IN_DS: WIN32_ERROR = 8220u32; +pub const ERROR_POPUP_ALREADY_ACTIVE: WIN32_ERROR = 1446u32; +pub const ERROR_PORT_MESSAGE_TOO_LONG: WIN32_ERROR = 546u32; +pub const ERROR_PORT_NOT_SET: WIN32_ERROR = 642u32; +pub const ERROR_PORT_UNREACHABLE: WIN32_ERROR = 1234u32; +pub const ERROR_POSSIBLE_DEADLOCK: WIN32_ERROR = 1131u32; +pub const ERROR_POTENTIAL_FILE_FOUND: WIN32_ERROR = 1180u32; +pub const ERROR_PREDEFINED_HANDLE: WIN32_ERROR = 714u32; +pub const ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED: WIN32_ERROR = 746u32; +pub const ERROR_PRINTER_ALREADY_EXISTS: WIN32_ERROR = 1802u32; +pub const ERROR_PRINTER_DELETED: WIN32_ERROR = 1905u32; +pub const ERROR_PRINTER_DRIVER_ALREADY_INSTALLED: WIN32_ERROR = 1795u32; +pub const ERROR_PRINTQ_FULL: WIN32_ERROR = 61u32; +pub const ERROR_PRINT_CANCELLED: WIN32_ERROR = 63u32; +pub const ERROR_PRIVATE_DIALOG_INDEX: WIN32_ERROR = 1415u32; +pub const ERROR_PRIVILEGE_NOT_HELD: WIN32_ERROR = 1314u32; +pub const ERROR_PROCESS_ABORTED: WIN32_ERROR = 1067u32; +pub const ERROR_PROCESS_IN_JOB: WIN32_ERROR = 760u32; +pub const ERROR_PROCESS_IS_PROTECTED: WIN32_ERROR = 1293u32; +pub const ERROR_PROCESS_MODE_ALREADY_BACKGROUND: WIN32_ERROR = 402u32; +pub const ERROR_PROCESS_MODE_NOT_BACKGROUND: WIN32_ERROR = 403u32; +pub const ERROR_PROCESS_NOT_IN_JOB: WIN32_ERROR = 759u32; +pub const ERROR_PROC_NOT_FOUND: WIN32_ERROR = 127u32; +pub const ERROR_PRODUCT_UNINSTALLED: WIN32_ERROR = 1614u32; +pub const ERROR_PRODUCT_VERSION: WIN32_ERROR = 1638u32; +pub const ERROR_PROFILING_AT_LIMIT: WIN32_ERROR = 553u32; +pub const ERROR_PROFILING_NOT_STARTED: WIN32_ERROR = 550u32; +pub const ERROR_PROFILING_NOT_STOPPED: WIN32_ERROR = 551u32; +pub const ERROR_PROMOTION_ACTIVE: WIN32_ERROR = 8221u32; +pub const ERROR_PROTOCOL_UNREACHABLE: WIN32_ERROR = 1233u32; +pub const ERROR_PWD_HISTORY_CONFLICT: WIN32_ERROR = 617u32; +pub const ERROR_PWD_TOO_LONG: WIN32_ERROR = 657u32; +pub const ERROR_PWD_TOO_RECENT: WIN32_ERROR = 616u32; +pub const ERROR_PWD_TOO_SHORT: WIN32_ERROR = 615u32; +pub const ERROR_QUOTA_ACTIVITY: WIN32_ERROR = 810u32; +pub const ERROR_QUOTA_LIST_INCONSISTENT: WIN32_ERROR = 621u32; +pub const ERROR_RANGE_LIST_CONFLICT: WIN32_ERROR = 627u32; +pub const ERROR_RANGE_NOT_FOUND: WIN32_ERROR = 644u32; +pub const ERROR_READ_FAULT: WIN32_ERROR = 30u32; +pub const ERROR_RECEIVE_EXPEDITED: WIN32_ERROR = 708u32; +pub const ERROR_RECEIVE_PARTIAL: WIN32_ERROR = 707u32; +pub const ERROR_RECEIVE_PARTIAL_EXPEDITED: WIN32_ERROR = 709u32; +pub const ERROR_RECOVERY_FAILURE: WIN32_ERROR = 1279u32; +pub const ERROR_REDIRECTOR_HAS_OPEN_HANDLES: WIN32_ERROR = 1794u32; +pub const ERROR_REDIR_PAUSED: WIN32_ERROR = 72u32; +pub const ERROR_REGISTRY_CORRUPT: WIN32_ERROR = 1015u32; +pub const ERROR_REGISTRY_HIVE_RECOVERED: WIN32_ERROR = 685u32; +pub const ERROR_REGISTRY_IO_FAILED: WIN32_ERROR = 1016u32; +pub const ERROR_REGISTRY_QUOTA_LIMIT: WIN32_ERROR = 613u32; +pub const ERROR_REGISTRY_RECOVERED: WIN32_ERROR = 1014u32; +pub const ERROR_REG_NAT_CONSUMPTION: WIN32_ERROR = 1261u32; +pub const ERROR_RELOC_CHAIN_XEEDS_SEGLIM: WIN32_ERROR = 201u32; +pub const ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED: WIN32_ERROR = 1936u32; +pub const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: WIN32_ERROR = 1220u32; +pub const ERROR_REMOTE_STORAGE_MEDIA_ERROR: WIN32_ERROR = 4352u32; +pub const ERROR_REMOTE_STORAGE_NOT_ACTIVE: WIN32_ERROR = 4351u32; +pub const ERROR_REM_NOT_LIST: WIN32_ERROR = 51u32; +pub const ERROR_REPARSE: WIN32_ERROR = 741u32; +pub const ERROR_REPARSE_ATTRIBUTE_CONFLICT: WIN32_ERROR = 4391u32; +pub const ERROR_REPARSE_OBJECT: WIN32_ERROR = 755u32; +pub const ERROR_REPARSE_POINT_ENCOUNTERED: WIN32_ERROR = 4395u32; +pub const ERROR_REPARSE_TAG_INVALID: WIN32_ERROR = 4393u32; +pub const ERROR_REPARSE_TAG_MISMATCH: WIN32_ERROR = 4394u32; +pub const ERROR_REPLY_MESSAGE_MISMATCH: WIN32_ERROR = 595u32; +pub const ERROR_REQUEST_ABORTED: WIN32_ERROR = 1235u32; +pub const ERROR_REQUEST_OUT_OF_SEQUENCE: WIN32_ERROR = 776u32; +pub const ERROR_REQUEST_PAUSED: WIN32_ERROR = 3050u32; +pub const ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION: WIN32_ERROR = 1459u32; +pub const ERROR_REQ_NOT_ACCEP: WIN32_ERROR = 71u32; +pub const ERROR_RESIDENT_FILE_NOT_SUPPORTED: WIN32_ERROR = 334u32; +pub const ERROR_RESOURCE_CALL_TIMED_OUT: WIN32_ERROR = 5910u32; +pub const ERROR_RESOURCE_DATA_NOT_FOUND: WIN32_ERROR = 1812u32; +pub const ERROR_RESOURCE_LANG_NOT_FOUND: WIN32_ERROR = 1815u32; +pub const ERROR_RESOURCE_NAME_NOT_FOUND: WIN32_ERROR = 1814u32; +pub const ERROR_RESOURCE_REQUIREMENTS_CHANGED: WIN32_ERROR = 756u32; +pub const ERROR_RESOURCE_TYPE_NOT_FOUND: WIN32_ERROR = 1813u32; +pub const ERROR_RESTART_APPLICATION: WIN32_ERROR = 1467u32; +pub const ERROR_RESUME_HIBERNATION: WIN32_ERROR = 727u32; +pub const ERROR_RETRY: WIN32_ERROR = 1237u32; +pub const ERROR_RETURN_ADDRESS_HIJACK_ATTEMPT: WIN32_ERROR = 1662u32; +pub const ERROR_REVISION_MISMATCH: WIN32_ERROR = 1306u32; +pub const ERROR_RING2SEG_MUST_BE_MOVABLE: WIN32_ERROR = 200u32; +pub const ERROR_RING2_STACK_IN_USE: WIN32_ERROR = 207u32; +pub const ERROR_RMODE_APP: WIN32_ERROR = 1153u32; +pub const ERROR_ROWSNOTRELEASED: WIN32_ERROR = 772u32; +pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: WIN32_ERROR = 15403u32; +pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: WIN32_ERROR = 15402u32; +pub const ERROR_RWRAW_ENCRYPTED_FILE_NOT_ENCRYPTED: WIN32_ERROR = 410u32; +pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILEOFFSET: WIN32_ERROR = 411u32; +pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_FILERANGE: WIN32_ERROR = 412u32; +pub const ERROR_RWRAW_ENCRYPTED_INVALID_EDATAINFO_PARAMETER: WIN32_ERROR = 413u32; +pub const ERROR_RXACT_COMMITTED: WIN32_ERROR = 744u32; +pub const ERROR_RXACT_COMMIT_FAILURE: WIN32_ERROR = 1370u32; +pub const ERROR_RXACT_COMMIT_NECESSARY: WIN32_ERROR = 678u32; +pub const ERROR_RXACT_INVALID_STATE: WIN32_ERROR = 1369u32; +pub const ERROR_RXACT_STATE_CREATED: WIN32_ERROR = 701u32; +pub const ERROR_SAME_DRIVE: WIN32_ERROR = 143u32; +pub const ERROR_SAM_INIT_FAILURE: WIN32_ERROR = 8541u32; +pub const ERROR_SCOPE_NOT_FOUND: WIN32_ERROR = 318u32; +pub const ERROR_SCREEN_ALREADY_LOCKED: WIN32_ERROR = 1440u32; +pub const ERROR_SCRUB_DATA_DISABLED: WIN32_ERROR = 332u32; +pub const ERROR_SECRET_TOO_LONG: WIN32_ERROR = 1382u32; +pub const ERROR_SECTION_DIRECT_MAP_ONLY: WIN32_ERROR = 819u32; +pub const ERROR_SECTOR_NOT_FOUND: WIN32_ERROR = 27u32; +pub const ERROR_SECURITY_DENIES_OPERATION: WIN32_ERROR = 447u32; +pub const ERROR_SECURITY_STREAM_IS_INCONSISTENT: WIN32_ERROR = 306u32; +pub const ERROR_SEEK: WIN32_ERROR = 25u32; +pub const ERROR_SEEK_ON_DEVICE: WIN32_ERROR = 132u32; +pub const ERROR_SEGMENT_NOTIFICATION: WIN32_ERROR = 702u32; +pub const ERROR_SEM_IS_SET: WIN32_ERROR = 102u32; +pub const ERROR_SEM_NOT_FOUND: WIN32_ERROR = 187u32; +pub const ERROR_SEM_OWNER_DIED: WIN32_ERROR = 105u32; +pub const ERROR_SEM_TIMEOUT: WIN32_ERROR = 121u32; +pub const ERROR_SEM_USER_LIMIT: WIN32_ERROR = 106u32; +pub const ERROR_SERIAL_NO_DEVICE: WIN32_ERROR = 1118u32; +pub const ERROR_SERVER_DISABLED: WIN32_ERROR = 1341u32; +pub const ERROR_SERVER_HAS_OPEN_HANDLES: WIN32_ERROR = 1811u32; +pub const ERROR_SERVER_NOT_DISABLED: WIN32_ERROR = 1342u32; +pub const ERROR_SERVER_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1255u32; +pub const ERROR_SERVER_SID_MISMATCH: WIN32_ERROR = 628u32; +pub const ERROR_SERVER_TRANSPORT_CONFLICT: WIN32_ERROR = 816u32; +pub const ERROR_SERVICE_ALREADY_RUNNING: WIN32_ERROR = 1056u32; +pub const ERROR_SERVICE_CANNOT_ACCEPT_CTRL: WIN32_ERROR = 1061u32; +pub const ERROR_SERVICE_DATABASE_LOCKED: WIN32_ERROR = 1055u32; +pub const ERROR_SERVICE_DEPENDENCY_DELETED: WIN32_ERROR = 1075u32; +pub const ERROR_SERVICE_DEPENDENCY_FAIL: WIN32_ERROR = 1068u32; +pub const ERROR_SERVICE_DISABLED: WIN32_ERROR = 1058u32; +pub const ERROR_SERVICE_DOES_NOT_EXIST: WIN32_ERROR = 1060u32; +pub const ERROR_SERVICE_EXISTS: WIN32_ERROR = 1073u32; +pub const ERROR_SERVICE_LOGON_FAILED: WIN32_ERROR = 1069u32; +pub const ERROR_SERVICE_MARKED_FOR_DELETE: WIN32_ERROR = 1072u32; +pub const ERROR_SERVICE_NEVER_STARTED: WIN32_ERROR = 1077u32; +pub const ERROR_SERVICE_NOTIFICATION: WIN32_ERROR = 716u32; +pub const ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: WIN32_ERROR = 1294u32; +pub const ERROR_SERVICE_NOT_ACTIVE: WIN32_ERROR = 1062u32; +pub const ERROR_SERVICE_NOT_FOUND: WIN32_ERROR = 1243u32; +pub const ERROR_SERVICE_NOT_IN_EXE: WIN32_ERROR = 1083u32; +pub const ERROR_SERVICE_NO_THREAD: WIN32_ERROR = 1054u32; +pub const ERROR_SERVICE_REQUEST_TIMEOUT: WIN32_ERROR = 1053u32; +pub const ERROR_SERVICE_SPECIFIC_ERROR: WIN32_ERROR = 1066u32; +pub const ERROR_SERVICE_START_HANG: WIN32_ERROR = 1070u32; +pub const ERROR_SESSION_CREDENTIAL_CONFLICT: WIN32_ERROR = 1219u32; +pub const ERROR_SESSION_KEY_TOO_SHORT: WIN32_ERROR = 501u32; +pub const ERROR_SETCOUNT_ON_BAD_LB: WIN32_ERROR = 1433u32; +pub const ERROR_SETMARK_DETECTED: WIN32_ERROR = 1103u32; +pub const ERROR_SET_CONTEXT_DENIED: WIN32_ERROR = 1660u32; +pub const ERROR_SET_NOT_FOUND: WIN32_ERROR = 1170u32; +pub const ERROR_SET_POWER_STATE_FAILED: WIN32_ERROR = 1141u32; +pub const ERROR_SET_POWER_STATE_VETOED: WIN32_ERROR = 1140u32; +pub const ERROR_SHARED_POLICY: WIN32_ERROR = 8218u32; +pub const ERROR_SHARING_BUFFER_EXCEEDED: WIN32_ERROR = 36u32; +pub const ERROR_SHARING_PAUSED: WIN32_ERROR = 70u32; +pub const ERROR_SHARING_VIOLATION: WIN32_ERROR = 32u32; +pub const ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME: WIN32_ERROR = 305u32; +pub const ERROR_SHUTDOWN_DISKS_NOT_IN_MAINTENANCE_MODE: WIN32_ERROR = 1192u32; +pub const ERROR_SHUTDOWN_IN_PROGRESS: WIN32_ERROR = 1115u32; +pub const ERROR_SHUTDOWN_IS_SCHEDULED: WIN32_ERROR = 1190u32; +pub const ERROR_SHUTDOWN_USERS_LOGGED_ON: WIN32_ERROR = 1191u32; +pub const ERROR_SIGNAL_PENDING: WIN32_ERROR = 162u32; +pub const ERROR_SIGNAL_REFUSED: WIN32_ERROR = 156u32; +pub const ERROR_SINGLE_INSTANCE_APP: WIN32_ERROR = 1152u32; +pub const ERROR_SMARTCARD_SUBSYSTEM_FAILURE: WIN32_ERROR = 1264u32; +pub const ERROR_SMB1_NOT_AVAILABLE: WIN32_ERROR = 384u32; +pub const ERROR_SMB_GUEST_LOGON_BLOCKED: WIN32_ERROR = 1272u32; +pub const ERROR_SMR_GARBAGE_COLLECTION_REQUIRED: WIN32_ERROR = 4445u32; +pub const ERROR_SOME_NOT_MAPPED: WIN32_ERROR = 1301u32; +pub const ERROR_SOURCE_ELEMENT_EMPTY: WIN32_ERROR = 1160u32; +pub const ERROR_SPARSE_FILE_NOT_SUPPORTED: WIN32_ERROR = 490u32; +pub const ERROR_SPECIAL_ACCOUNT: WIN32_ERROR = 1371u32; +pub const ERROR_SPECIAL_GROUP: WIN32_ERROR = 1372u32; +pub const ERROR_SPECIAL_USER: WIN32_ERROR = 1373u32; +pub const ERROR_SRC_SRV_DLL_LOAD_FAILED: WIN32_ERROR = 428u32; +pub const ERROR_STACK_BUFFER_OVERRUN: WIN32_ERROR = 1282u32; +pub const ERROR_STACK_OVERFLOW: WIN32_ERROR = 1001u32; +pub const ERROR_STACK_OVERFLOW_READ: WIN32_ERROR = 599u32; +pub const ERROR_STOPPED_ON_SYMLINK: WIN32_ERROR = 681u32; +pub const ERROR_STORAGE_LOST_DATA_PERSISTENCE: WIN32_ERROR = 368u32; +pub const ERROR_STORAGE_RESERVE_ALREADY_EXISTS: WIN32_ERROR = 418u32; +pub const ERROR_STORAGE_RESERVE_DOES_NOT_EXIST: WIN32_ERROR = 417u32; +pub const ERROR_STORAGE_RESERVE_ID_INVALID: WIN32_ERROR = 416u32; +pub const ERROR_STORAGE_RESERVE_NOT_EMPTY: WIN32_ERROR = 419u32; +pub const ERROR_STORAGE_STACK_ACCESS_DENIED: WIN32_ERROR = 472u32; +pub const ERROR_STORAGE_TOPOLOGY_ID_MISMATCH: WIN32_ERROR = 345u32; +pub const ERROR_STRICT_CFG_VIOLATION: WIN32_ERROR = 1657u32; +pub const ERROR_SUBST_TO_JOIN: WIN32_ERROR = 141u32; +pub const ERROR_SUBST_TO_SUBST: WIN32_ERROR = 139u32; +pub const ERROR_SUCCESS: WIN32_ERROR = 0u32; +pub const ERROR_SUCCESS_REBOOT_INITIATED: WIN32_ERROR = 1641u32; +pub const ERROR_SWAPERROR: WIN32_ERROR = 999u32; +pub const ERROR_SYMLINK_CLASS_DISABLED: WIN32_ERROR = 1463u32; +pub const ERROR_SYMLINK_NOT_SUPPORTED: WIN32_ERROR = 1464u32; +pub const ERROR_SYNCHRONIZATION_REQUIRED: WIN32_ERROR = 569u32; +pub const ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED: WIN32_ERROR = 1274u32; +pub const ERROR_SYSTEM_HIVE_TOO_LARGE: WIN32_ERROR = 653u32; +pub const ERROR_SYSTEM_IMAGE_BAD_SIGNATURE: WIN32_ERROR = 637u32; +pub const ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION: WIN32_ERROR = 783u32; +pub const ERROR_SYSTEM_POWERSTATE_TRANSITION: WIN32_ERROR = 782u32; +pub const ERROR_SYSTEM_PROCESS_TERMINATED: WIN32_ERROR = 591u32; +pub const ERROR_SYSTEM_SHUTDOWN: WIN32_ERROR = 641u32; +pub const ERROR_SYSTEM_TRACE: WIN32_ERROR = 150u32; +pub const ERROR_THREAD_1_INACTIVE: WIN32_ERROR = 210u32; +pub const ERROR_THREAD_ALREADY_IN_TASK: WIN32_ERROR = 1552u32; +pub const ERROR_THREAD_MODE_ALREADY_BACKGROUND: WIN32_ERROR = 400u32; +pub const ERROR_THREAD_MODE_NOT_BACKGROUND: WIN32_ERROR = 401u32; +pub const ERROR_THREAD_NOT_IN_PROCESS: WIN32_ERROR = 566u32; +pub const ERROR_THREAD_WAS_SUSPENDED: WIN32_ERROR = 699u32; +pub const ERROR_TIMEOUT: WIN32_ERROR = 1460u32; +pub const ERROR_TIMER_NOT_CANCELED: WIN32_ERROR = 541u32; +pub const ERROR_TIMER_RESOLUTION_NOT_SET: WIN32_ERROR = 607u32; +pub const ERROR_TIMER_RESUME_IGNORED: WIN32_ERROR = 722u32; +pub const ERROR_TIME_SENSITIVE_THREAD: WIN32_ERROR = 422u32; +pub const ERROR_TIME_SKEW: WIN32_ERROR = 1398u32; +pub const ERROR_TLW_WITH_WSCHILD: WIN32_ERROR = 1406u32; +pub const ERROR_TOKEN_ALREADY_IN_USE: WIN32_ERROR = 1375u32; +pub const ERROR_TOO_MANY_CMDS: WIN32_ERROR = 56u32; +pub const ERROR_TOO_MANY_CONTEXT_IDS: WIN32_ERROR = 1384u32; +pub const ERROR_TOO_MANY_DESCRIPTORS: WIN32_ERROR = 331u32; +pub const ERROR_TOO_MANY_LINKS: WIN32_ERROR = 1142u32; +pub const ERROR_TOO_MANY_LUIDS_REQUESTED: WIN32_ERROR = 1333u32; +pub const ERROR_TOO_MANY_MODULES: WIN32_ERROR = 214u32; +pub const ERROR_TOO_MANY_MUXWAITERS: WIN32_ERROR = 152u32; +pub const ERROR_TOO_MANY_NAMES: WIN32_ERROR = 68u32; +pub const ERROR_TOO_MANY_OPEN_FILES: WIN32_ERROR = 4u32; +pub const ERROR_TOO_MANY_POSTS: WIN32_ERROR = 298u32; +pub const ERROR_TOO_MANY_SECRETS: WIN32_ERROR = 1381u32; +pub const ERROR_TOO_MANY_SEMAPHORES: WIN32_ERROR = 100u32; +pub const ERROR_TOO_MANY_SEM_REQUESTS: WIN32_ERROR = 103u32; +pub const ERROR_TOO_MANY_SESS: WIN32_ERROR = 69u32; +pub const ERROR_TOO_MANY_SIDS: WIN32_ERROR = 1389u32; +pub const ERROR_TOO_MANY_TCBS: WIN32_ERROR = 155u32; +pub const ERROR_TOO_MANY_THREADS: WIN32_ERROR = 565u32; +pub const ERROR_TRANSLATION_COMPLETE: WIN32_ERROR = 757u32; +pub const ERROR_TRUSTED_DOMAIN_FAILURE: WIN32_ERROR = 1788u32; +pub const ERROR_TRUSTED_RELATIONSHIP_FAILURE: WIN32_ERROR = 1789u32; +pub const ERROR_TRUST_FAILURE: WIN32_ERROR = 1790u32; +pub const ERROR_UNABLE_TO_LOCK_MEDIA: WIN32_ERROR = 1108u32; +pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT: WIN32_ERROR = 1176u32; +pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT_2: WIN32_ERROR = 1177u32; +pub const ERROR_UNABLE_TO_REMOVE_REPLACED: WIN32_ERROR = 1175u32; +pub const ERROR_UNABLE_TO_UNLOAD_MEDIA: WIN32_ERROR = 1109u32; +pub const ERROR_UNDEFINED_CHARACTER: WIN32_ERROR = 583u32; +pub const ERROR_UNDEFINED_SCOPE: WIN32_ERROR = 319u32; +pub const ERROR_UNEXPECTED_MM_CREATE_ERR: WIN32_ERROR = 556u32; +pub const ERROR_UNEXPECTED_MM_EXTEND_ERR: WIN32_ERROR = 558u32; +pub const ERROR_UNEXPECTED_MM_MAP_ERROR: WIN32_ERROR = 557u32; +pub const ERROR_UNEXPECTED_NTCACHEMANAGER_ERROR: WIN32_ERROR = 443u32; +pub const ERROR_UNEXP_NET_ERR: WIN32_ERROR = 59u32; +pub const ERROR_UNHANDLED_EXCEPTION: WIN32_ERROR = 574u32; +pub const ERROR_UNIDENTIFIED_ERROR: WIN32_ERROR = 1287u32; +pub const ERROR_UNKNOWN_COMPONENT: WIN32_ERROR = 1607u32; +pub const ERROR_UNKNOWN_FEATURE: WIN32_ERROR = 1606u32; +pub const ERROR_UNKNOWN_PATCH: WIN32_ERROR = 1647u32; +pub const ERROR_UNKNOWN_PORT: WIN32_ERROR = 1796u32; +pub const ERROR_UNKNOWN_PRINTER_DRIVER: WIN32_ERROR = 1797u32; +pub const ERROR_UNKNOWN_PRINTPROCESSOR: WIN32_ERROR = 1798u32; +pub const ERROR_UNKNOWN_PRODUCT: WIN32_ERROR = 1605u32; +pub const ERROR_UNKNOWN_PROPERTY: WIN32_ERROR = 1608u32; +pub const ERROR_UNKNOWN_REVISION: WIN32_ERROR = 1305u32; +pub const ERROR_UNRECOGNIZED_MEDIA: WIN32_ERROR = 1785u32; +pub const ERROR_UNRECOGNIZED_VOLUME: WIN32_ERROR = 1005u32; +pub const ERROR_UNSATISFIED_DEPENDENCIES: WIN32_ERROR = 441u32; +pub const ERROR_UNSUPPORTED_COMPRESSION: WIN32_ERROR = 618u32; +pub const ERROR_UNSUPPORTED_TYPE: WIN32_ERROR = 1630u32; +pub const ERROR_UNTRUSTED_MOUNT_POINT: WIN32_ERROR = 448u32; +pub const ERROR_UNWIND: WIN32_ERROR = 542u32; +pub const ERROR_UNWIND_CONSOLIDATE: WIN32_ERROR = 684u32; +pub const ERROR_USER_APC: WIN32_ERROR = 737u32; +pub const ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED: WIN32_ERROR = 1934u32; +pub const ERROR_USER_EXISTS: WIN32_ERROR = 1316u32; +pub const ERROR_USER_MAPPED_FILE: WIN32_ERROR = 1224u32; +pub const ERROR_USER_PROFILE_LOAD: WIN32_ERROR = 500u32; +pub const ERROR_VALIDATE_CONTINUE: WIN32_ERROR = 625u32; +pub const ERROR_VC_DISCONNECTED: WIN32_ERROR = 240u32; +pub const ERROR_VDM_DISALLOWED: WIN32_ERROR = 1286u32; +pub const ERROR_VDM_HARD_ERROR: WIN32_ERROR = 593u32; +pub const ERROR_VERIFIER_STOP: WIN32_ERROR = 537u32; +pub const ERROR_VERSION_PARSE_ERROR: WIN32_ERROR = 777u32; +pub const ERROR_VIRUS_DELETED: WIN32_ERROR = 226u32; +pub const ERROR_VIRUS_INFECTED: WIN32_ERROR = 225u32; +pub const ERROR_VOLSNAP_HIBERNATE_READY: WIN32_ERROR = 761u32; +pub const ERROR_VOLSNAP_PREPARE_HIBERNATE: WIN32_ERROR = 655u32; +pub const ERROR_VOLUME_MOUNTED: WIN32_ERROR = 743u32; +pub const ERROR_VOLUME_NOT_CLUSTER_ALIGNED: WIN32_ERROR = 407u32; +pub const ERROR_VOLUME_NOT_SIS_ENABLED: WIN32_ERROR = 4500u32; +pub const ERROR_VOLUME_NOT_SUPPORTED: WIN32_ERROR = 492u32; +pub const ERROR_VOLUME_NOT_SUPPORT_EFS: WIN32_ERROR = 6014u32; +pub const ERROR_VOLUME_WRITE_ACCESS_DENIED: WIN32_ERROR = 508u32; +pub const ERROR_WAIT_1: WIN32_ERROR = 731u32; +pub const ERROR_WAIT_2: WIN32_ERROR = 732u32; +pub const ERROR_WAIT_3: WIN32_ERROR = 733u32; +pub const ERROR_WAIT_63: WIN32_ERROR = 734u32; +pub const ERROR_WAIT_FOR_OPLOCK: WIN32_ERROR = 765u32; +pub const ERROR_WAIT_NO_CHILDREN: WIN32_ERROR = 128u32; +pub const ERROR_WAKE_SYSTEM: WIN32_ERROR = 730u32; +pub const ERROR_WAKE_SYSTEM_DEBUGGER: WIN32_ERROR = 675u32; +pub const ERROR_WAS_LOCKED: WIN32_ERROR = 717u32; +pub const ERROR_WAS_UNLOCKED: WIN32_ERROR = 715u32; +pub const ERROR_WEAK_WHFBKEY_BLOCKED: WIN32_ERROR = 8651u32; +pub const ERROR_WINDOW_NOT_COMBOBOX: WIN32_ERROR = 1423u32; +pub const ERROR_WINDOW_NOT_DIALOG: WIN32_ERROR = 1420u32; +pub const ERROR_WINDOW_OF_OTHER_THREAD: WIN32_ERROR = 1408u32; +pub const ERROR_WIP_ENCRYPTION_FAILED: WIN32_ERROR = 6023u32; +pub const ERROR_WOF_FILE_RESOURCE_TABLE_CORRUPT: WIN32_ERROR = 4448u32; +pub const ERROR_WOF_WIM_HEADER_CORRUPT: WIN32_ERROR = 4446u32; +pub const ERROR_WOF_WIM_RESOURCE_TABLE_CORRUPT: WIN32_ERROR = 4447u32; +pub const ERROR_WORKING_SET_QUOTA: WIN32_ERROR = 1453u32; +pub const ERROR_WOW_ASSERTION: WIN32_ERROR = 670u32; +pub const ERROR_WRITE_FAULT: WIN32_ERROR = 29u32; +pub const ERROR_WRITE_PROTECT: WIN32_ERROR = 19u32; +pub const ERROR_WRONG_COMPARTMENT: WIN32_ERROR = 1468u32; +pub const ERROR_WRONG_DISK: WIN32_ERROR = 34u32; +pub const ERROR_WRONG_EFS: WIN32_ERROR = 6005u32; +pub const ERROR_WRONG_PASSWORD: WIN32_ERROR = 1323u32; +pub const ERROR_WRONG_TARGET_NAME: WIN32_ERROR = 1396u32; +pub const ERROR_WX86_ERROR: WIN32_ERROR = 540u32; +pub const ERROR_WX86_WARNING: WIN32_ERROR = 539u32; +pub const ERROR_XMLDSIG_ERROR: WIN32_ERROR = 1466u32; +pub const ERROR_XML_PARSE_ERROR: WIN32_ERROR = 1465u32; +pub type EXCEPTION_DISPOSITION = i32; +pub const EXCEPTION_MAXIMUM_PARAMETERS: u32 = 15u32; +#[repr(C)] +pub struct EXCEPTION_POINTERS { + pub ExceptionRecord: *mut EXCEPTION_RECORD, + pub ContextRecord: *mut CONTEXT, +} +impl ::core::marker::Copy for EXCEPTION_POINTERS {} +impl ::core::clone::Clone for EXCEPTION_POINTERS { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct EXCEPTION_RECORD { + pub ExceptionCode: NTSTATUS, + pub ExceptionFlags: u32, + pub ExceptionRecord: *mut EXCEPTION_RECORD, + pub ExceptionAddress: *mut ::core::ffi::c_void, + pub NumberParameters: u32, + pub ExceptionInformation: [usize; 15], +} +impl ::core::marker::Copy for EXCEPTION_RECORD {} +impl ::core::clone::Clone for EXCEPTION_RECORD { + fn clone(&self) -> Self { + *self + } +} +pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = -1073741571i32; +pub const EXTENDED_STARTUPINFO_PRESENT: PROCESS_CREATION_FLAGS = 524288u32; +pub const E_NOTIMPL: HRESULT = -2147467263i32; +pub const ExceptionCollidedUnwind: EXCEPTION_DISPOSITION = 3i32; +pub const ExceptionContinueExecution: EXCEPTION_DISPOSITION = 0i32; +pub const ExceptionContinueSearch: EXCEPTION_DISPOSITION = 1i32; +pub const ExceptionNestedException: EXCEPTION_DISPOSITION = 2i32; +pub type FACILITY_CODE = u32; +pub const FACILITY_NT_BIT: FACILITY_CODE = 268435456u32; +pub const FALSE: BOOL = 0i32; +pub type FARPROC = ::core::option::Option<unsafe extern "system" fn() -> isize>; +#[repr(C)] +pub struct FD_SET { + pub fd_count: u32, + pub fd_array: [SOCKET; 64], +} +impl ::core::marker::Copy for FD_SET {} +impl ::core::clone::Clone for FD_SET { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct FILETIME { + pub dwLowDateTime: u32, + pub dwHighDateTime: u32, +} +impl ::core::marker::Copy for FILETIME {} +impl ::core::clone::Clone for FILETIME { + fn clone(&self) -> Self { + *self + } +} +pub type FILE_ACCESS_RIGHTS = u32; +pub const FILE_ADD_FILE: FILE_ACCESS_RIGHTS = 2u32; +pub const FILE_ADD_SUBDIRECTORY: FILE_ACCESS_RIGHTS = 4u32; +pub const FILE_ALL_ACCESS: FILE_ACCESS_RIGHTS = 2032127u32; +pub const FILE_APPEND_DATA: FILE_ACCESS_RIGHTS = 4u32; +pub const FILE_ATTRIBUTE_ARCHIVE: FILE_FLAGS_AND_ATTRIBUTES = 32u32; +pub const FILE_ATTRIBUTE_COMPRESSED: FILE_FLAGS_AND_ATTRIBUTES = 2048u32; +pub const FILE_ATTRIBUTE_DEVICE: FILE_FLAGS_AND_ATTRIBUTES = 64u32; +pub const FILE_ATTRIBUTE_DIRECTORY: FILE_FLAGS_AND_ATTRIBUTES = 16u32; +pub const FILE_ATTRIBUTE_EA: FILE_FLAGS_AND_ATTRIBUTES = 262144u32; +pub const FILE_ATTRIBUTE_ENCRYPTED: FILE_FLAGS_AND_ATTRIBUTES = 16384u32; +pub const FILE_ATTRIBUTE_HIDDEN: FILE_FLAGS_AND_ATTRIBUTES = 2u32; +pub const FILE_ATTRIBUTE_INTEGRITY_STREAM: FILE_FLAGS_AND_ATTRIBUTES = 32768u32; +pub const FILE_ATTRIBUTE_NORMAL: FILE_FLAGS_AND_ATTRIBUTES = 128u32; +pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: FILE_FLAGS_AND_ATTRIBUTES = 8192u32; +pub const FILE_ATTRIBUTE_NO_SCRUB_DATA: FILE_FLAGS_AND_ATTRIBUTES = 131072u32; +pub const FILE_ATTRIBUTE_OFFLINE: FILE_FLAGS_AND_ATTRIBUTES = 4096u32; +pub const FILE_ATTRIBUTE_PINNED: FILE_FLAGS_AND_ATTRIBUTES = 524288u32; +pub const FILE_ATTRIBUTE_READONLY: FILE_FLAGS_AND_ATTRIBUTES = 1u32; +pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS: FILE_FLAGS_AND_ATTRIBUTES = 4194304u32; +pub const FILE_ATTRIBUTE_RECALL_ON_OPEN: FILE_FLAGS_AND_ATTRIBUTES = 262144u32; +pub const FILE_ATTRIBUTE_REPARSE_POINT: FILE_FLAGS_AND_ATTRIBUTES = 1024u32; +pub const FILE_ATTRIBUTE_SPARSE_FILE: FILE_FLAGS_AND_ATTRIBUTES = 512u32; +pub const FILE_ATTRIBUTE_SYSTEM: FILE_FLAGS_AND_ATTRIBUTES = 4u32; +#[repr(C)] +pub struct FILE_ATTRIBUTE_TAG_INFO { + pub FileAttributes: u32, + pub ReparseTag: u32, +} +impl ::core::marker::Copy for FILE_ATTRIBUTE_TAG_INFO {} +impl ::core::clone::Clone for FILE_ATTRIBUTE_TAG_INFO { + fn clone(&self) -> Self { + *self + } +} +pub const FILE_ATTRIBUTE_TEMPORARY: FILE_FLAGS_AND_ATTRIBUTES = 256u32; +pub const FILE_ATTRIBUTE_UNPINNED: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32; +pub const FILE_ATTRIBUTE_VIRTUAL: FILE_FLAGS_AND_ATTRIBUTES = 65536u32; +#[repr(C)] +pub struct FILE_BASIC_INFO { + pub CreationTime: i64, + pub LastAccessTime: i64, + pub LastWriteTime: i64, + pub ChangeTime: i64, + pub FileAttributes: u32, +} +impl ::core::marker::Copy for FILE_BASIC_INFO {} +impl ::core::clone::Clone for FILE_BASIC_INFO { + fn clone(&self) -> Self { + *self + } +} +pub const FILE_BEGIN: SET_FILE_POINTER_MOVE_METHOD = 0u32; +pub const FILE_COMPLETE_IF_OPLOCKED: NTCREATEFILE_CREATE_OPTIONS = 256u32; +pub const FILE_CONTAINS_EXTENDED_CREATE_INFORMATION: NTCREATEFILE_CREATE_OPTIONS = 268435456u32; +pub const FILE_CREATE: NTCREATEFILE_CREATE_DISPOSITION = 2u32; +pub const FILE_CREATE_PIPE_INSTANCE: FILE_ACCESS_RIGHTS = 4u32; +pub const FILE_CREATE_TREE_CONNECTION: NTCREATEFILE_CREATE_OPTIONS = 128u32; +pub type FILE_CREATION_DISPOSITION = u32; +pub const FILE_CURRENT: SET_FILE_POINTER_MOVE_METHOD = 1u32; +pub const FILE_DELETE_CHILD: FILE_ACCESS_RIGHTS = 64u32; +pub const FILE_DELETE_ON_CLOSE: NTCREATEFILE_CREATE_OPTIONS = 4096u32; +pub const FILE_DIRECTORY_FILE: NTCREATEFILE_CREATE_OPTIONS = 1u32; +pub const FILE_DISALLOW_EXCLUSIVE: NTCREATEFILE_CREATE_OPTIONS = 131072u32; +pub const FILE_DISPOSITION_FLAG_DELETE: FILE_DISPOSITION_INFO_EX_FLAGS = 1u32; +pub const FILE_DISPOSITION_FLAG_DO_NOT_DELETE: FILE_DISPOSITION_INFO_EX_FLAGS = 0u32; +pub const FILE_DISPOSITION_FLAG_FORCE_IMAGE_SECTION_CHECK: FILE_DISPOSITION_INFO_EX_FLAGS = 4u32; +pub const FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE: FILE_DISPOSITION_INFO_EX_FLAGS = 16u32; +pub const FILE_DISPOSITION_FLAG_ON_CLOSE: FILE_DISPOSITION_INFO_EX_FLAGS = 8u32; +pub const FILE_DISPOSITION_FLAG_POSIX_SEMANTICS: FILE_DISPOSITION_INFO_EX_FLAGS = 2u32; +#[repr(C)] +pub struct FILE_DISPOSITION_INFO { + pub DeleteFile: BOOLEAN, +} +impl ::core::marker::Copy for FILE_DISPOSITION_INFO {} +impl ::core::clone::Clone for FILE_DISPOSITION_INFO { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct FILE_DISPOSITION_INFO_EX { + pub Flags: FILE_DISPOSITION_INFO_EX_FLAGS, +} +impl ::core::marker::Copy for FILE_DISPOSITION_INFO_EX {} +impl ::core::clone::Clone for FILE_DISPOSITION_INFO_EX { + fn clone(&self) -> Self { + *self + } +} +pub type FILE_DISPOSITION_INFO_EX_FLAGS = u32; +pub const FILE_END: SET_FILE_POINTER_MOVE_METHOD = 2u32; +#[repr(C)] +pub struct FILE_END_OF_FILE_INFO { + pub EndOfFile: i64, +} +impl ::core::marker::Copy for FILE_END_OF_FILE_INFO {} +impl ::core::clone::Clone for FILE_END_OF_FILE_INFO { + fn clone(&self) -> Self { + *self + } +} +pub const FILE_EXECUTE: FILE_ACCESS_RIGHTS = 32u32; +pub type FILE_FLAGS_AND_ATTRIBUTES = u32; +pub const FILE_FLAG_BACKUP_SEMANTICS: FILE_FLAGS_AND_ATTRIBUTES = 33554432u32; +pub const FILE_FLAG_DELETE_ON_CLOSE: FILE_FLAGS_AND_ATTRIBUTES = 67108864u32; +pub const FILE_FLAG_FIRST_PIPE_INSTANCE: FILE_FLAGS_AND_ATTRIBUTES = 524288u32; +pub const FILE_FLAG_NO_BUFFERING: FILE_FLAGS_AND_ATTRIBUTES = 536870912u32; +pub const FILE_FLAG_OPEN_NO_RECALL: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32; +pub const FILE_FLAG_OPEN_REPARSE_POINT: FILE_FLAGS_AND_ATTRIBUTES = 2097152u32; +pub const FILE_FLAG_OVERLAPPED: FILE_FLAGS_AND_ATTRIBUTES = 1073741824u32; +pub const FILE_FLAG_POSIX_SEMANTICS: FILE_FLAGS_AND_ATTRIBUTES = 16777216u32; +pub const FILE_FLAG_RANDOM_ACCESS: FILE_FLAGS_AND_ATTRIBUTES = 268435456u32; +pub const FILE_FLAG_SEQUENTIAL_SCAN: FILE_FLAGS_AND_ATTRIBUTES = 134217728u32; +pub const FILE_FLAG_SESSION_AWARE: FILE_FLAGS_AND_ATTRIBUTES = 8388608u32; +pub const FILE_FLAG_WRITE_THROUGH: FILE_FLAGS_AND_ATTRIBUTES = 2147483648u32; +pub const FILE_GENERIC_EXECUTE: FILE_ACCESS_RIGHTS = 1179808u32; +pub const FILE_GENERIC_READ: FILE_ACCESS_RIGHTS = 1179785u32; +pub const FILE_GENERIC_WRITE: FILE_ACCESS_RIGHTS = 1179926u32; +#[repr(C)] +pub struct FILE_ID_BOTH_DIR_INFO { + pub NextEntryOffset: u32, + pub FileIndex: u32, + pub CreationTime: i64, + pub LastAccessTime: i64, + pub LastWriteTime: i64, + pub ChangeTime: i64, + pub EndOfFile: i64, + pub AllocationSize: i64, + pub FileAttributes: u32, + pub FileNameLength: u32, + pub EaSize: u32, + pub ShortNameLength: i8, + pub ShortName: [u16; 12], + pub FileId: i64, + pub FileName: [u16; 1], +} +impl ::core::marker::Copy for FILE_ID_BOTH_DIR_INFO {} +impl ::core::clone::Clone for FILE_ID_BOTH_DIR_INFO { + fn clone(&self) -> Self { + *self + } +} +pub type FILE_INFO_BY_HANDLE_CLASS = i32; +pub const FILE_LIST_DIRECTORY: FILE_ACCESS_RIGHTS = 1u32; +pub const FILE_NAME_NORMALIZED: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32; +pub const FILE_NAME_OPENED: GETFINALPATHNAMEBYHANDLE_FLAGS = 8u32; +pub const FILE_NON_DIRECTORY_FILE: NTCREATEFILE_CREATE_OPTIONS = 64u32; +pub const FILE_NO_COMPRESSION: NTCREATEFILE_CREATE_OPTIONS = 32768u32; +pub const FILE_NO_EA_KNOWLEDGE: NTCREATEFILE_CREATE_OPTIONS = 512u32; +pub const FILE_NO_INTERMEDIATE_BUFFERING: NTCREATEFILE_CREATE_OPTIONS = 8u32; +pub const FILE_OPEN: NTCREATEFILE_CREATE_DISPOSITION = 1u32; +pub const FILE_OPEN_BY_FILE_ID: NTCREATEFILE_CREATE_OPTIONS = 8192u32; +pub const FILE_OPEN_FOR_BACKUP_INTENT: NTCREATEFILE_CREATE_OPTIONS = 16384u32; +pub const FILE_OPEN_FOR_FREE_SPACE_QUERY: NTCREATEFILE_CREATE_OPTIONS = 8388608u32; +pub const FILE_OPEN_IF: NTCREATEFILE_CREATE_DISPOSITION = 3u32; +pub const FILE_OPEN_NO_RECALL: NTCREATEFILE_CREATE_OPTIONS = 4194304u32; +pub const FILE_OPEN_REPARSE_POINT: NTCREATEFILE_CREATE_OPTIONS = 2097152u32; +pub const FILE_OPEN_REQUIRING_OPLOCK: NTCREATEFILE_CREATE_OPTIONS = 65536u32; +pub const FILE_OVERWRITE: NTCREATEFILE_CREATE_DISPOSITION = 4u32; +pub const FILE_OVERWRITE_IF: NTCREATEFILE_CREATE_DISPOSITION = 5u32; +pub const FILE_RANDOM_ACCESS: NTCREATEFILE_CREATE_OPTIONS = 2048u32; +pub const FILE_READ_ATTRIBUTES: FILE_ACCESS_RIGHTS = 128u32; +pub const FILE_READ_DATA: FILE_ACCESS_RIGHTS = 1u32; +pub const FILE_READ_EA: FILE_ACCESS_RIGHTS = 8u32; +pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32; +pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32; +pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32; +pub const FILE_SHARE_DELETE: FILE_SHARE_MODE = 4u32; +pub type FILE_SHARE_MODE = u32; +pub const FILE_SHARE_NONE: FILE_SHARE_MODE = 0u32; +pub const FILE_SHARE_READ: FILE_SHARE_MODE = 1u32; +pub const FILE_SHARE_WRITE: FILE_SHARE_MODE = 2u32; +#[repr(C)] +pub struct FILE_STANDARD_INFO { + pub AllocationSize: i64, + pub EndOfFile: i64, + pub NumberOfLinks: u32, + pub DeletePending: BOOLEAN, + pub Directory: BOOLEAN, +} +impl ::core::marker::Copy for FILE_STANDARD_INFO {} +impl ::core::clone::Clone for FILE_STANDARD_INFO { + fn clone(&self) -> Self { + *self + } +} +pub const FILE_SUPERSEDE: NTCREATEFILE_CREATE_DISPOSITION = 0u32; +pub const FILE_SYNCHRONOUS_IO_ALERT: NTCREATEFILE_CREATE_OPTIONS = 16u32; +pub const FILE_SYNCHRONOUS_IO_NONALERT: NTCREATEFILE_CREATE_OPTIONS = 32u32; +pub const FILE_TRAVERSE: FILE_ACCESS_RIGHTS = 32u32; +pub type FILE_TYPE = u32; +pub const FILE_TYPE_CHAR: FILE_TYPE = 2u32; +pub const FILE_TYPE_DISK: FILE_TYPE = 1u32; +pub const FILE_TYPE_PIPE: FILE_TYPE = 3u32; +pub const FILE_TYPE_REMOTE: FILE_TYPE = 32768u32; +pub const FILE_TYPE_UNKNOWN: FILE_TYPE = 0u32; +pub const FILE_WRITE_ATTRIBUTES: FILE_ACCESS_RIGHTS = 256u32; +pub const FILE_WRITE_DATA: FILE_ACCESS_RIGHTS = 2u32; +pub const FILE_WRITE_EA: FILE_ACCESS_RIGHTS = 16u32; +pub const FILE_WRITE_THROUGH: NTCREATEFILE_CREATE_OPTIONS = 2u32; +pub const FIONBIO: i32 = -2147195266i32; +#[repr(C)] +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +pub struct FLOATING_SAVE_AREA { + pub ControlWord: u32, + pub StatusWord: u32, + pub TagWord: u32, + pub ErrorOffset: u32, + pub ErrorSelector: u32, + pub DataOffset: u32, + pub DataSelector: u32, + pub RegisterArea: [u8; 80], + pub Cr0NpxState: u32, +} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::marker::Copy for FLOATING_SAVE_AREA {} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::clone::Clone for FLOATING_SAVE_AREA { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86")] +pub struct FLOATING_SAVE_AREA { + pub ControlWord: u32, + pub StatusWord: u32, + pub TagWord: u32, + pub ErrorOffset: u32, + pub ErrorSelector: u32, + pub DataOffset: u32, + pub DataSelector: u32, + pub RegisterArea: [u8; 80], + pub Spare0: u32, +} +#[cfg(target_arch = "x86")] +impl ::core::marker::Copy for FLOATING_SAVE_AREA {} +#[cfg(target_arch = "x86")] +impl ::core::clone::Clone for FLOATING_SAVE_AREA { + fn clone(&self) -> Self { + *self + } +} +pub const FORMAT_MESSAGE_ALLOCATE_BUFFER: FORMAT_MESSAGE_OPTIONS = 256u32; +pub const FORMAT_MESSAGE_ARGUMENT_ARRAY: FORMAT_MESSAGE_OPTIONS = 8192u32; +pub const FORMAT_MESSAGE_FROM_HMODULE: FORMAT_MESSAGE_OPTIONS = 2048u32; +pub const FORMAT_MESSAGE_FROM_STRING: FORMAT_MESSAGE_OPTIONS = 1024u32; +pub const FORMAT_MESSAGE_FROM_SYSTEM: FORMAT_MESSAGE_OPTIONS = 4096u32; +pub const FORMAT_MESSAGE_IGNORE_INSERTS: FORMAT_MESSAGE_OPTIONS = 512u32; +pub type FORMAT_MESSAGE_OPTIONS = u32; +pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: i32 = 8014i32; +pub const FSCTL_GET_REPARSE_POINT: u32 = 589992u32; +pub const FSCTL_SET_REPARSE_POINT: u32 = 589988u32; +pub const FileAlignmentInfo: FILE_INFO_BY_HANDLE_CLASS = 17i32; +pub const FileAllocationInfo: FILE_INFO_BY_HANDLE_CLASS = 5i32; +pub const FileAttributeTagInfo: FILE_INFO_BY_HANDLE_CLASS = 9i32; +pub const FileBasicInfo: FILE_INFO_BY_HANDLE_CLASS = 0i32; +pub const FileCaseSensitiveInfo: FILE_INFO_BY_HANDLE_CLASS = 23i32; +pub const FileCompressionInfo: FILE_INFO_BY_HANDLE_CLASS = 8i32; +pub const FileDispositionInfo: FILE_INFO_BY_HANDLE_CLASS = 4i32; +pub const FileDispositionInfoEx: FILE_INFO_BY_HANDLE_CLASS = 21i32; +pub const FileEndOfFileInfo: FILE_INFO_BY_HANDLE_CLASS = 6i32; +pub const FileFullDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 14i32; +pub const FileFullDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 15i32; +pub const FileIdBothDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 10i32; +pub const FileIdBothDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 11i32; +pub const FileIdExtdDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 19i32; +pub const FileIdExtdDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 20i32; +pub const FileIdInfo: FILE_INFO_BY_HANDLE_CLASS = 18i32; +pub const FileIoPriorityHintInfo: FILE_INFO_BY_HANDLE_CLASS = 12i32; +pub const FileNameInfo: FILE_INFO_BY_HANDLE_CLASS = 2i32; +pub const FileNormalizedNameInfo: FILE_INFO_BY_HANDLE_CLASS = 24i32; +pub const FileRemoteProtocolInfo: FILE_INFO_BY_HANDLE_CLASS = 13i32; +pub const FileRenameInfo: FILE_INFO_BY_HANDLE_CLASS = 3i32; +pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32; +pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32; +pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32; +pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32; +pub type FindFileHandle = *mut ::core::ffi::c_void; +pub type GENERIC_ACCESS_RIGHTS = u32; +pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32; +pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32; +pub const GENERIC_READ: GENERIC_ACCESS_RIGHTS = 2147483648u32; +pub const GENERIC_WRITE: GENERIC_ACCESS_RIGHTS = 1073741824u32; +pub type GETFINALPATHNAMEBYHANDLE_FLAGS = u32; +#[repr(C)] +pub struct GUID { + pub data1: u32, + pub data2: u16, + pub data3: u16, + pub data4: [u8; 8], +} +impl GUID { + pub const fn from_u128(uuid: u128) -> Self { + Self { + data1: (uuid >> 96) as u32, + data2: (uuid >> 80 & 0xffff) as u16, + data3: (uuid >> 64 & 0xffff) as u16, + data4: (uuid as u64).to_be_bytes(), + } + } +} +impl ::core::marker::Copy for GUID {} +impl ::core::clone::Clone for GUID { + fn clone(&self) -> Self { + *self + } +} +pub type HANDLE = *mut ::core::ffi::c_void; +pub type HANDLE_FLAGS = u32; +pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32; +pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32; +pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32; +pub type HMODULE = *mut ::core::ffi::c_void; +pub type HRESULT = i32; +pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32; +#[repr(C)] +pub struct IN6_ADDR { + pub u: IN6_ADDR_0, +} +impl ::core::marker::Copy for IN6_ADDR {} +impl ::core::clone::Clone for IN6_ADDR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union IN6_ADDR_0 { + pub Byte: [u8; 16], + pub Word: [u16; 8], +} +impl ::core::marker::Copy for IN6_ADDR_0 {} +impl ::core::clone::Clone for IN6_ADDR_0 { + fn clone(&self) -> Self { + *self + } +} +pub const INFINITE: u32 = 4294967295u32; +pub const INHERIT_CALLER_PRIORITY: PROCESS_CREATION_FLAGS = 131072u32; +pub const INHERIT_PARENT_AFFINITY: PROCESS_CREATION_FLAGS = 65536u32; +pub const INIT_ONCE_INIT_FAILED: u32 = 4u32; +pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32; +pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _); +pub const INVALID_SOCKET: SOCKET = -1i32 as _; +#[repr(C)] +pub struct IN_ADDR { + pub S_un: IN_ADDR_0, +} +impl ::core::marker::Copy for IN_ADDR {} +impl ::core::clone::Clone for IN_ADDR { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union IN_ADDR_0 { + pub S_un_b: IN_ADDR_0_0, + pub S_un_w: IN_ADDR_0_1, + pub S_addr: u32, +} +impl ::core::marker::Copy for IN_ADDR_0 {} +impl ::core::clone::Clone for IN_ADDR_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct IN_ADDR_0_0 { + pub s_b1: u8, + pub s_b2: u8, + pub s_b3: u8, + pub s_b4: u8, +} +impl ::core::marker::Copy for IN_ADDR_0_0 {} +impl ::core::clone::Clone for IN_ADDR_0_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct IN_ADDR_0_1 { + pub s_w1: u16, + pub s_w2: u16, +} +impl ::core::marker::Copy for IN_ADDR_0_1 {} +impl ::core::clone::Clone for IN_ADDR_0_1 { + fn clone(&self) -> Self { + *self + } +} +pub const IO_REPARSE_TAG_MOUNT_POINT: u32 = 2684354563u32; +pub const IO_REPARSE_TAG_SYMLINK: u32 = 2684354572u32; +#[repr(C)] +pub struct IO_STATUS_BLOCK { + pub Anonymous: IO_STATUS_BLOCK_0, + pub Information: usize, +} +impl ::core::marker::Copy for IO_STATUS_BLOCK {} +impl ::core::clone::Clone for IO_STATUS_BLOCK { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union IO_STATUS_BLOCK_0 { + pub Status: NTSTATUS, + pub Pointer: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for IO_STATUS_BLOCK_0 {} +impl ::core::clone::Clone for IO_STATUS_BLOCK_0 { + fn clone(&self) -> Self { + *self + } +} +pub type IPPROTO = i32; +pub const IPPROTO_AH: IPPROTO = 51i32; +pub const IPPROTO_CBT: IPPROTO = 7i32; +pub const IPPROTO_DSTOPTS: IPPROTO = 60i32; +pub const IPPROTO_EGP: IPPROTO = 8i32; +pub const IPPROTO_ESP: IPPROTO = 50i32; +pub const IPPROTO_FRAGMENT: IPPROTO = 44i32; +pub const IPPROTO_GGP: IPPROTO = 3i32; +pub const IPPROTO_HOPOPTS: IPPROTO = 0i32; +pub const IPPROTO_ICLFXBM: IPPROTO = 78i32; +pub const IPPROTO_ICMP: IPPROTO = 1i32; +pub const IPPROTO_ICMPV6: IPPROTO = 58i32; +pub const IPPROTO_IDP: IPPROTO = 22i32; +pub const IPPROTO_IGMP: IPPROTO = 2i32; +pub const IPPROTO_IGP: IPPROTO = 9i32; +pub const IPPROTO_IP: IPPROTO = 0i32; +pub const IPPROTO_IPV4: IPPROTO = 4i32; +pub const IPPROTO_IPV6: IPPROTO = 41i32; +pub const IPPROTO_L2TP: IPPROTO = 115i32; +pub const IPPROTO_MAX: IPPROTO = 256i32; +pub const IPPROTO_ND: IPPROTO = 77i32; +pub const IPPROTO_NONE: IPPROTO = 59i32; +pub const IPPROTO_PGM: IPPROTO = 113i32; +pub const IPPROTO_PIM: IPPROTO = 103i32; +pub const IPPROTO_PUP: IPPROTO = 12i32; +pub const IPPROTO_RAW: IPPROTO = 255i32; +pub const IPPROTO_RDP: IPPROTO = 27i32; +pub const IPPROTO_RESERVED_IPSEC: IPPROTO = 258i32; +pub const IPPROTO_RESERVED_IPSECOFFLOAD: IPPROTO = 259i32; +pub const IPPROTO_RESERVED_MAX: IPPROTO = 261i32; +pub const IPPROTO_RESERVED_RAW: IPPROTO = 257i32; +pub const IPPROTO_RESERVED_WNV: IPPROTO = 260i32; +pub const IPPROTO_RM: IPPROTO = 113i32; +pub const IPPROTO_ROUTING: IPPROTO = 43i32; +pub const IPPROTO_SCTP: IPPROTO = 132i32; +pub const IPPROTO_ST: IPPROTO = 5i32; +pub const IPPROTO_TCP: IPPROTO = 6i32; +pub const IPPROTO_UDP: IPPROTO = 17i32; +pub const IPV6_ADD_MEMBERSHIP: i32 = 12i32; +pub const IPV6_DROP_MEMBERSHIP: i32 = 13i32; +#[repr(C)] +pub struct IPV6_MREQ { + pub ipv6mr_multiaddr: IN6_ADDR, + pub ipv6mr_interface: u32, +} +impl ::core::marker::Copy for IPV6_MREQ {} +impl ::core::clone::Clone for IPV6_MREQ { + fn clone(&self) -> Self { + *self + } +} +pub const IPV6_MULTICAST_LOOP: i32 = 11i32; +pub const IPV6_V6ONLY: i32 = 27i32; +pub const IP_ADD_MEMBERSHIP: i32 = 12i32; +pub const IP_DROP_MEMBERSHIP: i32 = 13i32; +#[repr(C)] +pub struct IP_MREQ { + pub imr_multiaddr: IN_ADDR, + pub imr_interface: IN_ADDR, +} +impl ::core::marker::Copy for IP_MREQ {} +impl ::core::clone::Clone for IP_MREQ { + fn clone(&self) -> Self { + *self + } +} +pub const IP_MULTICAST_LOOP: i32 = 11i32; +pub const IP_MULTICAST_TTL: i32 = 10i32; +pub const IP_TTL: i32 = 4i32; +#[repr(C)] +pub struct LINGER { + pub l_onoff: u16, + pub l_linger: u16, +} +impl ::core::marker::Copy for LINGER {} +impl ::core::clone::Clone for LINGER { + fn clone(&self) -> Self { + *self + } +} +pub type LPOVERLAPPED_COMPLETION_ROUTINE = ::core::option::Option< + unsafe extern "system" fn( + dwerrorcode: u32, + dwnumberofbytestransfered: u32, + lpoverlapped: *mut OVERLAPPED, + ) -> (), +>; +pub type LPPROGRESS_ROUTINE = ::core::option::Option< + unsafe extern "system" fn( + totalfilesize: i64, + totalbytestransferred: i64, + streamsize: i64, + streambytestransferred: i64, + dwstreamnumber: u32, + dwcallbackreason: LPPROGRESS_ROUTINE_CALLBACK_REASON, + hsourcefile: HANDLE, + hdestinationfile: HANDLE, + lpdata: *const ::core::ffi::c_void, + ) -> u32, +>; +pub type LPPROGRESS_ROUTINE_CALLBACK_REASON = u32; +pub type LPTHREAD_START_ROUTINE = ::core::option::Option< + unsafe extern "system" fn(lpthreadparameter: *mut ::core::ffi::c_void) -> u32, +>; +pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = ::core::option::Option< + unsafe extern "system" fn( + dwerror: u32, + cbtransferred: u32, + lpoverlapped: *mut OVERLAPPED, + dwflags: u32, + ) -> (), +>; +#[repr(C)] +pub struct M128A { + pub Low: u64, + pub High: i64, +} +impl ::core::marker::Copy for M128A {} +impl ::core::clone::Clone for M128A { + fn clone(&self) -> Self { + *self + } +} +pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: u32 = 16384u32; +pub const MAX_PATH: u32 = 260u32; +pub const MB_COMPOSITE: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 2u32; +pub const MB_ERR_INVALID_CHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 8u32; +pub const MB_PRECOMPOSED: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 1u32; +pub const MB_USEGLYPHCHARS: MULTI_BYTE_TO_WIDE_CHAR_FLAGS = 4u32; +pub const MOVEFILE_COPY_ALLOWED: MOVE_FILE_FLAGS = 2u32; +pub const MOVEFILE_CREATE_HARDLINK: MOVE_FILE_FLAGS = 16u32; +pub const MOVEFILE_DELAY_UNTIL_REBOOT: MOVE_FILE_FLAGS = 4u32; +pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE: MOVE_FILE_FLAGS = 32u32; +pub const MOVEFILE_REPLACE_EXISTING: MOVE_FILE_FLAGS = 1u32; +pub const MOVEFILE_WRITE_THROUGH: MOVE_FILE_FLAGS = 8u32; +pub type MOVE_FILE_FLAGS = u32; +pub const MSG_DONTROUTE: SEND_RECV_FLAGS = 4i32; +pub const MSG_OOB: SEND_RECV_FLAGS = 1i32; +pub const MSG_PEEK: SEND_RECV_FLAGS = 2i32; +pub const MSG_PUSH_IMMEDIATE: SEND_RECV_FLAGS = 32i32; +pub const MSG_WAITALL: SEND_RECV_FLAGS = 8i32; +pub type MULTI_BYTE_TO_WIDE_CHAR_FLAGS = u32; +pub const MaximumFileInfoByHandleClass: FILE_INFO_BY_HANDLE_CLASS = 25i32; +pub type NAMED_PIPE_MODE = u32; +pub const NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32u32; +pub const NO_ERROR: WIN32_ERROR = 0u32; +pub type NTCREATEFILE_CREATE_DISPOSITION = u32; +pub type NTCREATEFILE_CREATE_OPTIONS = u32; +pub type NTSTATUS = i32; +#[repr(C)] +pub struct OBJECT_ATTRIBUTES { + pub Length: u32, + pub RootDirectory: HANDLE, + pub ObjectName: *mut UNICODE_STRING, + pub Attributes: u32, + pub SecurityDescriptor: *mut ::core::ffi::c_void, + pub SecurityQualityOfService: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for OBJECT_ATTRIBUTES {} +impl ::core::clone::Clone for OBJECT_ATTRIBUTES { + fn clone(&self) -> Self { + *self + } +} +pub const OBJ_DONT_REPARSE: i32 = 4096i32; +pub const OPEN_ALWAYS: FILE_CREATION_DISPOSITION = 4u32; +pub const OPEN_EXISTING: FILE_CREATION_DISPOSITION = 3u32; +#[repr(C)] +pub struct OVERLAPPED { + pub Internal: usize, + pub InternalHigh: usize, + pub Anonymous: OVERLAPPED_0, + pub hEvent: HANDLE, +} +impl ::core::marker::Copy for OVERLAPPED {} +impl ::core::clone::Clone for OVERLAPPED { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union OVERLAPPED_0 { + pub Anonymous: OVERLAPPED_0_0, + pub Pointer: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for OVERLAPPED_0 {} +impl ::core::clone::Clone for OVERLAPPED_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct OVERLAPPED_0_0 { + pub Offset: u32, + pub OffsetHigh: u32, +} +impl ::core::marker::Copy for OVERLAPPED_0_0 {} +impl ::core::clone::Clone for OVERLAPPED_0_0 { + fn clone(&self) -> Self { + *self + } +} +pub type PCSTR = *const u8; +pub type PCWSTR = *const u16; +pub type PIO_APC_ROUTINE = ::core::option::Option< + unsafe extern "system" fn( + apccontext: *const ::core::ffi::c_void, + iostatusblock: *const IO_STATUS_BLOCK, + reserved: u32, + ) -> (), +>; +pub const PIPE_ACCEPT_REMOTE_CLIENTS: NAMED_PIPE_MODE = 0u32; +pub const PIPE_ACCESS_DUPLEX: FILE_FLAGS_AND_ATTRIBUTES = 3u32; +pub const PIPE_ACCESS_INBOUND: FILE_FLAGS_AND_ATTRIBUTES = 1u32; +pub const PIPE_ACCESS_OUTBOUND: FILE_FLAGS_AND_ATTRIBUTES = 2u32; +pub const PIPE_CLIENT_END: NAMED_PIPE_MODE = 0u32; +pub const PIPE_NOWAIT: NAMED_PIPE_MODE = 1u32; +pub const PIPE_READMODE_BYTE: NAMED_PIPE_MODE = 0u32; +pub const PIPE_READMODE_MESSAGE: NAMED_PIPE_MODE = 2u32; +pub const PIPE_REJECT_REMOTE_CLIENTS: NAMED_PIPE_MODE = 8u32; +pub const PIPE_SERVER_END: NAMED_PIPE_MODE = 1u32; +pub const PIPE_TYPE_BYTE: NAMED_PIPE_MODE = 0u32; +pub const PIPE_TYPE_MESSAGE: NAMED_PIPE_MODE = 4u32; +pub const PIPE_WAIT: NAMED_PIPE_MODE = 0u32; +pub type PROCESSOR_ARCHITECTURE = u16; +pub type PROCESS_CREATION_FLAGS = u32; +#[repr(C)] +pub struct PROCESS_INFORMATION { + pub hProcess: HANDLE, + pub hThread: HANDLE, + pub dwProcessId: u32, + pub dwThreadId: u32, +} +impl ::core::marker::Copy for PROCESS_INFORMATION {} +impl ::core::clone::Clone for PROCESS_INFORMATION { + fn clone(&self) -> Self { + *self + } +} +pub const PROCESS_MODE_BACKGROUND_BEGIN: PROCESS_CREATION_FLAGS = 1048576u32; +pub const PROCESS_MODE_BACKGROUND_END: PROCESS_CREATION_FLAGS = 2097152u32; +pub const PROFILE_KERNEL: PROCESS_CREATION_FLAGS = 536870912u32; +pub const PROFILE_SERVER: PROCESS_CREATION_FLAGS = 1073741824u32; +pub const PROFILE_USER: PROCESS_CREATION_FLAGS = 268435456u32; +pub const PROGRESS_CONTINUE: u32 = 0u32; +pub type PSTR = *mut u8; +pub type PVECTORED_EXCEPTION_HANDLER = ::core::option::Option< + unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32, +>; +pub type PWSTR = *mut u16; +pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32; +pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32; +#[repr(C)] +pub struct RTL_CONDITION_VARIABLE { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for RTL_CONDITION_VARIABLE {} +impl ::core::clone::Clone for RTL_CONDITION_VARIABLE { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union RTL_RUN_ONCE { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for RTL_RUN_ONCE {} +impl ::core::clone::Clone for RTL_RUN_ONCE { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct RTL_SRWLOCK { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for RTL_SRWLOCK {} +impl ::core::clone::Clone for RTL_SRWLOCK { + fn clone(&self) -> Self { + *self + } +} +pub const SD_BOTH: WINSOCK_SHUTDOWN_HOW = 2i32; +pub const SD_RECEIVE: WINSOCK_SHUTDOWN_HOW = 0i32; +pub const SD_SEND: WINSOCK_SHUTDOWN_HOW = 1i32; +pub const SECURITY_ANONYMOUS: FILE_FLAGS_AND_ATTRIBUTES = 0u32; +#[repr(C)] +pub struct SECURITY_ATTRIBUTES { + pub nLength: u32, + pub lpSecurityDescriptor: *mut ::core::ffi::c_void, + pub bInheritHandle: BOOL, +} +impl ::core::marker::Copy for SECURITY_ATTRIBUTES {} +impl ::core::clone::Clone for SECURITY_ATTRIBUTES { + fn clone(&self) -> Self { + *self + } +} +pub const SECURITY_CONTEXT_TRACKING: FILE_FLAGS_AND_ATTRIBUTES = 262144u32; +pub const SECURITY_DELEGATION: FILE_FLAGS_AND_ATTRIBUTES = 196608u32; +pub const SECURITY_EFFECTIVE_ONLY: FILE_FLAGS_AND_ATTRIBUTES = 524288u32; +pub const SECURITY_IDENTIFICATION: FILE_FLAGS_AND_ATTRIBUTES = 65536u32; +pub const SECURITY_IMPERSONATION: FILE_FLAGS_AND_ATTRIBUTES = 131072u32; +pub const SECURITY_SQOS_PRESENT: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32; +pub const SECURITY_VALID_SQOS_FLAGS: FILE_FLAGS_AND_ATTRIBUTES = 2031616u32; +pub type SEND_RECV_FLAGS = i32; +pub type SET_FILE_POINTER_MOVE_METHOD = u32; +#[repr(C)] +pub struct SOCKADDR { + pub sa_family: ADDRESS_FAMILY, + pub sa_data: [u8; 14], +} +impl ::core::marker::Copy for SOCKADDR {} +impl ::core::clone::Clone for SOCKADDR { + fn clone(&self) -> Self { + *self + } +} +#[cfg(target_pointer_width = "32")] +pub type SOCKET = u32; +#[cfg(target_pointer_width = "64")] +pub type SOCKET = u64; +pub const SOCKET_ERROR: i32 = -1i32; +pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32; +pub const SOCK_RAW: WINSOCK_SOCKET_TYPE = 3i32; +pub const SOCK_RDM: WINSOCK_SOCKET_TYPE = 4i32; +pub const SOCK_SEQPACKET: WINSOCK_SOCKET_TYPE = 5i32; +pub const SOCK_STREAM: WINSOCK_SOCKET_TYPE = 1i32; +pub const SOL_SOCKET: i32 = 65535i32; +pub const SO_BROADCAST: i32 = 32i32; +pub const SO_ERROR: i32 = 4103i32; +pub const SO_LINGER: i32 = 128i32; +pub const SO_RCVTIMEO: i32 = 4102i32; +pub const SO_SNDTIMEO: i32 = 4101i32; +pub const SPECIFIC_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 65535u32; +pub const STACK_SIZE_PARAM_IS_A_RESERVATION: THREAD_CREATION_FLAGS = 65536u32; +pub const STANDARD_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 2031616u32; +pub const STANDARD_RIGHTS_EXECUTE: FILE_ACCESS_RIGHTS = 131072u32; +pub const STANDARD_RIGHTS_READ: FILE_ACCESS_RIGHTS = 131072u32; +pub const STANDARD_RIGHTS_REQUIRED: FILE_ACCESS_RIGHTS = 983040u32; +pub const STANDARD_RIGHTS_WRITE: FILE_ACCESS_RIGHTS = 131072u32; +pub const STARTF_FORCEOFFFEEDBACK: STARTUPINFOW_FLAGS = 128u32; +pub const STARTF_FORCEONFEEDBACK: STARTUPINFOW_FLAGS = 64u32; +pub const STARTF_PREVENTPINNING: STARTUPINFOW_FLAGS = 8192u32; +pub const STARTF_RUNFULLSCREEN: STARTUPINFOW_FLAGS = 32u32; +pub const STARTF_TITLEISAPPID: STARTUPINFOW_FLAGS = 4096u32; +pub const STARTF_TITLEISLINKNAME: STARTUPINFOW_FLAGS = 2048u32; +pub const STARTF_UNTRUSTEDSOURCE: STARTUPINFOW_FLAGS = 32768u32; +pub const STARTF_USECOUNTCHARS: STARTUPINFOW_FLAGS = 8u32; +pub const STARTF_USEFILLATTRIBUTE: STARTUPINFOW_FLAGS = 16u32; +pub const STARTF_USEHOTKEY: STARTUPINFOW_FLAGS = 512u32; +pub const STARTF_USEPOSITION: STARTUPINFOW_FLAGS = 4u32; +pub const STARTF_USESHOWWINDOW: STARTUPINFOW_FLAGS = 1u32; +pub const STARTF_USESIZE: STARTUPINFOW_FLAGS = 2u32; +pub const STARTF_USESTDHANDLES: STARTUPINFOW_FLAGS = 256u32; +#[repr(C)] +pub struct STARTUPINFOW { + pub cb: u32, + pub lpReserved: PWSTR, + pub lpDesktop: PWSTR, + pub lpTitle: PWSTR, + pub dwX: u32, + pub dwY: u32, + pub dwXSize: u32, + pub dwYSize: u32, + pub dwXCountChars: u32, + pub dwYCountChars: u32, + pub dwFillAttribute: u32, + pub dwFlags: STARTUPINFOW_FLAGS, + pub wShowWindow: u16, + pub cbReserved2: u16, + pub lpReserved2: *mut u8, + pub hStdInput: HANDLE, + pub hStdOutput: HANDLE, + pub hStdError: HANDLE, +} +impl ::core::marker::Copy for STARTUPINFOW {} +impl ::core::clone::Clone for STARTUPINFOW { + fn clone(&self) -> Self { + *self + } +} +pub type STARTUPINFOW_FLAGS = u32; +pub const STATUS_DELETE_PENDING: NTSTATUS = -1073741738i32; +pub const STATUS_END_OF_FILE: NTSTATUS = -1073741807i32; +pub const STATUS_INVALID_PARAMETER: NTSTATUS = -1073741811i32; +pub const STATUS_PENDING: NTSTATUS = 259i32; +pub const STATUS_SUCCESS: NTSTATUS = 0i32; +pub const STD_ERROR_HANDLE: STD_HANDLE = 4294967284u32; +pub type STD_HANDLE = u32; +pub const STD_INPUT_HANDLE: STD_HANDLE = 4294967286u32; +pub const STD_OUTPUT_HANDLE: STD_HANDLE = 4294967285u32; +pub type SYMBOLIC_LINK_FLAGS = u32; +pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: SYMBOLIC_LINK_FLAGS = 2u32; +pub const SYMBOLIC_LINK_FLAG_DIRECTORY: SYMBOLIC_LINK_FLAGS = 1u32; +pub const SYMLINK_FLAG_RELATIVE: u32 = 1u32; +pub const SYNCHRONIZE: FILE_ACCESS_RIGHTS = 1048576u32; +#[repr(C)] +pub struct SYSTEM_INFO { + pub Anonymous: SYSTEM_INFO_0, + pub dwPageSize: u32, + pub lpMinimumApplicationAddress: *mut ::core::ffi::c_void, + pub lpMaximumApplicationAddress: *mut ::core::ffi::c_void, + pub dwActiveProcessorMask: usize, + pub dwNumberOfProcessors: u32, + pub dwProcessorType: u32, + pub dwAllocationGranularity: u32, + pub wProcessorLevel: u16, + pub wProcessorRevision: u16, +} +impl ::core::marker::Copy for SYSTEM_INFO {} +impl ::core::clone::Clone for SYSTEM_INFO { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub union SYSTEM_INFO_0 { + pub dwOemId: u32, + pub Anonymous: SYSTEM_INFO_0_0, +} +impl ::core::marker::Copy for SYSTEM_INFO_0 {} +impl ::core::clone::Clone for SYSTEM_INFO_0 { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct SYSTEM_INFO_0_0 { + pub wProcessorArchitecture: PROCESSOR_ARCHITECTURE, + pub wReserved: u16, +} +impl ::core::marker::Copy for SYSTEM_INFO_0_0 {} +impl ::core::clone::Clone for SYSTEM_INFO_0_0 { + fn clone(&self) -> Self { + *self + } +} +pub const TCP_NODELAY: i32 = 1i32; +pub const THREAD_CREATE_RUN_IMMEDIATELY: THREAD_CREATION_FLAGS = 0u32; +pub const THREAD_CREATE_SUSPENDED: THREAD_CREATION_FLAGS = 4u32; +pub type THREAD_CREATION_FLAGS = u32; +#[repr(C)] +pub struct TIMEVAL { + pub tv_sec: i32, + pub tv_usec: i32, +} +impl ::core::marker::Copy for TIMEVAL {} +impl ::core::clone::Clone for TIMEVAL { + fn clone(&self) -> Self { + *self + } +} +pub const TLS_OUT_OF_INDEXES: u32 = 4294967295u32; +pub type TOKEN_ACCESS_MASK = u32; +pub const TOKEN_ACCESS_PSEUDO_HANDLE: TOKEN_ACCESS_MASK = 24u32; +pub const TOKEN_ACCESS_PSEUDO_HANDLE_WIN8: TOKEN_ACCESS_MASK = 24u32; +pub const TOKEN_ACCESS_SYSTEM_SECURITY: TOKEN_ACCESS_MASK = 16777216u32; +pub const TOKEN_ADJUST_DEFAULT: TOKEN_ACCESS_MASK = 128u32; +pub const TOKEN_ADJUST_GROUPS: TOKEN_ACCESS_MASK = 64u32; +pub const TOKEN_ADJUST_PRIVILEGES: TOKEN_ACCESS_MASK = 32u32; +pub const TOKEN_ADJUST_SESSIONID: TOKEN_ACCESS_MASK = 256u32; +pub const TOKEN_ALL_ACCESS: TOKEN_ACCESS_MASK = 983551u32; +pub const TOKEN_ASSIGN_PRIMARY: TOKEN_ACCESS_MASK = 1u32; +pub const TOKEN_DELETE: TOKEN_ACCESS_MASK = 65536u32; +pub const TOKEN_DUPLICATE: TOKEN_ACCESS_MASK = 2u32; +pub const TOKEN_EXECUTE: TOKEN_ACCESS_MASK = 131072u32; +pub const TOKEN_IMPERSONATE: TOKEN_ACCESS_MASK = 4u32; +pub const TOKEN_QUERY: TOKEN_ACCESS_MASK = 8u32; +pub const TOKEN_QUERY_SOURCE: TOKEN_ACCESS_MASK = 16u32; +pub const TOKEN_READ: TOKEN_ACCESS_MASK = 131080u32; +pub const TOKEN_READ_CONTROL: TOKEN_ACCESS_MASK = 131072u32; +pub const TOKEN_TRUST_CONSTRAINT_MASK: TOKEN_ACCESS_MASK = 131096u32; +pub const TOKEN_WRITE: TOKEN_ACCESS_MASK = 131296u32; +pub const TOKEN_WRITE_DAC: TOKEN_ACCESS_MASK = 262144u32; +pub const TOKEN_WRITE_OWNER: TOKEN_ACCESS_MASK = 524288u32; +pub const TRUE: BOOL = 1i32; +pub const TRUNCATE_EXISTING: FILE_CREATION_DISPOSITION = 5u32; +#[repr(C)] +pub struct UNICODE_STRING { + pub Length: u16, + pub MaximumLength: u16, + pub Buffer: PWSTR, +} +impl ::core::marker::Copy for UNICODE_STRING {} +impl ::core::clone::Clone for UNICODE_STRING { + fn clone(&self) -> Self { + *self + } +} +pub const VOLUME_NAME_DOS: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32; +pub const VOLUME_NAME_GUID: GETFINALPATHNAMEBYHANDLE_FLAGS = 1u32; +pub const VOLUME_NAME_NONE: GETFINALPATHNAMEBYHANDLE_FLAGS = 4u32; +pub const WAIT_ABANDONED: WIN32_ERROR = 128u32; +pub const WAIT_ABANDONED_0: WIN32_ERROR = 128u32; +pub const WAIT_FAILED: WIN32_ERROR = 4294967295u32; +pub const WAIT_IO_COMPLETION: WIN32_ERROR = 192u32; +pub const WAIT_OBJECT_0: WIN32_ERROR = 0u32; +pub const WAIT_TIMEOUT: WIN32_ERROR = 258u32; +pub const WC_ERR_INVALID_CHARS: u32 = 128u32; +pub type WIN32_ERROR = u32; +#[repr(C)] +pub struct WIN32_FIND_DATAW { + pub dwFileAttributes: u32, + pub ftCreationTime: FILETIME, + pub ftLastAccessTime: FILETIME, + pub ftLastWriteTime: FILETIME, + pub nFileSizeHigh: u32, + pub nFileSizeLow: u32, + pub dwReserved0: u32, + pub dwReserved1: u32, + pub cFileName: [u16; 260], + pub cAlternateFileName: [u16; 14], +} +impl ::core::marker::Copy for WIN32_FIND_DATAW {} +impl ::core::clone::Clone for WIN32_FIND_DATAW { + fn clone(&self) -> Self { + *self + } +} +pub type WINSOCK_SHUTDOWN_HOW = i32; +pub type WINSOCK_SOCKET_TYPE = i32; +pub const WRITE_DAC: FILE_ACCESS_RIGHTS = 262144u32; +pub const WRITE_OWNER: FILE_ACCESS_RIGHTS = 524288u32; +pub const WSABASEERR: WSA_ERROR = 10000i32; +#[repr(C)] +pub struct WSABUF { + pub len: u32, + pub buf: PSTR, +} +impl ::core::marker::Copy for WSABUF {} +impl ::core::clone::Clone for WSABUF { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +pub struct WSADATA { + pub wVersion: u16, + pub wHighVersion: u16, + pub iMaxSockets: u16, + pub iMaxUdpDg: u16, + pub lpVendorInfo: PSTR, + pub szDescription: [u8; 257], + pub szSystemStatus: [u8; 129], +} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::marker::Copy for WSADATA {} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::clone::Clone for WSADATA { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86")] +pub struct WSADATA { + pub wVersion: u16, + pub wHighVersion: u16, + pub szDescription: [u8; 257], + pub szSystemStatus: [u8; 129], + pub iMaxSockets: u16, + pub iMaxUdpDg: u16, + pub lpVendorInfo: PSTR, +} +#[cfg(target_arch = "x86")] +impl ::core::marker::Copy for WSADATA {} +#[cfg(target_arch = "x86")] +impl ::core::clone::Clone for WSADATA { + fn clone(&self) -> Self { + *self + } +} +pub const WSAEACCES: WSA_ERROR = 10013i32; +pub const WSAEADDRINUSE: WSA_ERROR = 10048i32; +pub const WSAEADDRNOTAVAIL: WSA_ERROR = 10049i32; +pub const WSAEAFNOSUPPORT: WSA_ERROR = 10047i32; +pub const WSAEALREADY: WSA_ERROR = 10037i32; +pub const WSAEBADF: WSA_ERROR = 10009i32; +pub const WSAECANCELLED: WSA_ERROR = 10103i32; +pub const WSAECONNABORTED: WSA_ERROR = 10053i32; +pub const WSAECONNREFUSED: WSA_ERROR = 10061i32; +pub const WSAECONNRESET: WSA_ERROR = 10054i32; +pub const WSAEDESTADDRREQ: WSA_ERROR = 10039i32; +pub const WSAEDISCON: WSA_ERROR = 10101i32; +pub const WSAEDQUOT: WSA_ERROR = 10069i32; +pub const WSAEFAULT: WSA_ERROR = 10014i32; +pub const WSAEHOSTDOWN: WSA_ERROR = 10064i32; +pub const WSAEHOSTUNREACH: WSA_ERROR = 10065i32; +pub const WSAEINPROGRESS: WSA_ERROR = 10036i32; +pub const WSAEINTR: WSA_ERROR = 10004i32; +pub const WSAEINVAL: WSA_ERROR = 10022i32; +pub const WSAEINVALIDPROCTABLE: WSA_ERROR = 10104i32; +pub const WSAEINVALIDPROVIDER: WSA_ERROR = 10105i32; +pub const WSAEISCONN: WSA_ERROR = 10056i32; +pub const WSAELOOP: WSA_ERROR = 10062i32; +pub const WSAEMFILE: WSA_ERROR = 10024i32; +pub const WSAEMSGSIZE: WSA_ERROR = 10040i32; +pub const WSAENAMETOOLONG: WSA_ERROR = 10063i32; +pub const WSAENETDOWN: WSA_ERROR = 10050i32; +pub const WSAENETRESET: WSA_ERROR = 10052i32; +pub const WSAENETUNREACH: WSA_ERROR = 10051i32; +pub const WSAENOBUFS: WSA_ERROR = 10055i32; +pub const WSAENOMORE: WSA_ERROR = 10102i32; +pub const WSAENOPROTOOPT: WSA_ERROR = 10042i32; +pub const WSAENOTCONN: WSA_ERROR = 10057i32; +pub const WSAENOTEMPTY: WSA_ERROR = 10066i32; +pub const WSAENOTSOCK: WSA_ERROR = 10038i32; +pub const WSAEOPNOTSUPP: WSA_ERROR = 10045i32; +pub const WSAEPFNOSUPPORT: WSA_ERROR = 10046i32; +pub const WSAEPROCLIM: WSA_ERROR = 10067i32; +pub const WSAEPROTONOSUPPORT: WSA_ERROR = 10043i32; +pub const WSAEPROTOTYPE: WSA_ERROR = 10041i32; +pub const WSAEPROVIDERFAILEDINIT: WSA_ERROR = 10106i32; +pub const WSAEREFUSED: WSA_ERROR = 10112i32; +pub const WSAEREMOTE: WSA_ERROR = 10071i32; +pub const WSAESHUTDOWN: WSA_ERROR = 10058i32; +pub const WSAESOCKTNOSUPPORT: WSA_ERROR = 10044i32; +pub const WSAESTALE: WSA_ERROR = 10070i32; +pub const WSAETIMEDOUT: WSA_ERROR = 10060i32; +pub const WSAETOOMANYREFS: WSA_ERROR = 10059i32; +pub const WSAEUSERS: WSA_ERROR = 10068i32; +pub const WSAEWOULDBLOCK: WSA_ERROR = 10035i32; +pub const WSAHOST_NOT_FOUND: WSA_ERROR = 11001i32; +pub const WSANOTINITIALISED: WSA_ERROR = 10093i32; +pub const WSANO_DATA: WSA_ERROR = 11004i32; +pub const WSANO_RECOVERY: WSA_ERROR = 11003i32; +#[repr(C)] +pub struct WSAPROTOCOLCHAIN { + pub ChainLen: i32, + pub ChainEntries: [u32; 7], +} +impl ::core::marker::Copy for WSAPROTOCOLCHAIN {} +impl ::core::clone::Clone for WSAPROTOCOLCHAIN { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +pub struct WSAPROTOCOL_INFOW { + pub dwServiceFlags1: u32, + pub dwServiceFlags2: u32, + pub dwServiceFlags3: u32, + pub dwServiceFlags4: u32, + pub dwProviderFlags: u32, + pub ProviderId: GUID, + pub dwCatalogEntryId: u32, + pub ProtocolChain: WSAPROTOCOLCHAIN, + pub iVersion: i32, + pub iAddressFamily: i32, + pub iMaxSockAddr: i32, + pub iMinSockAddr: i32, + pub iSocketType: i32, + pub iProtocol: i32, + pub iProtocolMaxOffset: i32, + pub iNetworkByteOrder: i32, + pub iSecurityScheme: i32, + pub dwMessageSize: u32, + pub dwProviderReserved: u32, + pub szProtocol: [u16; 256], +} +impl ::core::marker::Copy for WSAPROTOCOL_INFOW {} +impl ::core::clone::Clone for WSAPROTOCOL_INFOW { + fn clone(&self) -> Self { + *self + } +} +pub const WSASERVICE_NOT_FOUND: WSA_ERROR = 10108i32; +pub const WSASYSCALLFAILURE: WSA_ERROR = 10107i32; +pub const WSASYSNOTREADY: WSA_ERROR = 10091i32; +pub const WSATRY_AGAIN: WSA_ERROR = 11002i32; +pub const WSATYPE_NOT_FOUND: WSA_ERROR = 10109i32; +pub const WSAVERNOTSUPPORTED: WSA_ERROR = 10092i32; +pub type WSA_ERROR = i32; +pub const WSA_E_CANCELLED: WSA_ERROR = 10111i32; +pub const WSA_E_NO_MORE: WSA_ERROR = 10110i32; +pub const WSA_FLAG_NO_HANDLE_INHERIT: u32 = 128u32; +pub const WSA_FLAG_OVERLAPPED: u32 = 1u32; +pub const WSA_INVALID_HANDLE: WSA_ERROR = 6i32; +pub const WSA_INVALID_PARAMETER: WSA_ERROR = 87i32; +pub const WSA_IO_INCOMPLETE: WSA_ERROR = 996i32; +pub const WSA_IO_PENDING: WSA_ERROR = 997i32; +pub const WSA_IPSEC_NAME_POLICY_ERROR: WSA_ERROR = 11033i32; +pub const WSA_NOT_ENOUGH_MEMORY: WSA_ERROR = 8i32; +pub const WSA_OPERATION_ABORTED: WSA_ERROR = 995i32; +pub const WSA_QOS_ADMISSION_FAILURE: WSA_ERROR = 11010i32; +pub const WSA_QOS_BAD_OBJECT: WSA_ERROR = 11013i32; +pub const WSA_QOS_BAD_STYLE: WSA_ERROR = 11012i32; +pub const WSA_QOS_EFILTERCOUNT: WSA_ERROR = 11021i32; +pub const WSA_QOS_EFILTERSTYLE: WSA_ERROR = 11019i32; +pub const WSA_QOS_EFILTERTYPE: WSA_ERROR = 11020i32; +pub const WSA_QOS_EFLOWCOUNT: WSA_ERROR = 11023i32; +pub const WSA_QOS_EFLOWDESC: WSA_ERROR = 11026i32; +pub const WSA_QOS_EFLOWSPEC: WSA_ERROR = 11017i32; +pub const WSA_QOS_EOBJLENGTH: WSA_ERROR = 11022i32; +pub const WSA_QOS_EPOLICYOBJ: WSA_ERROR = 11025i32; +pub const WSA_QOS_EPROVSPECBUF: WSA_ERROR = 11018i32; +pub const WSA_QOS_EPSFILTERSPEC: WSA_ERROR = 11028i32; +pub const WSA_QOS_EPSFLOWSPEC: WSA_ERROR = 11027i32; +pub const WSA_QOS_ESDMODEOBJ: WSA_ERROR = 11029i32; +pub const WSA_QOS_ESERVICETYPE: WSA_ERROR = 11016i32; +pub const WSA_QOS_ESHAPERATEOBJ: WSA_ERROR = 11030i32; +pub const WSA_QOS_EUNKOWNPSOBJ: WSA_ERROR = 11024i32; +pub const WSA_QOS_GENERIC_ERROR: WSA_ERROR = 11015i32; +pub const WSA_QOS_NO_RECEIVERS: WSA_ERROR = 11008i32; +pub const WSA_QOS_NO_SENDERS: WSA_ERROR = 11007i32; +pub const WSA_QOS_POLICY_FAILURE: WSA_ERROR = 11011i32; +pub const WSA_QOS_RECEIVERS: WSA_ERROR = 11005i32; +pub const WSA_QOS_REQUEST_CONFIRMED: WSA_ERROR = 11009i32; +pub const WSA_QOS_RESERVED_PETYPE: WSA_ERROR = 11031i32; +pub const WSA_QOS_SENDERS: WSA_ERROR = 11006i32; +pub const WSA_QOS_TRAFFIC_CTRL_ERROR: WSA_ERROR = 11014i32; +pub const WSA_SECURE_HOST_NOT_FOUND: WSA_ERROR = 11032i32; +pub const WSA_WAIT_EVENT_0: WSA_ERROR = 0i32; +pub const WSA_WAIT_IO_COMPLETION: WSA_ERROR = 192i32; +#[repr(C)] +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +pub struct XSAVE_FORMAT { + pub ControlWord: u16, + pub StatusWord: u16, + pub TagWord: u8, + pub Reserved1: u8, + pub ErrorOpcode: u16, + pub ErrorOffset: u32, + pub ErrorSelector: u16, + pub Reserved2: u16, + pub DataOffset: u32, + pub DataSelector: u16, + pub Reserved3: u16, + pub MxCsr: u32, + pub MxCsr_Mask: u32, + pub FloatRegisters: [M128A; 8], + pub XmmRegisters: [M128A; 16], + pub Reserved4: [u8; 96], +} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::marker::Copy for XSAVE_FORMAT {} +#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] +impl ::core::clone::Clone for XSAVE_FORMAT { + fn clone(&self) -> Self { + *self + } +} +#[repr(C)] +#[cfg(target_arch = "x86")] +pub struct XSAVE_FORMAT { + pub ControlWord: u16, + pub StatusWord: u16, + pub TagWord: u8, + pub Reserved1: u8, + pub ErrorOpcode: u16, + pub ErrorOffset: u32, + pub ErrorSelector: u16, + pub Reserved2: u16, + pub DataOffset: u32, + pub DataSelector: u16, + pub Reserved3: u16, + pub MxCsr: u32, + pub MxCsr_Mask: u32, + pub FloatRegisters: [M128A; 8], + pub XmmRegisters: [M128A; 8], + pub Reserved4: [u8; 224], +} +#[cfg(target_arch = "x86")] +impl ::core::marker::Copy for XSAVE_FORMAT {} +#[cfg(target_arch = "x86")] +impl ::core::clone::Clone for XSAVE_FORMAT { + fn clone(&self) -> Self { + *self + } +} diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs index 7dff81ecb8d..4fe95d41116 100644 --- a/library/std/src/sys/windows/compat.rs +++ b/library/std/src/sys/windows/compat.rs @@ -114,17 +114,20 @@ impl Module { /// (e.g. kernel32 and ntdll). pub unsafe fn new(name: &CStr) -> Option<Self> { // SAFETY: A CStr is always null terminated. - let module = c::GetModuleHandleA(name.as_ptr()); + let module = c::GetModuleHandleA(name.as_ptr().cast::<u8>()); NonNull::new(module).map(Self) } // Try to get the address of a function. pub fn proc_address(self, name: &CStr) -> Option<NonNull<c_void>> { - // SAFETY: - // `self.0` will always be a valid module. - // A CStr is always null terminated. - let proc = unsafe { c::GetProcAddress(self.0.as_ptr(), name.as_ptr()) }; - NonNull::new(proc) + unsafe { + // SAFETY: + // `self.0` will always be a valid module. + // A CStr is always null terminated. + let proc = c::GetProcAddress(self.0.as_ptr(), name.as_ptr().cast::<u8>()); + // SAFETY: `GetProcAddress` returns None on null. + proc.map(|p| NonNull::new_unchecked(p as *mut c_void)) + } } } @@ -199,6 +202,7 @@ macro_rules! compat_fn_optional { )+) => ( $( pub mod $symbol { + #[allow(unused_imports)] use super::*; use crate::ffi::c_void; use crate::mem; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index fe052c8281b..ce427766d17 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -89,6 +89,12 @@ pub struct FileTimes { accessed: Option<c::FILETIME>, modified: Option<c::FILETIME>, } +impl core::fmt::Debug for c::FILETIME { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let time = ((self.dwHighDateTime as u64) << 32) | self.dwLowDateTime as u64; + f.debug_tuple("FILETIME").field(&time).finish() + } +} #[derive(Debug)] pub struct DirBuilder; @@ -290,6 +296,7 @@ impl File { ptr::null_mut(), ) }; + let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) }; if let Ok(handle) = handle.try_into() { Ok(File { handle: Handle::from_inner(handle) }) } else { @@ -501,7 +508,8 @@ impl File { } fn readlink(&self) -> io::Result<PathBuf> { - let mut space = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]); + let mut space = + Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); let (_bytes, buf) = self.reparse_point(&mut space)?; unsafe { let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag { @@ -589,7 +597,11 @@ impl File { )); } cvt(unsafe { - c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref()) + let accessed = + times.accessed.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null()); + let modified = + times.modified.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null()); + c::SetFileTime(self.as_raw_handle(), ptr::null_mut(), accessed, modified) })?; Ok(()) } @@ -618,9 +630,9 @@ impl File { /// then errors will be `ERROR_NOT_SUPPORTED` or `ERROR_INVALID_PARAMETER`. fn posix_delete(&self) -> io::Result<()> { let mut info = c::FILE_DISPOSITION_INFO_EX { - Flags: c::FILE_DISPOSITION_DELETE - | c::FILE_DISPOSITION_POSIX_SEMANTICS - | c::FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE, + Flags: c::FILE_DISPOSITION_FLAG_DELETE + | c::FILE_DISPOSITION_FLAG_POSIX_SEMANTICS + | c::FILE_DISPOSITION_FLAG_IGNORE_READONLY_ATTRIBUTE, }; let size = mem::size_of_val(&info); cvt(unsafe { @@ -791,15 +803,15 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< // See https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntcreatefile unsafe { let mut handle = ptr::null_mut(); - let mut io_status = c::IO_STATUS_BLOCK::default(); - let name_str = c::UNICODE_STRING::from_ref(name); + let mut io_status = c::IO_STATUS_BLOCK::PENDING; + let mut name_str = c::UNICODE_STRING::from_ref(name); use crate::sync::atomic::{AtomicU32, Ordering}; // The `OBJ_DONT_REPARSE` attribute ensures that we haven't been // tricked into following a symlink. However, it may not be available in // earlier versions of Windows. static ATTRIBUTES: AtomicU32 = AtomicU32::new(c::OBJ_DONT_REPARSE); - let object = c::OBJECT_ATTRIBUTES { - ObjectName: &name_str, + let mut object = c::OBJECT_ATTRIBUTES { + ObjectName: &mut name_str, RootDirectory: parent.as_raw_handle(), Attributes: ATTRIBUTES.load(Ordering::Relaxed), ..c::OBJECT_ATTRIBUTES::default() @@ -807,7 +819,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< let status = c::NtCreateFile( &mut handle, access, - &object, + &mut object, &mut io_status, crate::ptr::null_mut(), 0, @@ -1368,7 +1380,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { _dwCallbackReason: c::DWORD, _hSourceFile: c::HANDLE, _hDestinationFile: c::HANDLE, - lpData: c::LPVOID, + lpData: c::LPCVOID, ) -> c::DWORD { if dwStreamNumber == 1 { *(lpData as *mut i64) = StreamBytesTransferred; @@ -1415,9 +1427,10 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> { let f = File::open(junction, &opts)?; let h = f.as_inner().as_raw_handle(); unsafe { - let mut data = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]); + let mut data = + Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); let data_ptr = data.0.as_mut_ptr(); - let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + let data_end = data_ptr.add(c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize); let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>(); // Zero the header to ensure it's fully initialized, including reserved parameters. *db = mem::zeroed(); diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index c7677d1c13a..84c1fbde32d 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -144,7 +144,7 @@ impl Handle { let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD; let mut amt = 0; let res = cvt(c::ReadFile( - self.as_handle(), + self.as_raw_handle(), buf.as_ptr() as c::LPVOID, len, &mut amt, @@ -235,7 +235,7 @@ impl Handle { len: usize, offset: Option<u64>, ) -> io::Result<usize> { - let mut io_status = c::IO_STATUS_BLOCK::default(); + let mut io_status = c::IO_STATUS_BLOCK::PENDING; // The length is clamped at u32::MAX. let len = cmp::min(len, c::DWORD::MAX as usize) as c::DWORD; @@ -283,7 +283,7 @@ impl Handle { /// /// If `offset` is `None` then the current file position is used. fn synchronous_write(&self, buf: &[u8], offset: Option<u64>) -> io::Result<usize> { - let mut io_status = c::IO_STATUS_BLOCK::default(); + let mut io_status = c::IO_STATUS_BLOCK::PENDING; // The length is clamped at u32::MAX. let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs index 7fdd1f702e2..fc9856caed6 100644 --- a/library/std/src/sys/windows/io.rs +++ b/library/std/src/sys/windows/io.rs @@ -17,10 +17,7 @@ impl<'a> IoSlice<'a> { pub fn new(buf: &'a [u8]) -> IoSlice<'a> { assert!(buf.len() <= c::ULONG::MAX as usize); IoSlice { - vec: c::WSABUF { - len: buf.len() as c::ULONG, - buf: buf.as_ptr() as *mut u8 as *mut c::CHAR, - }, + vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_ptr() as *mut u8 }, _p: PhantomData, } } @@ -54,7 +51,7 @@ impl<'a> IoSliceMut<'a> { pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { assert!(buf.len() <= c::ULONG::MAX as usize); IoSliceMut { - vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() as *mut c::CHAR }, + vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() }, _p: PhantomData, } } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 8158713fa84..2404bbe2b89 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -263,7 +263,7 @@ impl Socket { &mut nread, &mut flags, ptr::null_mut(), - ptr::null_mut(), + None, ) }; @@ -347,7 +347,7 @@ impl Socket { &mut nwritten, 0, ptr::null_mut(), - ptr::null_mut(), + None, ) }; cvt(result).map(|_| nwritten as usize) diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 0780b29584d..d07147eccc1 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -373,7 +373,7 @@ impl AnonPipe { // Asynchronous read of the pipe. // If successful, `callback` will be called once it completes. - let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback); + let result = io(self.inner.as_handle(), buf, len, &mut overlapped, Some(callback)); if result == c::FALSE { // We can return here because the call failed. // After this we must not return until the I/O completes. diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 1c73b64e250..df3667c0fd7 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -308,7 +308,7 @@ impl Command { let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?; let mut si = zeroed_startupinfo(); - si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD; + si.cb = mem::size_of::<c::STARTUPINFOW>() as c::DWORD; // If at least one of stdin, stdout or stderr are set (i.e. are non null) // then set the `hStd` fields in `STARTUPINFO`. @@ -332,7 +332,7 @@ impl Command { flags, envp, dirp, - &mut si, + &si, &mut pi, )) }?; @@ -720,8 +720,8 @@ impl From<u32> for ExitCode { } } -fn zeroed_startupinfo() -> c::STARTUPINFO { - c::STARTUPINFO { +fn zeroed_startupinfo() -> c::STARTUPINFOW { + c::STARTUPINFOW { cb: 0, lpReserved: ptr::null_mut(), lpDesktop: ptr::null_mut(), @@ -731,7 +731,7 @@ fn zeroed_startupinfo() -> c::STARTUPINFO { dwXSize: 0, dwYSize: 0, dwXCountChars: 0, - dwYCountCharts: 0, + dwYCountChars: 0, dwFillAttribute: 0, dwFlags: 0, wShowWindow: 0, diff --git a/library/std/src/sys/windows/rand.rs b/library/std/src/sys/windows/rand.rs index cdf37cfe911..bca4e38d9f6 100644 --- a/library/std/src/sys/windows/rand.rs +++ b/library/std/src/sys/windows/rand.rs @@ -1,3 +1,4 @@ +use crate::ffi::c_void; use crate::io; use crate::mem; use crate::ptr; @@ -25,8 +26,9 @@ pub fn hashmap_random_keys() -> (u64, u64) { #[inline(never)] fn fallback_rng() -> (u64, u64) { let mut v = (0, 0); - let ret = - unsafe { c::RtlGenRandom(&mut v as *mut _ as *mut u8, mem::size_of_val(&v) as c::ULONG) }; + let ret = unsafe { + c::RtlGenRandom(&mut v as *mut _ as *mut c_void, mem::size_of_val(&v) as c::ULONG) + }; if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) } } diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs index 18a2a36ad25..0caf0a317a4 100644 --- a/library/std/src/sys/windows/stack_overflow.rs +++ b/library/std/src/sys/windows/stack_overflow.rs @@ -18,7 +18,7 @@ impl Handler { } } -extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG { +unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG { unsafe { let rec = &(*(*ExceptionInfo).ExceptionRecord); let code = rec.ExceptionCode; @@ -34,7 +34,7 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) - } pub unsafe fn init() { - if c::AddVectoredExceptionHandler(0, vectored_handler).is_null() { + if c::AddVectoredExceptionHandler(0, Some(vectored_handler)).is_null() { panic!("failed to install exception handler"); } // Set the thread stack guarantee for the main thread. diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs index 32c6ccffb7a..2e3e0859dc1 100644 --- a/library/std/src/sys/windows/stdio.rs +++ b/library/std/src/sys/windows/stdio.rs @@ -180,7 +180,7 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz let result = c::MultiByteToWideChar( c::CP_UTF8, // CodePage c::MB_ERR_INVALID_CHARS, // dwFlags - utf8.as_ptr() as c::LPCCH, // lpMultiByteStr + utf8.as_ptr(), // lpMultiByteStr utf8.len() as c::c_int, // cbMultiByte utf16.as_mut_ptr() as c::LPWSTR, // lpWideCharStr utf16.len() as c::c_int, // cchWideChar @@ -344,7 +344,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz // See #38274 and https://stackoverflow.com/questions/43836040/win-api-readconsole. const CTRL_Z: u16 = 0x1A; const CTRL_Z_MASK: c::ULONG = 1 << CTRL_Z; - let mut input_control = c::CONSOLE_READCONSOLE_CONTROL { + let input_control = c::CONSOLE_READCONSOLE_CONTROL { nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as c::ULONG, nInitialChars: 0, dwCtrlWakeupMask: CTRL_Z_MASK, @@ -360,7 +360,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz buf.as_mut_ptr() as c::LPVOID, buf.len() as u32, &mut amount, - &mut input_control as c::PCONSOLE_READCONSOLE_CONTROL, + &input_control, ) })?; @@ -385,14 +385,14 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> { let result = unsafe { c::WideCharToMultiByte( - c::CP_UTF8, // CodePage - c::WC_ERR_INVALID_CHARS, // dwFlags - utf16.as_ptr(), // lpWideCharStr - utf16.len() as c::c_int, // cchWideChar - utf8.as_mut_ptr() as c::LPSTR, // lpMultiByteStr - utf8.len() as c::c_int, // cbMultiByte - ptr::null(), // lpDefaultChar - ptr::null_mut(), // lpUsedDefaultChar + c::CP_UTF8, // CodePage + c::WC_ERR_INVALID_CHARS, // dwFlags + utf16.as_ptr(), // lpWideCharStr + utf16.len() as c::c_int, // cchWideChar + utf8.as_mut_ptr(), // lpMultiByteStr + utf8.len() as c::c_int, // cbMultiByte + ptr::null(), // lpDefaultChar + ptr::null_mut(), // lpUsedDefaultChar ) }; if result == 0 { diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index ed58c47e090..18cecb65681 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -2,6 +2,7 @@ use crate::ffi::CStr; use crate::io; use crate::num::NonZeroUsize; use crate::os::windows::io::AsRawHandle; +use crate::os::windows::io::HandleOrNull; use crate::ptr; use crate::sys::c; use crate::sys::handle::Handle; @@ -32,12 +33,12 @@ impl Thread { let ret = c::CreateThread( ptr::null_mut(), stack, - thread_start, + Some(thread_start), p as *mut _, c::STACK_SIZE_PARAM_IS_A_RESERVATION, ptr::null_mut(), ); - + let ret = HandleOrNull::from_raw_handle(ret); return if let Ok(handle) = ret.try_into() { Ok(Thread { handle: Handle::from_inner(handle) }) } else { 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/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 6c9ce6fa0dd..b65e2572cc5 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -375,7 +375,9 @@ fn test_scoped_threads_nll() { // this is mostly a *compilation test* for this exact function: fn foo(x: &u8) { thread::scope(|s| { - s.spawn(|| drop(x)); + s.spawn(|| match x { + _ => (), + }); }); } // let's also run it for good measure diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index bf3c81fcc98..9ce29a33df6 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -16,7 +16,6 @@ fn arm_linux() { // tidy-alphabetical-start println!("aes: {}", is_arm_feature_detected!("aes")); println!("crc: {}", is_arm_feature_detected!("crc")); - println!("crypto: {}", is_arm_feature_detected!("crypto")); println!("neon: {}", is_arm_feature_detected!("neon")); println!("pmull: {}", is_arm_feature_detected!("pmull")); println!("sha2: {}", is_arm_feature_detected!("sha2")); diff --git a/library/stdarch b/library/stdarch -Subproject b655243782c18d3419439daa523782e0818ecf2 +Subproject 7e2cdc675b92165c5f8c4c794620252be4605e7 diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 74dd22df9e0..d6924cf2cfb 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) - Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false. - Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false. +- Add `rpath` option in `target` section to support set rpath option for each target independently. [#111242](https://github.com/rust-lang/rust/pull/111242) ## [Version 2] - 2020-09-25 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 45f2975f5f5..5c37fab5470 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -838,6 +838,8 @@ impl<'a> Builder<'a> { run::Miri, 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), @@ -1622,7 +1624,7 @@ impl<'a> Builder<'a> { // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it // fun to pass a flag to a tool to pass a flag to pass a flag to a tool // to change a flag in a binary? - if self.config.rust_rpath && util::use_host_linker(target) { + if self.config.rpath_enabled(target) && util::use_host_linker(target) { let rpath = if target.contains("apple") { // Note that we need to take one extra step on macOS to also pass // `-Wl,-instal_name,@rpath/...` to get things to work right. To diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f4e97d7dfed..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; @@ -467,6 +468,7 @@ pub struct Target { pub ndk: Option<PathBuf>, pub sanitizers: Option<bool>, pub profiler: Option<bool>, + pub rpath: Option<bool>, pub crt_static: Option<bool>, pub musl_root: Option<PathBuf>, pub musl_libdir: Option<PathBuf>, @@ -812,6 +814,7 @@ define_config! { android_ndk: Option<String> = "android-ndk", sanitizers: Option<bool> = "sanitizers", profiler: Option<bool> = "profiler", + rpath: Option<bool> = "rpath", crt_static: Option<bool> = "crt-static", musl_root: Option<String> = "musl-root", musl_libdir: Option<String> = "musl-libdir", @@ -1017,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| { @@ -1318,6 +1322,7 @@ impl Config { target.qemu_rootfs = cfg.qemu_rootfs.map(PathBuf::from); target.sanitizers = cfg.sanitizers; target.profiler = cfg.profiler; + target.rpath = cfg.rpath; config.target_config.insert(TargetSelection::from_user(&triple), target); } @@ -1649,6 +1654,10 @@ impl Config { self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler } + pub fn rpath_enabled(&self, target: TargetSelection) -> bool { + self.target_config.get(&target).map(|t| t.rpath).flatten().unwrap_or(self.rust_rpath) + } + pub fn llvm_enabled(&self) -> bool { self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) } @@ -1673,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 cb15d9a6325..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; @@ -253,3 +256,56 @@ impl Step for GenerateCopyright { dest } } + +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct GenerateWindowsSys; + +impl Step for GenerateWindowsSys { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/generate-windows-sys") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(GenerateWindowsSys); + } + + fn run(self, builder: &Builder<'_>) { + let mut cmd = builder.tool_cmd(Tool::GenerateWindowsSys); + cmd.arg(&builder.src); + 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 854b7f5bd3a..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; @@ -613,6 +615,21 @@ impl Step for Miri { builder.run(&mut cargo); } + // Run it again for mir-opt-level 4 to catch some miscompilations. + if builder.config.test_args().is_empty() { + cargo.env("MIRIFLAGS", "-O -Zmir-opt-level=4 -Cdebug-assertions=yes"); + // Optimizations can change backtraces + cargo.env("MIRI_SKIP_UI_CHECKS", "1"); + // Optimizations can change error locations and remove UB so don't run `fail` tests. + cargo.args(&["tests/pass", "tests/panic"]); + + let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", compiler, target, builder); + { + let _time = util::timeit(&builder); + builder.run(&mut cargo); + } + } + // # Run `cargo miri test`. // This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures // that we get the desired output), but that is sufficient to make sure that the libtest harness @@ -644,8 +661,10 @@ impl Step for Miri { cargo.env("RUST_BACKTRACE", "1"); let mut cargo = Command::from(cargo); - let _time = util::timeit(&builder); - builder.run(&mut cargo); + { + let _time = util::timeit(&builder); + builder.run(&mut cargo); + } } } @@ -1121,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/bootstrap/tool.rs b/src/bootstrap/tool.rs index 39f6369b4d3..f13d365e375 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -301,6 +301,7 @@ bootstrap_tool!( CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata"; GenerateCopyright, "src/tools/generate-copyright", "generate-copyright"; SuggestTests, "src/tools/suggest-tests", "suggest-tests"; + GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys"; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] 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 7092c7c46f8..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.15.0
\ No newline at end of file +0.16.3
\ No newline at end of file diff --git a/src/doc/edition-guide b/src/doc/edition-guide -Subproject 6038be9d37d7251c966b486154af621d1794d7a +Subproject f63e578b92ff43e8cc38fcaa257b660f45c8a8c diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject 897fcf566f16bf87bf37199bdddec1801fd0053 +Subproject d9eb4c3f75435b008881062ffa77bf0d1527b37 diff --git a/src/doc/reference b/src/doc/reference -Subproject 1f8dc727e94ae4ef92adf70df979521a1ea1143 +Subproject 28dc0f3576b55f5e57c5d6e65cd68ba3161e9fd diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject 31961fe22521a779070a44a8f30a2b00a20b621 +Subproject 8ee9528b72b927cff8fd32346db8bbd1198816f diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject 2a5eb92197e9cf8fe91164dcbf4f9b88c0d7e73 +Subproject 28dbeaf5c44bc7f5111ad412e99f2d7c5cec6c9 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 48efa67191a..73343ba9df5 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -27,6 +27,7 @@ - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) - [\*-linux-ohos](platform-support/openharmony.md) + - [\*-esp-espidf](platform-support/esp-idf.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 75f97c1fc1e..d22e1cf7f68 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -297,7 +297,7 @@ target | std | host | notes `riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches) `riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA) [`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) -`riscv32imc-esp-espidf` | ✓ | | RISC-V ESP-IDF +[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia `riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0) diff --git a/src/doc/rustc/src/platform-support/esp-idf.md b/src/doc/rustc/src/platform-support/esp-idf.md new file mode 100644 index 00000000000..8a4ca347e22 --- /dev/null +++ b/src/doc/rustc/src/platform-support/esp-idf.md @@ -0,0 +1,41 @@ +# `*-esp-espidf` + +**Tier: 3** + +Targets for the [ESP-IDF](https://github.com/espressif/esp-idf) development framework running on RISC-V and Xtensa CPUs. + +## Target maintainers + +- Ivan Markov [@ivmarkov](https://github.com/ivmarkov) +- Scott Mabin [@MabezDev](https://github.com/MabezDev) + +## Requirements + +The target names follow this format: `$ARCH-esp-espidf`, where `$ARCH` specifies the target processor architecture. The following targets are currently defined: + +| Target name | Target CPU(s) | +|--------------------------------|-----------------------| +| `riscv32imc-esp-espidf` | [ESP32-C3](https://www.espressif.com/en/products/socs/esp32-c3) | + +The minimum supported ESP-IDF version is `v4.3`, though it is recommended to use the latest stable release if possible. + +## Building the target + +The target can be built by enabling it for a `rustc` build. The `build-std` feature is required to build the standard library for ESP-IDF. `ldproxy` is also required for linking, it can be installed from crates.io. + +```toml +[build] +target = ["$ARCH-esp-espidf"] + +[target.$ARCH-esp-espidf] +linker = "ldproxy" + +[unstable] +build-std = ["std", "panic_abort"] +``` + +The `esp-idf-sys` crate will handle the compilation of ESP-IDF, including downloading the relevant toolchains for the build. + +## Cross-compilation toolchains and C code + +`esp-idf-sys` exposes the toolchain used in the compilation of ESP-IDF, see the crate [documentation for build output propagation](https://github.com/esp-rs/esp-idf-sys#conditional-compilation) for more information. 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/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fb32b6ef1d3..baf2b0a8585 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -556,7 +556,10 @@ where WherePredicate::EqPredicate { lhs, rhs, bound_params } => { match *lhs { Type::QPath(box QPathData { - ref assoc, ref self_type, ref trait_, .. + ref assoc, + ref self_type, + trait_: Some(ref trait_), + .. }) => { let ty = &*self_type; let mut new_trait = trait_.clone(); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 951f54e9366..c852f9cca2b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -706,7 +706,12 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean: g.where_predicates.retain(|pred| match pred { clean::WherePredicate::BoundPredicate { - ty: clean::QPath(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }), + ty: + clean::QPath(box clean::QPathData { + self_type: clean::Generic(ref s), + trait_: Some(trait_), + .. + }), bounds, .. } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 23449a25c3a..59a3e631724 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -119,7 +119,39 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< }); let kind = ModuleItem(Module { items, span }); - Item::from_def_id_and_parts(doc.def_id.to_def_id(), Some(doc.name), kind, cx) + generate_item_with_correct_attrs(cx, kind, doc.def_id, doc.name, doc.import_id, doc.renamed) +} + +fn generate_item_with_correct_attrs( + cx: &mut DocContext<'_>, + kind: ItemKind, + local_def_id: LocalDefId, + name: Symbol, + import_id: Option<LocalDefId>, + renamed: Option<Symbol>, +) -> Item { + let def_id = local_def_id.to_def_id(); + let target_attrs = inline::load_attrs(cx, def_id); + let attrs = if let Some(import_id) = import_id { + let is_inline = inline::load_attrs(cx, import_id.to_def_id()) + .lists(sym::doc) + .get_word_attr(sym::inline) + .is_some(); + let mut attrs = get_all_import_attributes(cx, import_id, local_def_id, is_inline); + add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None); + attrs + } else { + // We only keep the item's attributes. + target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect() + }; + + let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); + let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); + + let name = renamed.or(Some(name)); + let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, Box::new(attrs), cfg); + item.inline_stmt_id = import_id.map(|local| local.to_def_id()); + item } fn clean_generic_bound<'tcx>( @@ -441,7 +473,7 @@ fn clean_projection<'tcx>( assoc: projection_to_path_segment(ty, cx), should_show_cast, self_type, - trait_, + trait_: Some(trait_), })) } @@ -1330,7 +1362,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let mut bounds: Vec<GenericBound> = Vec::new(); generics.where_predicates.retain_mut(|pred| match *pred { WherePredicate::BoundPredicate { - ty: QPath(box QPathData { ref assoc, ref self_type, ref trait_, .. }), + ty: + QPath(box QPathData { + ref assoc, + ref self_type, + trait_: Some(ref trait_), + .. + }), bounds: ref mut pred_bounds, .. } => { @@ -1492,25 +1530,30 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx), should_show_cast, self_type, - trait_, + trait_: Some(trait_), })) } hir::QPath::TypeRelative(qself, segment) => { let ty = hir_ty_to_ty(cx.tcx, hir_ty); - let res = match ty.kind() { + let self_type = clean_ty(qself, cx); + + let (trait_, should_show_cast) = match ty.kind() { ty::Alias(ty::Projection, proj) => { - Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id) + let res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id); + let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx); + register_res(cx, trait_.res); + let self_def_id = res.opt_def_id(); + let should_show_cast = + compute_should_show_cast(self_def_id, &trait_, &self_type); + + (Some(trait_), should_show_cast) } + ty::Alias(ty::Inherent, _) => (None, false), // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s. ty::Error(_) => return Type::Infer, - // Otherwise, this is an inherent associated type. - _ => return clean_middle_ty(ty::Binder::dummy(ty), cx, None), + _ => bug!("clean: expected associated type, found `{ty:?}`"), }; - let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx); - register_res(cx, trait_.res); - let self_def_id = res.opt_def_id(); - let self_type = clean_ty(qself, cx); - let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); + Type::QPath(Box::new(QPathData { assoc: clean_path_segment(segment, cx), should_show_cast, @@ -1836,6 +1879,29 @@ pub(crate) fn clean_middle_ty<'tcx>( clean_projection(bound_ty.rebind(*data), cx, parent_def_id) } + ty::Alias(ty::Inherent, alias_ty) => { + let alias_ty = bound_ty.rebind(alias_ty); + let self_type = clean_middle_ty(alias_ty.map_bound(|ty| ty.self_ty()), cx, None); + + Type::QPath(Box::new(QPathData { + assoc: PathSegment { + name: cx.tcx.associated_item(alias_ty.skip_binder().def_id).name, + args: GenericArgs::AngleBracketed { + args: substs_to_args( + cx, + alias_ty.map_bound(|ty| ty.substs.as_slice()), + true, + ) + .into(), + bindings: Default::default(), + }, + }, + should_show_cast: false, + self_type, + trait_: None, + })) + } + ty::Param(ref p) => { if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) { ImplTrait(bounds) @@ -2311,29 +2377,14 @@ fn clean_maybe_renamed_item<'tcx>( _ => unreachable!("not yet converted"), }; - let target_attrs = inline::load_attrs(cx, def_id); - let attrs = if let Some(import_id) = import_id { - let is_inline = inline::load_attrs(cx, import_id.to_def_id()) - .lists(sym::doc) - .get_word_attr(sym::inline) - .is_some(); - let mut attrs = - get_all_import_attributes(cx, import_id, item.owner_id.def_id, is_inline); - add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None); - attrs - } else { - // We only keep the item's attributes. - target_attrs.iter().map(|attr| (Cow::Borrowed(attr), None)).collect() - }; - - let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); - let attrs = - Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false); - - let mut item = - Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg); - item.inline_stmt_id = import_id.map(|local| local.to_def_id()); - vec![item] + vec![generate_item_with_correct_attrs( + cx, + kind, + item.owner_id.def_id, + name, + import_id, + renamed, + )] }) } @@ -2363,14 +2414,15 @@ fn clean_impl<'tcx>( } let for_ = clean_ty(impl_.self_ty, cx); - let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) { - DefKind::TyAlias => Some(clean_middle_ty( - ty::Binder::dummy(tcx.type_of(did).subst_identity()), - cx, - Some(did), - )), - _ => None, - }); + let type_alias = + for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) { + DefKind::TyAlias => Some(clean_middle_ty( + ty::Binder::dummy(tcx.type_of(def_id).subst_identity()), + cx, + Some(def_id.to_def_id()), + )), + _ => None, + }); let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| { let kind = ImplItem(Box::new(Impl { unsafety: impl_.unsafety, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7371b44465b..38664c3e359 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1660,7 +1660,7 @@ impl Type { pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self { - Some((self_type, trait_.def_id(), assoc.clone())) + Some((self_type, trait_.as_ref()?.def_id(), assoc.clone())) } else { None } @@ -1704,7 +1704,7 @@ pub(crate) struct QPathData { pub self_type: Type, /// FIXME: compute this field on demand. pub should_show_cast: bool, - pub trait_: Path, + pub trait_: Option<Path>, } /// A primitive (aka, builtin) type. 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/formats/cache.rs b/src/librustdoc/formats/cache.rs index 841abfab666..c0730e90740 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -195,7 +195,13 @@ impl Cache { impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { if item.item_id.is_local() { - debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.item_id); + let is_stripped = matches!(*item.kind, clean::ItemKind::StrippedItem(..)); + debug!( + "folding {} (stripped: {is_stripped:?}) \"{:?}\", id {:?}", + item.type_(), + item.name, + item.item_id + ); } // If this is a stripped module, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1c6810bdaf9..d963d6092c4 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1116,14 +1116,17 @@ fn fmt_type<'cx>( ref trait_, should_show_cast, }) => { + // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719), + // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`). + if f.alternate() { - if should_show_cast { + if let Some(trait_) = trait_ && should_show_cast { write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? } else { write!(f, "{:#}::", self_type.print(cx))? } } else { - if should_show_cast { + if let Some(trait_) = trait_ && should_show_cast { write!(f, "<{} as {}>::", self_type.print(cx), trait_.print(cx))? } else { write!(f, "{}::", self_type.print(cx))? @@ -1139,15 +1142,36 @@ fn fmt_type<'cx>( // the ugliness comes from inlining across crates where // everything comes in as a fully resolved QPath (hard to // look at). - if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) { - write!( - f, - "<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \ - title=\"type {path}::{name}\">{name}</a>", - shortty = ItemType::AssocType, - name = assoc.name, - path = join_with_double_colon(&path), - ) + if !f.alternate() { + // FIXME(inherent_associated_types): We always link to the very first associated + // type (in respect to source order) that bears the given name (`assoc.name`) and that is + // affiliated with the computed `DefId`. This is obviously incorrect when we have + // multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself + // through here and map it to the corresponding HTML ID that was generated by + // `render::Context::derive_id` when the impl blocks were rendered. + // There is no such mapping unfortunately. + // As a hack, we could badly imitate `derive_id` here by keeping *count* when looking + // for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()` + // considering privacy, `doc(hidden)`, etc. + // I don't feel like that right now :cold_sweat:. + + let parent_href = match trait_ { + Some(trait_) => href(trait_.def_id(), cx).ok(), + None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()), + }; + + if let Some((url, _, path)) = parent_href { + write!( + f, + "<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \ + title=\"type {path}::{name}\">{name}</a>", + shortty = ItemType::AssocType, + name = assoc.name, + path = join_with_double_colon(&path), + ) + } else { + write!(f, "{}", assoc.name) + } } else { write!(f, "{}", assoc.name) }?; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e09c6480060..0a2f5f6653c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1751,7 +1751,7 @@ fn render_impl( if trait_.is_none() && i.inner_impl().items.is_empty() { w.write_str( "<div class=\"item-info\">\ - <div class=\"stab empty-impl\">This impl block contains no items.</div> + <div class=\"stab empty-impl\">This impl block contains no items.</div>\ </div>", ); } @@ -2202,7 +2202,9 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> { } clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => { work.push_back(self_type); - process_path(trait_.def_id()); + if let Some(trait_) = trait_ { + process_path(trait_.def_id()); + } } _ => {} } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b5bebb70593..b1cef20b434 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -574,7 +574,7 @@ impl FromWithTcx<clean::Type> for Type { name: assoc.name.to_string(), args: Box::new(assoc.args.into_tcx(tcx)), self_type: Box::new(self_type.into_tcx(tcx)), - trait_: trait_.into_tcx(tcx), + trait_: trait_.map(|trait_| trait_.into_tcx(tcx)), }, } } 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/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 6b13e6c9581..10295cbd189 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -95,7 +95,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - } if cx.tcx.is_doc_hidden(def_id.to_def_id()) - || inherits_doc_hidden(cx.tcx, def_id) + || inherits_doc_hidden(cx.tcx, def_id, None) || cx.tcx.def_span(def_id.to_def_id()).in_derive_expansion() { return false; diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index a688aa14863..972b0c5ec19 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -1,5 +1,6 @@ //! Strip all doc(hidden) items from the output. +use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; use std::mem; @@ -29,6 +30,7 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea update_retained: true, tcx: cx.tcx, is_in_hidden_item: false, + last_reexport: None, }; stripper.fold_crate(krate) }; @@ -49,13 +51,24 @@ struct Stripper<'a, 'tcx> { update_retained: bool, tcx: TyCtxt<'tcx>, is_in_hidden_item: bool, + last_reexport: Option<LocalDefId>, } impl<'a, 'tcx> Stripper<'a, 'tcx> { + fn set_last_reexport_then_fold_item(&mut self, i: Item) -> Item { + let prev_from_reexport = self.last_reexport; + if i.inline_stmt_id.is_some() { + self.last_reexport = i.item_id.as_def_id().and_then(|def_id| def_id.as_local()); + } + let ret = self.fold_item_recur(i); + self.last_reexport = prev_from_reexport; + ret + } + fn set_is_in_hidden_item_and_fold(&mut self, is_in_hidden_item: bool, i: Item) -> Item { let prev = self.is_in_hidden_item; self.is_in_hidden_item |= is_in_hidden_item; - let ret = self.fold_item_recur(i); + let ret = self.set_last_reexport_then_fold_item(i); self.is_in_hidden_item = prev; ret } @@ -64,7 +77,7 @@ impl<'a, 'tcx> Stripper<'a, 'tcx> { /// of `is_in_hidden_item` to `true` because the impl children inherit its visibility. fn recurse_in_impl_or_exported_macro(&mut self, i: Item) -> Item { let prev = mem::replace(&mut self.is_in_hidden_item, false); - let ret = self.fold_item_recur(i); + let ret = self.set_last_reexport_then_fold_item(i); self.is_in_hidden_item = prev; ret } @@ -86,13 +99,20 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { if !is_impl_or_exported_macro { is_hidden = self.is_in_hidden_item || has_doc_hidden; if !is_hidden && i.inline_stmt_id.is_none() { - // We don't need to check if it's coming from a reexport since the reexport itself was - // already checked. + // `i.inline_stmt_id` is `Some` if the item is directly reexported. If it is, we + // don't need to check it, because the reexport itself was already checked. + // + // If this item is the child of a reexported module, `self.last_reexport` will be + // `Some` even though `i.inline_stmt_id` is `None`. Hiddenness inheritance needs to + // account for the possibility that an item's true parent module is hidden, but it's + // inlined into a visible module true. This code shouldn't be reachable if the + // module's reexport is itself hidden, for the same reason it doesn't need to be + // checked if `i.inline_stmt_id` is Some: hidden reexports are never inlined. is_hidden = i .item_id .as_def_id() .and_then(|def_id| def_id.as_local()) - .map(|def_id| inherits_doc_hidden(self.tcx, def_id)) + .map(|def_id| inherits_doc_hidden(self.tcx, def_id, self.last_reexport)) .unwrap_or(false); } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 841c7a78b2d..8f8dc6b7090 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; -use rustc_hir::intravisit::{walk_item, Visitor}; +use rustc_hir::intravisit::{walk_body, walk_item, Visitor}; use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; @@ -27,6 +27,8 @@ pub(crate) struct Module<'hir> { pub(crate) where_inner: Span, pub(crate) mods: Vec<Module<'hir>>, pub(crate) def_id: LocalDefId, + pub(crate) renamed: Option<Symbol>, + pub(crate) import_id: Option<LocalDefId>, /// The key is the item `ItemId` and the value is: (item, renamed, import_id). /// We use `FxIndexMap` to keep the insert order. pub(crate) items: FxIndexMap< @@ -37,11 +39,19 @@ pub(crate) struct Module<'hir> { } impl Module<'_> { - pub(crate) fn new(name: Symbol, def_id: LocalDefId, where_inner: Span) -> Self { + pub(crate) fn new( + name: Symbol, + def_id: LocalDefId, + where_inner: Span, + renamed: Option<Symbol>, + import_id: Option<LocalDefId>, + ) -> Self { Module { name, def_id, where_inner, + renamed, + import_id, mods: Vec::new(), items: FxIndexMap::default(), foreigns: Vec::new(), @@ -60,9 +70,16 @@ fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<Symbol> { std::iter::once(crate_name).chain(relative).collect() } -pub(crate) fn inherits_doc_hidden(tcx: TyCtxt<'_>, mut def_id: LocalDefId) -> bool { +pub(crate) fn inherits_doc_hidden( + tcx: TyCtxt<'_>, + mut def_id: LocalDefId, + stop_at: Option<LocalDefId>, +) -> bool { let hir = tcx.hir(); while let Some(id) = tcx.opt_local_parent(def_id) { + if let Some(stop_at) = stop_at && id == stop_at { + return false; + } def_id = id; if tcx.is_doc_hidden(def_id.to_def_id()) { return true; @@ -89,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> { exact_paths: DefIdMap<Vec<Symbol>>, modules: Vec<Module<'tcx>>, is_importable_from_parent: bool, + inside_body: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -100,6 +118,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { cx.tcx.crate_name(LOCAL_CRATE), CRATE_DEF_ID, cx.tcx.hir().root_module().spans.inner_span, + None, + None, ); RustdocVisitor { @@ -110,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { exact_paths: Default::default(), modules: vec![om], is_importable_from_parent: true, + inside_body: false, } } @@ -261,7 +282,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let is_private = !self.cx.cache.effective_visibilities.is_directly_public(self.cx.tcx, ori_res_did); - let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did); + let is_hidden = inherits_doc_hidden(self.cx.tcx, res_did, None); // Only inline if requested or if the item would otherwise be stripped. if (!please_inline && !is_private && !is_hidden) || is_no_inline { @@ -278,7 +299,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .cache .effective_visibilities .is_directly_public(self.cx.tcx, item_def_id.to_def_id()) && - !inherits_doc_hidden(self.cx.tcx, item_def_id) + !inherits_doc_hidden(self.cx.tcx, item_def_id, None) { // The imported item is public and not `doc(hidden)` so no need to inline it. return false; @@ -349,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { import_id: Option<LocalDefId>, ) { debug!("visiting item {:?}", item); + if self.inside_body { + // Only impls can be "seen" outside a body. For example: + // + // ``` + // struct Bar; + // + // fn foo() { + // impl Bar { fn bar() {} } + // } + // Bar::bar(); + // ``` + if let hir::ItemKind::Impl(impl_) = item.kind && + // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick + // them up regardless of where they're located. + impl_.of_trait.is_none() + { + self.add_to_current_mod(item, None, None); + } + return; + } let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -427,7 +468,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } hir::ItemKind::Mod(ref m) => { - self.enter_mod(item.owner_id.def_id, m, name); + self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id); } hir::ItemKind::Fn(..) | hir::ItemKind::ExternCrate(..) @@ -436,7 +477,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | hir::ItemKind::Union(..) | hir::ItemKind::TyAlias(..) | hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, .. + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. }) | hir::ItemKind::Static(..) | hir::ItemKind::Trait(..) @@ -480,8 +522,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { /// This method will create a new module and push it onto the "modules stack" then call /// `visit_mod_contents`. Once done, it'll remove it from the "modules stack" and instead /// add into the list of modules of the current module. - fn enter_mod(&mut self, id: LocalDefId, m: &'tcx hir::Mod<'tcx>, name: Symbol) { - self.modules.push(Module::new(name, id, m.spans.inner_span)); + fn enter_mod( + &mut self, + id: LocalDefId, + m: &'tcx hir::Mod<'tcx>, + name: Symbol, + renamed: Option<Symbol>, + import_id: Option<LocalDefId>, + ) { + self.modules.push(Module::new(name, id, m.spans.inner_span, renamed, import_id)); self.visit_mod_contents(id, m); @@ -501,19 +550,14 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { self.visit_item_inner(i, None, None); - let new_value = if self.is_importable_from_parent { - matches!( + let new_value = self.is_importable_from_parent + && matches!( i.kind, hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) - ) - } else { - // Whatever the context, if it's an impl block, the items inside it can be used so they - // should be visible. - matches!(i.kind, hir::ItemKind::Impl(..)) - }; + ); let prev = mem::replace(&mut self.is_importable_from_parent, new_value); walk_item(self, i); self.is_importable_from_parent = prev; @@ -542,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { fn visit_lifetime(&mut self, _: &hir::Lifetime) { // Unneeded. } + + fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) { + let prev = mem::replace(&mut self.inside_body, true); + walk_body(self, b); + self.inside_body = prev; + } } diff --git a/src/llvm-project b/src/llvm-project -Subproject ea6fa9c2d43aaf0f11559719eda9b54d356d541 +Subproject 533d3f338b804d54e5d0ac4fba6276af23002d9 diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 3cf8ceed620..3556834071f 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; /// rustdoc format-version. -pub const FORMAT_VERSION: u32 = 24; +pub const FORMAT_VERSION: u32 = 25; /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information /// about the language items in the local crate, as well as info about external items to allow @@ -581,13 +581,15 @@ pub enum Type { #[serde(rename = "type")] type_: Box<Type>, }, - /// `<Type as Trait>::Name` or associated types like `T::Item` where `T: Iterator` + /// Associated types like `<Type as Trait>::Name` and `T::Item` where + /// `T: Iterator` or inherent associated types like `Struct::Name`. QualifiedPath { name: String, args: Box<GenericArgs>, self_type: Box<Type>, + /// `None` iff this is an *inherent* associated type. #[serde(rename = "trait")] - trait_: Path, + trait_: Option<Path>, }, } diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 569b648b5831ae8a515e90c80843a5287c3304e +Subproject 09276c703a473ab33daaeb94917232e80eefd62 diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 79d0f6f3607..04993e49287 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -132,12 +132,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::doc::NEEDLESS_DOCTEST_MAIN_INFO, crate::doc::UNNECESSARY_SAFETY_DOC_INFO, crate::double_parens::DOUBLE_PARENS_INFO, - crate::drop_forget_ref::DROP_COPY_INFO, crate::drop_forget_ref::DROP_NON_DROP_INFO, - crate::drop_forget_ref::DROP_REF_INFO, - crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, - crate::drop_forget_ref::FORGET_REF_INFO, crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO, crate::duplicate_mod::DUPLICATE_MOD_INFO, crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 7f3f26bed7c..b27ffe73ffd 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1424,6 +1424,7 @@ fn ty_auto_deref_stability<'tcx>( continue; }, ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty), + ty::Alias(ty::Inherent, _) => unreachable!("inherent projection should have been normalized away above"), ty::Alias(ty::Projection, _) if ty.has_non_region_param() => { TyPosition::new_deref_stable_for_result(precedence, ty) }, diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 11e1bcdf12d..b2f7d026cc8 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -9,102 +9,6 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Checks for calls to `std::mem::drop` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `drop` on a reference will only drop the - /// reference itself, which is a no-op. It will not call the `drop` method (from - /// the `Drop` trait implementation) on the underlying referenced value, which - /// is likely what was intended. - /// - /// ### Example - /// ```ignore - /// let mut lock_guard = mutex.lock(); - /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex - /// // still locked - /// operation_that_requires_mutex_to_be_unlocked(); - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_REF, - correctness, - "calls to `std::mem::drop` with a reference instead of an owned value" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `forget` on a reference will only forget the - /// reference itself, which is a no-op. It will not forget the underlying - /// referenced - /// value, which is likely what was intended. - /// - /// ### Example - /// ```rust - /// let x = Box::new(1); - /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_REF, - correctness, - "calls to `std::mem::forget` with a reference instead of an owned value" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::drop` with a value - /// that derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::drop` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the - /// value will be copied and moved into the function on invocation. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::drop(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_COPY, - correctness, - "calls to `std::mem::drop` with a value that implements Copy" -} - -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a value that - /// derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::forget` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the - /// value will be copied and moved into the function on invocation. - /// - /// An alternative, but also valid, explanation is that Copy types do not - /// implement - /// the Drop trait, which means they have no destructors. Without a destructor, - /// there - /// is nothing for `std::mem::forget` to ignore. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::forget(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_COPY, - correctness, - "calls to `std::mem::forget` with a value that implements Copy" -} - -declare_clippy_lint! { - /// ### What it does /// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`. /// /// ### Why is this bad? @@ -172,24 +76,12 @@ declare_clippy_lint! { "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value" } -const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \ - Dropping a reference does nothing"; -const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ - Forgetting a reference does nothing"; -const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \ - Dropping a copy leaves the original intact"; -const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ - Forgetting a copy leaves the original intact"; const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \ Dropping such a type only extends its contained lifetimes"; const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \ Forgetting such a type is the same as dropping it"; declare_lint_pass!(DropForgetRef => [ - DROP_REF, - FORGET_REF, - DROP_COPY, - FORGET_COPY, DROP_NON_DROP, FORGET_NON_DROP, UNDROPPED_MANUALLY_DROPS @@ -206,10 +98,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg) = match fn_name { - sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => (DROP_REF, DROP_REF_SUMMARY), - sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY), - sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY), - sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), + // early return for uplifted lints: drop_ref, drop_copy, forget_ref, forget_copy + sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, + sym::mem_forget if arg_ty.is_ref() => return, + sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, + sym::mem_forget if is_copy => return, sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => { span_lint_and_help( cx, diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index af121f317cd..0809837d1fd 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -289,10 +289,11 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false }; match expected_item { - Item::Lang(expected_lang_item) => { - let expected_id = cx.tcx.lang_items().require(expected_lang_item).unwrap(); - cx.tcx.parent(id) == expected_id - }, + Item::Lang(expected_lang_item) => cx + .tcx + .lang_items() + .get(expected_lang_item) + .map_or(false, |expected_id| cx.tcx.parent(id) == expected_id), Item::Diag(expected_ty, expected_variant) => { let ty = cx.typeck_results().pat_ty(pat); diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index 5e81a01a461..52e22c0c630 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -32,9 +32,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::zero_width_space", "clippy::invisible_characters"), ("clippy::clone_double_ref", "suspicious_double_ref_op"), ("clippy::drop_bounds", "drop_bounds"), + ("clippy::drop_copy", "drop_copy"), + ("clippy::drop_ref", "drop_ref"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"), + ("clippy::forget_copy", "forget_copy"), + ("clippy::forget_ref", "forget_ref"), ("clippy::into_iter_on_array", "array_into_iter"), ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"), ("clippy::invalid_ref", "invalid_value"), 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/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs deleted file mode 100644 index a7276dd59f4..00000000000 --- a/src/tools/clippy/tests/ui/drop_forget_copy.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![warn(clippy::drop_copy, clippy::forget_copy)] -#![allow(clippy::toplevel_ref_arg, clippy::drop_ref, clippy::forget_ref, unused_mut)] - -use std::mem::{drop, forget}; -use std::vec::Vec; - -#[derive(Copy, Clone)] -struct SomeStruct; - -struct AnotherStruct { - x: u8, - y: u8, - z: Vec<u8>, -} - -impl Clone for AnotherStruct { - fn clone(&self) -> AnotherStruct { - AnotherStruct { - x: self.x, - y: self.y, - z: self.z.clone(), - } - } -} - -fn main() { - let s1 = SomeStruct {}; - let s2 = s1; - let s3 = &s1; - let mut s4 = s1; - let ref s5 = s1; - - drop(s1); - drop(s2); - drop(s3); - drop(s4); - drop(s5); - - forget(s1); - forget(s2); - forget(s3); - forget(s4); - forget(s5); - - let a1 = AnotherStruct { - x: 255, - y: 0, - z: vec![1, 2, 3], - }; - let a2 = &a1; - let mut a3 = a1.clone(); - let ref a4 = a1; - let a5 = a1.clone(); - - drop(a2); - drop(a3); - drop(a4); - drop(a5); - - forget(a2); - let a3 = &a1; - forget(a3); - forget(a4); - let a5 = a1.clone(); - forget(a5); -} - -#[allow(unused)] -#[allow(clippy::unit_cmp)] -fn issue9482(x: u8) { - fn println_and<T>(t: T) -> T { - println!("foo"); - t - } - - match x { - 0 => drop(println_and(12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(String::new())), // Don't lint (no copy type), we only care about side-effects - 2 => { - drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - }, - 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(2), // Lint, not a fn/method call - _ => (), - } -} diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr deleted file mode 100644 index 90bef1c3c43..00000000000 --- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr +++ /dev/null @@ -1,112 +0,0 @@ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:33:5 - | -LL | drop(s1); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:33:10 - | -LL | drop(s1); - | ^^ - = note: `-D clippy::drop-copy` implied by `-D warnings` - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:34:5 - | -LL | drop(s2); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:34:10 - | -LL | drop(s2); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:36:5 - | -LL | drop(s4); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:36:10 - | -LL | drop(s4); - | ^^ - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:39:5 - | -LL | forget(s1); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:39:12 - | -LL | forget(s1); - | ^^ - = note: `-D clippy::forget-copy` implied by `-D warnings` - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:40:5 - | -LL | forget(s2); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:40:12 - | -LL | forget(s2); - | ^^ - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:42:5 - | -LL | forget(s4); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:42:12 - | -LL | forget(s4); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:80:13 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:80:18 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:82:14 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:82:19 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:83:14 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:83:19 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^ - -error: aborting due to 9 previous errors - diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr deleted file mode 100644 index 293b9f6de83..00000000000 --- a/src/tools/clippy/tests/ui/drop_ref.stderr +++ /dev/null @@ -1,147 +0,0 @@ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:11:5 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:11:10 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::drop-ref` implied by `-D warnings` - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:14:5 - | -LL | drop(&owned1); - | ^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:14:10 - | -LL | drop(&owned1); - | ^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:15:5 - | -LL | drop(&&owned1); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/drop_ref.rs:15:10 - | -LL | drop(&&owned1); - | ^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:16:5 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:16:10 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:20:5 - | -LL | drop(reference1); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:20:10 - | -LL | drop(reference1); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:23:5 - | -LL | drop(reference2); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:23:10 - | -LL | drop(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:26:5 - | -LL | drop(reference3); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:26:10 - | -LL | drop(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:31:5 - | -LL | drop(&val); - | ^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/drop_ref.rs:31:10 - | -LL | drop(&val); - | ^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:39:5 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:39:20 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:91:13 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:91:18 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:93:14 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:93:19 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:94:14 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:94:19 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^ - -error: aborting due to 12 previous errors - diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs deleted file mode 100644 index 031b415f56f..00000000000 --- a/src/tools/clippy/tests/ui/forget_ref.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![warn(clippy::forget_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)] -#![allow(clippy::borrow_deref_ref)] - -use std::mem::forget; - -struct SomeStruct; - -fn main() { - forget(&SomeStruct); - - let mut owned = SomeStruct; - forget(&owned); - forget(&&owned); - forget(&mut owned); - forget(owned); //OK - - let reference1 = &SomeStruct; - forget(&*reference1); - - let reference2 = &mut SomeStruct; - forget(reference2); - - let ref reference3 = SomeStruct; - forget(reference3); -} - -#[allow(dead_code)] -fn test_generic_fn_forget<T>(val: T) { - forget(&val); - forget(val); //OK -} - -#[allow(dead_code)] -fn test_similarly_named_function() { - fn forget<T>(_val: T) {} - forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::forget(&SomeStruct); -} - -#[derive(Copy, Clone)] -pub struct Error; -fn produce_half_owl_error() -> Result<(), Error> { - Ok(()) -} - -fn produce_half_owl_ok() -> Result<bool, ()> { - Ok(true) -} diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr deleted file mode 100644 index 011cdefc665..00000000000 --- a/src/tools/clippy/tests/ui/forget_ref.stderr +++ /dev/null @@ -1,111 +0,0 @@ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:11:5 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:11:12 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::forget-ref` implied by `-D warnings` - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:14:5 - | -LL | forget(&owned); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:14:12 - | -LL | forget(&owned); - | ^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:15:5 - | -LL | forget(&&owned); - | ^^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/forget_ref.rs:15:12 - | -LL | forget(&&owned); - | ^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:16:5 - | -LL | forget(&mut owned); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:16:12 - | -LL | forget(&mut owned); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:20:5 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:20:12 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:23:5 - | -LL | forget(reference2); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:23:12 - | -LL | forget(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:26:5 - | -LL | forget(reference3); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:26:12 - | -LL | forget(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:31:5 - | -LL | forget(&val); - | ^^^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/forget_ref.rs:31:12 - | -LL | forget(&val); - | ^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:39:5 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:39:22 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^ - -error: aborting due to 9 previous errors - diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs index e5b35c098a2..5137448a6d4 100644 --- a/src/tools/clippy/tests/ui/mem_forget.rs +++ b/src/tools/clippy/tests/ui/mem_forget.rs @@ -5,7 +5,7 @@ use std::mem as memstuff; use std::mem::forget as forgetSomething; #[warn(clippy::mem_forget)] -#[allow(clippy::forget_copy)] +#[allow(forget_copy)] fn main() { let five: i32 = 5; forgetSomething(five); diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs index 73ef35c8c36..f28153e56b0 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -2,7 +2,7 @@ #![allow(unused)] #![allow(deref_nullptr)] #![allow(clippy::unnecessary_operation)] -#![allow(clippy::drop_copy)] +#![allow(drop_copy)] #![warn(clippy::multiple_unsafe_ops_per_block)] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 42a59f6d43d..9036f892612 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -29,7 +29,11 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_copy)] +#![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_copy)] +#![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] @@ -71,9 +75,13 @@ #![warn(clippy::invisible_characters)] #![warn(suspicious_double_ref_op)] #![warn(drop_bounds)] +#![warn(drop_copy)] +#![warn(drop_ref)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] +#![warn(forget_copy)] +#![warn(forget_ref)] #![warn(array_into_iter)] #![warn(invalid_atomic_ordering)] #![warn(invalid_value)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 4d173e8cbbf..43cabe810f3 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -29,7 +29,11 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_copy)] +#![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_copy)] +#![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] @@ -71,9 +75,13 @@ #![warn(clippy::zero_width_space)] #![warn(clippy::clone_double_ref)] #![warn(clippy::drop_bounds)] +#![warn(clippy::drop_copy)] +#![warn(clippy::drop_ref)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loops_over_fallibles)] +#![warn(clippy::forget_copy)] +#![warn(clippy::forget_ref)] #![warn(clippy::into_iter_on_array)] #![warn(clippy::invalid_atomic_ordering)] #![warn(clippy::invalid_ref)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 0da4ed7520c..1ad7cf412c8 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:44:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,256 +7,280 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` +error: lint `clippy::drop_copy` has been renamed to `drop_copy` + --> $DIR/rename.rs:78:9 + | +LL | #![warn(clippy::drop_copy)] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy` + +error: lint `clippy::drop_ref` has been renamed to `drop_ref` + --> $DIR/rename.rs:79:9 + | +LL | #![warn(clippy::drop_ref)] + | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref` + error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` +error: lint `clippy::forget_copy` has been renamed to `forget_copy` + --> $DIR/rename.rs:83:9 + | +LL | #![warn(clippy::forget_copy)] + | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_copy` + +error: lint `clippy::forget_ref` has been renamed to `forget_ref` + --> $DIR/rename.rs:84:9 + | +LL | #![warn(clippy::forget_ref)] + | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref` + error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:91:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:92:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:93:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:94:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 43 previous errors +error: aborting due to 47 previous errors diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed index 0c269d650c8..49c0e4dc7eb 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed @@ -10,7 +10,7 @@ #[warn(clippy::unnecessary_cast)] #[warn(clippy::useless_transmute)] // Shouldn't suggest rustc lint name(`dead_code`) -#[warn(clippy::drop_copy)] +#[warn(clippy::eq_op)] // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_self)] // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr index 421bf5ffa9a..584c428932f 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr @@ -34,7 +34,7 @@ error: unknown lint: `clippy::dead_cod` --> $DIR/unknown_clippy_lints.rs:13:8 | LL | #[warn(clippy::dead_cod)] - | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy` + | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op` error: unknown lint: `clippy::unused_colle` --> $DIR/unknown_clippy_lints.rs:15:8 diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 85fd6523c82..0d42504c7f4 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -28,7 +28,7 @@ libc = "0.2" miow = "0.5" [target.'cfg(windows)'.dependencies.windows] -version = "0.46.0" +version = "0.48.0" features = [ "Win32_Foundation", "Win32_System_Diagnostics_Debug", 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/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml new file mode 100644 index 00000000000..23e88844bd0 --- /dev/null +++ b/src/tools/generate-windows-sys/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "generate-windows-sys" +version = "0.1.0" +edition = "2021" + +[dependencies.windows-bindgen] +version = "0.49" diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs new file mode 100644 index 00000000000..91d981462e8 --- /dev/null +++ b/src/tools/generate-windows-sys/src/main.rs @@ -0,0 +1,37 @@ +use std::fs; +use std::io::{self, Write}; +use std::path::PathBuf; + +/// This is printed to the file before the rest of the contents. +const PRELUDE: &str = r#"// This file is autogenerated. +// +// To add bindings, edit windows_sys.lst then use `./x run generate-windows-sys` to +// regenerate the bindings. +// +// ignore-tidy-filelength +"#; + +fn main() -> io::Result<()> { + let mut path: PathBuf = + std::env::args_os().nth(1).expect("a path to the rust repository is required").into(); + path.push("library/std/src/sys/windows/c/windows_sys.lst"); + + // Load the list of APIs + let buffer = fs::read_to_string(&path)?; + let names: Vec<&str> = buffer + .lines() + .filter_map(|line| { + let line = line.trim(); + if line.is_empty() || line.starts_with("//") { None } else { Some(line) } + }) + .collect(); + + // Write the bindings to windows-sys.rs + let bindings = windows_bindgen::standalone_std(&names); + path.set_extension("rs"); + let mut f = std::fs::File::create(&path)?; + f.write_all(PRELUDE.as_bytes())?; + f.write_all(bindings.as_bytes())?; + + Ok(()) +} diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index a1f675a3b40..bf8a64acf08 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -273,7 +273,9 @@ impl<'a> Validator<'a> { Type::QualifiedPath { name: _, args, self_type, trait_ } => { self.check_generic_args(&**args); self.check_type(&**self_type); - self.check_path(trait_, PathKind::Trait); + if let Some(trait_) = trait_ { + self.check_path(trait_, PathKind::Trait); + } } } } 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 10079ba85b6..737423a2cd1 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -19,18 +19,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "atty" @@ -38,7 +38,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -72,9 +72,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" +checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" dependencies = [ "memchr", "once_cell", @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ "serde", ] @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if", "crossbeam-utils", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -203,6 +203,27 @@ dependencies = [ ] [[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] name = "eyre" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -214,18 +235,18 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -234,9 +255,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "hermit-abi" @@ -248,6 +269,12 @@ dependencies = [ ] [[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -269,10 +296,21 @@ dependencies = [ ] [[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "lazy_static" @@ -282,9 +320,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libffi" @@ -316,6 +354,12 @@ dependencies = [ ] [[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + +[[package]] name = "lock_api" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -336,9 +380,9 @@ dependencies = [ [[package]] name = "measureme" -version = "10.1.0" +version = "10.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdc226fa10994e8f66a4d2f6f000148bc563a1c671b6dcd2135737018033d8a" +checksum = "1930d162935fecd56fc4e0f6729eb3483bac1264542eb4ea31570b86a434b6bc" dependencies = [ "log", "memmap2", @@ -395,18 +439,18 @@ dependencies = [ [[package]] name = "object" -version = "0.30.0" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "owo-colors" @@ -434,16 +478,16 @@ dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "perf-event-open-sys" -version = "1.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce9bedf5da2c234fdf2391ede2b90fabf585355f33100689bc364a3ea558561a" +checksum = "b29be2ba35c12c6939f6bc73187f728bba82c3c062ecdc5fa90ea739282a1f58" dependencies = [ "libc", ] @@ -462,18 +506,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -518,10 +562,19 @@ dependencies = [ ] [[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] name = "regex" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -536,24 +589,15 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -589,10 +633,24 @@ dependencies = [ ] [[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "scopeguard" @@ -602,27 +660,27 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.152" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", @@ -631,9 +689,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -657,9 +715,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" -version = "1.0.107" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -668,41 +726,40 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", @@ -711,10 +768,11 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] @@ -751,9 +809,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "sharded-slab", "thread_local", @@ -762,9 +820,9 @@ dependencies = [ [[package]] name = "ui_test" -version = "0.6.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba" +checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2" dependencies = [ "bstr", "cargo-platform", @@ -784,9 +842,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "valuable" @@ -830,3 +888,135 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index b962d0c1096..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.6.2" +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/README.md b/src/tools/miri/README.md index 640a953dac9..79b0daf9e82 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -389,7 +389,7 @@ to Miri failing to detect cases of undefined behavior in a program. Follow [the discussion on supporting other types](https://github.com/rust-lang/miri/issues/2365). * `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program. This can be used to find which parts of your program are executing slowly under Miri. - The profile is written out to a file with the prefix `<name>`, and can be processed + The profile is written out to a file inside a directory called `<name>`, and can be processed using the tools in the repository https://github.com/rust-lang/measureme. * `-Zmiri-mute-stdout-stderr` silently ignores all writes to stdout and stderr, but reports to the program that it did actually write. This is useful when you diff --git a/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock new file mode 100644 index 00000000000..de6760a0359 --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "zip-equal" +version = "0.1.0" diff --git a/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml new file mode 100644 index 00000000000..f4208de727d --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/zip-equal/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "zip-equal" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs b/src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs new file mode 100644 index 00000000000..ba4e9b41d1d --- /dev/null +++ b/src/tools/miri/bench-cargo-miri/zip-equal/src/main.rs @@ -0,0 +1,22 @@ +//! This is a pathological pattern in which opportunities to merge +//! adjacent identical items in the RangeMap are not properly detected +//! because `RangeMap::iter_mut` is never called on overlapping ranges +//! and thus never merges previously split ranges. This does not produce any +//! additional cost for access operations, but it makes the job of the Tree Borrows +//! GC procedure much more costly. +//! See https://github.com/rust-lang/miri/issues/2863 + +const LENGTH: usize = (1 << 14) - 1; +const LONG: &[u8] = &[b'x'; LENGTH]; + +fn main() { + assert!(eq(LONG, LONG)) +} + +fn eq(s1: &[u8], s2: &[u8]) -> bool { + if s1.len() != s2.len() { + return false; + } + + s1.iter().zip(s2).all(|(c1, c2)| *c1 == *c2) +} diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index 76badcf94af..727e46a028d 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "bitflags" @@ -16,9 +16,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "camino" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ "serde", ] @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", @@ -61,6 +61,12 @@ dependencies = [ ] [[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -87,19 +93,40 @@ dependencies = [ ] [[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -107,6 +134,12 @@ dependencies = [ ] [[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -116,31 +149,48 @@ dependencies = [ ] [[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + +[[package]] +name = "linux-raw-sys" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -155,30 +205,30 @@ dependencies = [ ] [[package]] -name = "redox_users" -version = "0.4.3" +name = "redox_syscall" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", + "bitflags", ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "redox_users" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "winapi", + "getrandom", + "redox_syscall 0.2.16", + "thiserror", ] [[package]] name = "rustc-build-sysroot" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65b1271cdac365b71b59570ea35d945dea2dd2cc47eba3d33b4bd1e0190ac6d" +checksum = "8ed2a90dfa5232ed5ff21d53d4df655f315ab316ea06fc508f1c74bcedb1ce6c" dependencies = [ "anyhow", "rustc_version", @@ -207,34 +257,48 @@ dependencies = [ ] [[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "semver" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.152" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", @@ -243,9 +307,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -254,9 +318,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.107" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -265,32 +329,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", @@ -299,9 +362,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "wasi" @@ -330,3 +393,135 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 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 d4bffe5f945..b450f986149 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -eb62877597000ccf8bb99ab131b5977344afdfa3 +69fef92ab2f287f072b66fb7b4f62c8bb4acba43 diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 65bc004fc4a..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; @@ -63,7 +63,9 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { queries: &'tcx rustc_interface::Queries<'tcx>, ) -> Compilation { queries.global_ctxt().unwrap().enter(|tcx| { - tcx.sess.abort_if_errors(); + if tcx.sess.compile_status().is_err() { + tcx.sess.fatal("miri cannot be run on programs that fail compilation"); + } init_late_loggers(tcx); if !tcx.sess.crate_types().contains(&CrateType::Executable) { diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 4d7bbb643b8..29881bbcfca 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -459,7 +459,7 @@ impl<'tcx> Stack { impl Stacks { pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) { if self.modified_since_last_gc { - for stack in self.stacks.iter_mut_all() { + for (_stack_range, stack) in self.stacks.iter_mut_all() { if stack.len() > 64 { stack.retain(live_tags); } @@ -511,8 +511,8 @@ impl<'tcx> Stacks { ) -> InterpResult<'tcx>, ) -> InterpResult<'tcx> { self.modified_since_last_gc = true; - for (offset, stack) in self.stacks.iter_mut(range.start, range.size) { - let mut dcx = dcx_builder.build(&mut self.history, offset); + for (stack_range, stack) in self.stacks.iter_mut(range.start, range.size) { + let mut dcx = dcx_builder.build(&mut self.history, Size::from_bytes(stack_range.start)); f(stack, &mut dcx, &mut self.exposed_tags)?; dcx_builder = dcx.unbuild(); } 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/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index 2c6d27ced01..10873c46a6c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -3,7 +3,6 @@ use std::ops::Range; use rustc_data_structures::fx::FxHashMap; use rustc_span::{Span, SpanData}; -use rustc_target::abi::Size; use crate::borrow_tracker::tree_borrows::{ perms::{PermTransition, Permission}, @@ -14,18 +13,30 @@ use crate::borrow_tracker::{AccessKind, ProtectorKind}; use crate::*; /// Complete data for an event: -/// - `kind` is what happened to the permissions -/// - `access_kind` and `access_range` describe the access that caused the event -/// - `offset` allows filtering only the relevant events for a given memory location -/// (see how we perform the filtering in `History::extract_relevant`. -/// - `span` is the line of code in question #[derive(Clone, Debug)] pub struct Event { + /// Transformation of permissions that occured because of this event pub transition: PermTransition, + /// Kind of the access that triggered this event pub access_kind: AccessKind, + /// Relative position of the tag to the one used for the access pub is_foreign: bool, + /// User-visible range of the access pub access_range: AllocRange, - pub offset: Size, + /// The transition recorded by this event only occured on a subrange of + /// `access_range`: a single access on `access_range` triggers several events, + /// each with their own mutually disjoint `transition_range`. No-op transitions + /// should not be recorded as events, so the union of all `transition_range` is not + /// necessarily the entire `access_range`. + /// + /// No data from any `transition_range` should ever be user-visible, because + /// both the start and end of `transition_range` are entirely dependent on the + /// internal representation of `RangeMap` which is supposed to be opaque. + /// What will be shown in the error message is the first byte `error_offset` of + /// the `TbError`, which should satisfy + /// `event.transition_range.contains(error.error_offset)`. + pub transition_range: Range<u64>, + /// Line of code that triggered this event pub span: Span, } @@ -35,9 +46,9 @@ pub struct Event { /// Available filtering methods include `History::forget` and `History::extract_relevant`. #[derive(Clone, Debug)] pub struct History { - pub tag: BorTag, - pub created: (Span, Permission), - pub events: Vec<Event>, + tag: BorTag, + created: (Span, Permission), + events: Vec<Event>, } /// History formatted for use by `src/diagnostics.rs`. @@ -60,12 +71,7 @@ impl HistoryData { // Format events from `new_history` into those recorded by `self`. // // NOTE: also converts `Span` to `SpanData`. - pub fn extend( - &mut self, - new_history: History, - tag_name: &'static str, - show_initial_state: bool, - ) { + fn extend(&mut self, new_history: History, tag_name: &'static str, show_initial_state: bool) { let History { tag, created, events } = new_history; let this = format!("the {tag_name} tag {tag:?}"); let msg_initial_state = format!(", in the initial state {}", created.1); @@ -75,9 +81,16 @@ impl HistoryData { ); self.events.push((Some(created.0.data()), msg_creation)); - for &Event { transition, access_kind, is_foreign, access_range, span, offset: _ } in &events + for &Event { + transition, + access_kind, + is_foreign, + access_range, + span, + transition_range: _, + } in &events { - // NOTE: `offset` is explicitly absent from the error message, it has no significance + // NOTE: `transition_range` is explicitly absent from the error message, it has no significance // to the user. The meaningful one is `access_range`. self.events.push((Some(span.data()), format!("{this} then transitioned {transition} due to a {rel} {access_kind} at offsets {access_range:?}", rel = if is_foreign { "foreign" } else { "child" }))); self.events.push((None, format!("this corresponds to {}", transition.summary()))); @@ -197,44 +210,19 @@ impl History { History { events: Vec::new(), created: self.created, tag: self.tag } } - /// Reconstruct the history relevant to `error_offset` knowing that - /// its permission followed `complete_transition`. - /// - /// Here's how we do this: - /// - we know `full := complete_transition` the transition of the permission from - /// its initialization to the state just before the error was caused, - /// we want to find a chain of events that produces `full` - /// - we decompose `full` into `pre o post` where - /// `pre` is the best applicable transition from recorded events - /// - we select the event that caused `pre` and iterate - /// to find the chain of events that produces `full := post` - /// - /// To find the "best applicable transition" for full: - /// - eliminate events that cannot be applied because their offset is too big - /// - eliminate events that cannot be applied because their starting point is wrong - /// - select the one that happened closest to the range of interest - fn extract_relevant(&self, complete_transition: PermTransition, error_offset: Size) -> Self { - let mut selected_events: Vec<Event> = Vec::new(); - let mut full = complete_transition; - while !full.is_noop() { - let (pre, post) = self + /// Reconstruct the history relevant to `error_offset` by filtering + /// only events whose range contains the offset we are interested in. + fn extract_relevant(&self, error_offset: u64) -> Self { + History { + events: self .events .iter() - .filter(|e| e.offset <= error_offset) - .filter_map(|pre_canditate| { - full.apply_start(pre_canditate.transition) - .map(|post_canditate| (pre_canditate, post_canditate)) - }) - .max_by_key(|(pre_canditate, _post_candidate)| pre_canditate.offset) - .unwrap(); - // If this occurs we will loop infinitely ! - // Make sure to only put non-noop transitions in `History`. - assert!(!pre.transition.is_noop()); - full = post; - selected_events.push(pre.clone()); + .filter(|e| e.transition_range.contains(&error_offset)) + .cloned() + .collect::<Vec<_>>(), + created: self.created, + tag: self.tag, } - - History { events: selected_events, created: self.created, tag: self.tag } } } @@ -242,8 +230,8 @@ impl History { pub(super) struct TbError<'node> { /// What failure occurred. pub error_kind: TransitionError, - /// The byte at which the conflict occured. - pub error_offset: Size, + /// The offset (into the allocation) at which the conflict occurred. + pub error_offset: u64, /// The tag on which the error was triggered. /// On protector violations, this is the tag that was protected. /// On accesses rejected due to insufficient permissions, this is the @@ -261,12 +249,11 @@ impl TbError<'_> { /// Produce a UB error. pub fn build<'tcx>(self) -> InterpError<'tcx> { use TransitionError::*; - let started_as = self.conflicting_info.history.created.1; let kind = self.access_kind; let accessed = self.accessed_info; let conflicting = self.conflicting_info; let accessed_is_conflicting = accessed.tag == conflicting.tag; - let (pre_error, title, details, conflicting_tag_name) = match self.error_kind { + let (title, details, conflicting_tag_name) = match self.error_kind { ChildAccessForbidden(perm) => { let conflicting_tag_name = if accessed_is_conflicting { "accessed" } else { "conflicting" }; @@ -280,7 +267,7 @@ impl TbError<'_> { details.push(format!( "the {conflicting_tag_name} tag {conflicting} has state {perm} which forbids child {kind}es" )); - (perm, title, details, conflicting_tag_name) + (title, details, conflicting_tag_name) } ProtectedTransition(transition) => { let conflicting_tag_name = "protected"; @@ -297,7 +284,7 @@ impl TbError<'_> { loss = transition.summary(), ), ]; - (transition.started(), title, details, conflicting_tag_name) + (title, details, conflicting_tag_name) } ProtectedDealloc => { let conflicting_tag_name = "strongly protected"; @@ -308,16 +295,15 @@ impl TbError<'_> { ), format!("the {conflicting_tag_name} tag {conflicting} disallows deallocations"), ]; - (started_as, title, details, conflicting_tag_name) + (title, details, conflicting_tag_name) } }; - let pre_transition = PermTransition::from(started_as, pre_error).unwrap(); let mut history = HistoryData::default(); if !accessed_is_conflicting { history.extend(self.accessed_info.history.forget(), "accessed", false); } history.extend( - self.conflicting_info.history.extract_relevant(pre_transition, self.error_offset), + self.conflicting_info.history.extract_relevant(self.error_offset), conflicting_tag_name, true, ); diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index 6392f5101ad..52947aa0f9f 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -311,7 +311,7 @@ impl<'tcx> Tree { parent_tag: BorTag, new_tag: BorTag, default_initial_perm: Permission, - range: AllocRange, + reborrow_range: AllocRange, span: Span, ) -> InterpResult<'tcx> { assert!(!self.tag_mapping.contains_key(&new_tag)); @@ -332,7 +332,8 @@ impl<'tcx> Tree { self.nodes.get_mut(parent_idx).unwrap().children.push(idx); // Initialize perms let perm = LocationState::new(default_initial_perm).with_access(); - for (_range, perms) in self.rperms.iter_mut(range.start, range.size) { + for (_perms_range, perms) in self.rperms.iter_mut(reborrow_range.start, reborrow_range.size) + { perms.insert(idx, perm); } Ok(()) @@ -344,12 +345,12 @@ impl<'tcx> Tree { pub fn dealloc( &mut self, tag: BorTag, - range: AllocRange, + access_range: AllocRange, global: &GlobalState, span: Span, // diagnostics ) -> InterpResult<'tcx> { - self.perform_access(AccessKind::Write, tag, range, global, span)?; - for (offset, perms) in self.rperms.iter_mut(range.start, range.size) { + self.perform_access(AccessKind::Write, tag, access_range, global, span)?; + for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) { TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_parents_this_children_others( tag, @@ -368,7 +369,7 @@ impl<'tcx> Tree { TbError { conflicting_info, access_kind: AccessKind::Write, - error_offset: offset, + error_offset: perms_range.start, error_kind, accessed_info, } @@ -388,11 +389,11 @@ impl<'tcx> Tree { &mut self, access_kind: AccessKind, tag: BorTag, - range: AllocRange, + access_range: AllocRange, global: &GlobalState, span: Span, // diagnostics ) -> InterpResult<'tcx> { - for (offset, perms) in self.rperms.iter_mut(range.start, range.size) { + for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) { TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_parents_this_children_others( tag, @@ -456,9 +457,9 @@ impl<'tcx> Tree { node.debug_info.history.push(diagnostics::Event { transition, access_kind, - access_range: range, is_foreign: rel_pos.is_foreign(), - offset, + access_range, + transition_range: perms_range.clone(), span, }); old_state.permission = @@ -472,7 +473,7 @@ impl<'tcx> Tree { TbError { conflicting_info, access_kind, - error_offset: offset, + error_offset: perms_range.start, error_kind, accessed_info, } @@ -487,7 +488,13 @@ impl<'tcx> Tree { /// Integration with the BorTag garbage collector impl Tree { pub fn remove_unreachable_tags(&mut self, live_tags: &FxHashSet<BorTag>) { - assert!(self.keep_only_needed(self.root, live_tags)); // root can't be removed + let root_is_needed = self.keep_only_needed(self.root, live_tags); // root can't be removed + assert!(root_is_needed); + // Right after the GC runs is a good moment to check if we can + // merge some adjacent ranges that were made equal by the removal of some + // tags (this does not necessarily mean that they have identical internal representations, + // see the `PartialEq` impl for `UniValMap`) + self.rperms.merge_adjacent_thorough(); } /// Traverses the entire tree looking for useless tags. @@ -530,7 +537,7 @@ impl Tree { // the tag from the mapping. let tag = node.tag; self.nodes.remove(idx); - for perms in self.rperms.iter_mut_all() { + for (_perms_range, perms) in self.rperms.iter_mut_all() { perms.remove(idx); } self.tag_mapping.remove(&tag); diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs index c1d452ca89e..58af32385c5 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs @@ -36,13 +36,42 @@ pub struct UniKeyMap<K> { } /// From UniIndex to V -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Eq)] pub struct UniValMap<V> { /// The mapping data. Thanks to Vec we get both fast accesses, and /// a memory-optimal representation if there are few deletions. data: Vec<Option<V>>, } +impl<V: PartialEq> UniValMap<V> { + /// Exact equality of two maps. + /// Less accurate but faster than `equivalent`, mostly because + /// of the fast path when the lengths are different. + pub fn identical(&self, other: &Self) -> bool { + self.data == other.data + } + + /// Equality up to trailing `None`s of two maps, i.e. + /// do they represent the same mapping ? + pub fn equivalent(&self, other: &Self) -> bool { + let min_len = self.data.len().min(other.data.len()); + self.data[min_len..].iter().all(Option::is_none) + && other.data[min_len..].iter().all(Option::is_none) + && (self.data[..min_len] == other.data[..min_len]) + } +} + +impl<V: PartialEq> PartialEq for UniValMap<V> { + /// 2023-05: We found that using `equivalent` rather than `identical` + /// in the equality testing of the `RangeMap` is neutral for most + /// benchmarks, while being quite beneficial for `zip-equal` + /// and to a lesser extent for `unicode`, `slice-get-unchecked` and + /// `backtraces` as well. + fn eq(&self, other: &Self) -> bool { + self.equivalent(other) + } +} + impl<V> Default for UniValMap<V> { fn default() -> Self { Self { data: Vec::default() } diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 13306b4809c..f6252c43f9f 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -275,20 +275,20 @@ impl MemoryCellClocks { /// not used previously as atomic memory. fn load_acquire( &mut self, - clocks: &mut ThreadClockSet, + thread_clocks: &mut ThreadClockSet, index: VectorIdx, ) -> Result<(), DataRace> { - self.atomic_read_detect(clocks, index)?; + self.atomic_read_detect(thread_clocks, index)?; if let Some(atomic) = self.atomic() { - clocks.clock.join(&atomic.sync_vector); + thread_clocks.clock.join(&atomic.sync_vector); } Ok(()) } /// Checks if the memory cell access is ordered with all prior atomic reads and writes - fn race_free_with_atomic(&self, clocks: &ThreadClockSet) -> bool { + fn race_free_with_atomic(&self, thread_clocks: &ThreadClockSet) -> bool { if let Some(atomic) = self.atomic() { - atomic.read_vector <= clocks.clock && atomic.write_vector <= clocks.clock + atomic.read_vector <= thread_clocks.clock && atomic.write_vector <= thread_clocks.clock } else { true } @@ -299,54 +299,70 @@ impl MemoryCellClocks { /// not used previously as atomic memory. fn load_relaxed( &mut self, - clocks: &mut ThreadClockSet, + thread_clocks: &mut ThreadClockSet, index: VectorIdx, ) -> Result<(), DataRace> { - self.atomic_read_detect(clocks, index)?; + self.atomic_read_detect(thread_clocks, index)?; if let Some(atomic) = self.atomic() { - clocks.fence_acquire.join(&atomic.sync_vector); + thread_clocks.fence_acquire.join(&atomic.sync_vector); } Ok(()) } /// Update the memory cell data-race tracking for atomic /// store release semantics. - fn store_release(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> { - self.atomic_write_detect(clocks, index)?; + fn store_release( + &mut self, + thread_clocks: &ThreadClockSet, + index: VectorIdx, + ) -> Result<(), DataRace> { + self.atomic_write_detect(thread_clocks, index)?; let atomic = self.atomic_mut(); - atomic.sync_vector.clone_from(&clocks.clock); + atomic.sync_vector.clone_from(&thread_clocks.clock); Ok(()) } /// Update the memory cell data-race tracking for atomic /// store relaxed semantics. - fn store_relaxed(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> { - self.atomic_write_detect(clocks, index)?; + fn store_relaxed( + &mut self, + thread_clocks: &ThreadClockSet, + index: VectorIdx, + ) -> Result<(), DataRace> { + self.atomic_write_detect(thread_clocks, index)?; // The handling of release sequences was changed in C++20 and so // the code here is different to the paper since now all relaxed // stores block release sequences. The exception for same-thread // relaxed stores has been removed. let atomic = self.atomic_mut(); - atomic.sync_vector.clone_from(&clocks.fence_release); + atomic.sync_vector.clone_from(&thread_clocks.fence_release); Ok(()) } /// Update the memory cell data-race tracking for atomic /// store release semantics for RMW operations. - fn rmw_release(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> { - self.atomic_write_detect(clocks, index)?; + fn rmw_release( + &mut self, + thread_clocks: &ThreadClockSet, + index: VectorIdx, + ) -> Result<(), DataRace> { + self.atomic_write_detect(thread_clocks, index)?; let atomic = self.atomic_mut(); - atomic.sync_vector.join(&clocks.clock); + atomic.sync_vector.join(&thread_clocks.clock); Ok(()) } /// Update the memory cell data-race tracking for atomic /// store relaxed semantics for RMW operations. - fn rmw_relaxed(&mut self, clocks: &ThreadClockSet, index: VectorIdx) -> Result<(), DataRace> { - self.atomic_write_detect(clocks, index)?; + fn rmw_relaxed( + &mut self, + thread_clocks: &ThreadClockSet, + index: VectorIdx, + ) -> Result<(), DataRace> { + self.atomic_write_detect(thread_clocks, index)?; let atomic = self.atomic_mut(); - atomic.sync_vector.join(&clocks.fence_release); + atomic.sync_vector.join(&thread_clocks.fence_release); Ok(()) } @@ -354,26 +370,26 @@ impl MemoryCellClocks { /// not happen-before the atomic-read. fn atomic_read_detect( &mut self, - clocks: &ThreadClockSet, + thread_clocks: &ThreadClockSet, index: VectorIdx, ) -> Result<(), DataRace> { - log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, clocks); + log::trace!("Atomic read with vectors: {:#?} :: {:#?}", self, thread_clocks); let atomic = self.atomic_mut(); - atomic.read_vector.set_at_index(&clocks.clock, index); - if self.write <= clocks.clock[self.write_index] { Ok(()) } else { Err(DataRace) } + atomic.read_vector.set_at_index(&thread_clocks.clock, index); + if self.write <= thread_clocks.clock[self.write_index] { Ok(()) } else { Err(DataRace) } } /// Detect data-races with an atomic write, either with a non-atomic read or with /// a non-atomic write. fn atomic_write_detect( &mut self, - clocks: &ThreadClockSet, + thread_clocks: &ThreadClockSet, index: VectorIdx, ) -> Result<(), DataRace> { - log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, clocks); + log::trace!("Atomic write with vectors: {:#?} :: {:#?}", self, thread_clocks); let atomic = self.atomic_mut(); - atomic.write_vector.set_at_index(&clocks.clock, index); - if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock { + atomic.write_vector.set_at_index(&thread_clocks.clock, index); + if self.write <= thread_clocks.clock[self.write_index] && self.read <= thread_clocks.clock { Ok(()) } else { Err(DataRace) @@ -384,21 +400,21 @@ impl MemoryCellClocks { /// returns true if a data-race is detected. fn read_race_detect( &mut self, - clocks: &mut ThreadClockSet, + thread_clocks: &mut ThreadClockSet, index: VectorIdx, current_span: Span, ) -> Result<(), DataRace> { - log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, clocks); + log::trace!("Unsynchronized read with vectors: {:#?} :: {:#?}", self, thread_clocks); if !current_span.is_dummy() { - clocks.clock[index].span = current_span; + thread_clocks.clock[index].span = current_span; } - if self.write <= clocks.clock[self.write_index] { + if self.write <= thread_clocks.clock[self.write_index] { let race_free = if let Some(atomic) = self.atomic() { - atomic.write_vector <= clocks.clock + atomic.write_vector <= thread_clocks.clock } else { true }; - self.read.set_at_index(&clocks.clock, index); + self.read.set_at_index(&thread_clocks.clock, index); if race_free { Ok(()) } else { Err(DataRace) } } else { Err(DataRace) @@ -409,22 +425,23 @@ impl MemoryCellClocks { /// returns true if a data-race is detected. fn write_race_detect( &mut self, - clocks: &mut ThreadClockSet, + thread_clocks: &mut ThreadClockSet, index: VectorIdx, write_type: WriteType, current_span: Span, ) -> Result<(), DataRace> { - log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, clocks); + log::trace!("Unsynchronized write with vectors: {:#?} :: {:#?}", self, thread_clocks); if !current_span.is_dummy() { - clocks.clock[index].span = current_span; + thread_clocks.clock[index].span = current_span; } - if self.write <= clocks.clock[self.write_index] && self.read <= clocks.clock { + if self.write <= thread_clocks.clock[self.write_index] && self.read <= thread_clocks.clock { let race_free = if let Some(atomic) = self.atomic() { - atomic.write_vector <= clocks.clock && atomic.read_vector <= clocks.clock + atomic.write_vector <= thread_clocks.clock + && atomic.read_vector <= thread_clocks.clock } else { true }; - self.write = clocks.clock[index]; + self.write = thread_clocks.clock[index]; self.write_index = index; self.write_type = write_type; if race_free { @@ -764,24 +781,24 @@ impl VClockAlloc { fn report_data_race<'tcx>( global: &GlobalState, thread_mgr: &ThreadManager<'_, '_>, - range: &MemoryCellClocks, + mem_clocks: &MemoryCellClocks, action: &str, is_atomic: bool, ptr_dbg: Pointer<AllocId>, ) -> InterpResult<'tcx> { let (current_index, current_clocks) = global.current_thread_state(thread_mgr); let write_clock; - let (other_action, other_thread, other_clock) = if range.write - > current_clocks.clock[range.write_index] + let (other_action, other_thread, other_clock) = if mem_clocks.write + > current_clocks.clock[mem_clocks.write_index] { // Convert the write action into the vector clock it // represents for diagnostic purposes. - write_clock = VClock::new_with_index(range.write_index, range.write); - (range.write_type.get_descriptor(), range.write_index, &write_clock) - } else if let Some(idx) = Self::find_gt_index(&range.read, ¤t_clocks.clock) { - ("Read", idx, &range.read) + write_clock = VClock::new_with_index(mem_clocks.write_index, mem_clocks.write); + (mem_clocks.write_type.get_descriptor(), mem_clocks.write_index, &write_clock) + } else if let Some(idx) = Self::find_gt_index(&mem_clocks.read, ¤t_clocks.clock) { + ("Read", idx, &mem_clocks.read) } else if !is_atomic { - if let Some(atomic) = range.atomic() { + if let Some(atomic) = mem_clocks.atomic() { if let Some(idx) = Self::find_gt_index(&atomic.write_vector, ¤t_clocks.clock) { ("Atomic Store", idx, &atomic.write_vector) @@ -832,10 +849,10 @@ impl VClockAlloc { thread_mgr: &ThreadManager<'_, '_>, ) -> bool { if global.race_detecting() { - let (_, clocks) = global.current_thread_state(thread_mgr); + let (_, thread_clocks) = global.current_thread_state(thread_mgr); let alloc_ranges = self.alloc_ranges.borrow(); - for (_, range) in alloc_ranges.iter(range.start, range.size) { - if !range.race_free_with_atomic(&clocks) { + for (_, mem_clocks) in alloc_ranges.iter(range.start, range.size) { + if !mem_clocks.race_free_with_atomic(&thread_clocks) { return false; } } @@ -851,25 +868,29 @@ impl VClockAlloc { pub fn read<'tcx>( &self, alloc_id: AllocId, - range: AllocRange, + access_range: AllocRange, machine: &MiriMachine<'_, '_>, ) -> InterpResult<'tcx> { let current_span = machine.current_span(); let global = machine.data_race.as_ref().unwrap(); if global.race_detecting() { - let (index, mut clocks) = global.current_thread_state_mut(&machine.threads); + let (index, mut thread_clocks) = global.current_thread_state_mut(&machine.threads); let mut alloc_ranges = self.alloc_ranges.borrow_mut(); - for (offset, range) in alloc_ranges.iter_mut(range.start, range.size) { - if let Err(DataRace) = range.read_race_detect(&mut clocks, index, current_span) { - drop(clocks); + for (mem_clocks_range, mem_clocks) in + alloc_ranges.iter_mut(access_range.start, access_range.size) + { + if let Err(DataRace) = + mem_clocks.read_race_detect(&mut thread_clocks, index, current_span) + { + drop(thread_clocks); // Report data-race. return Self::report_data_race( global, &machine.threads, - range, + mem_clocks, "Read", false, - Pointer::new(alloc_id, offset), + Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)), ); } } @@ -883,27 +904,32 @@ impl VClockAlloc { fn unique_access<'tcx>( &mut self, alloc_id: AllocId, - range: AllocRange, + access_range: AllocRange, write_type: WriteType, machine: &mut MiriMachine<'_, '_>, ) -> InterpResult<'tcx> { let current_span = machine.current_span(); let global = machine.data_race.as_mut().unwrap(); if global.race_detecting() { - let (index, mut clocks) = global.current_thread_state_mut(&machine.threads); - for (offset, range) in self.alloc_ranges.get_mut().iter_mut(range.start, range.size) { - if let Err(DataRace) = - range.write_race_detect(&mut clocks, index, write_type, current_span) - { - drop(clocks); + let (index, mut thread_clocks) = global.current_thread_state_mut(&machine.threads); + for (mem_clocks_range, mem_clocks) in + self.alloc_ranges.get_mut().iter_mut(access_range.start, access_range.size) + { + if let Err(DataRace) = mem_clocks.write_race_detect( + &mut thread_clocks, + index, + write_type, + current_span, + ) { + drop(thread_clocks); // Report data-race return Self::report_data_race( global, &machine.threads, - range, + mem_clocks, write_type.get_descriptor(), false, - Pointer::new(alloc_id, offset), + Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)), ); } } @@ -1125,19 +1151,23 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { data_race.maybe_perform_sync_operation( &this.machine.threads, current_span, - |index, mut clocks| { - for (offset, range) in + |index, mut thread_clocks| { + for (mem_clocks_range, mem_clocks) in alloc_meta.alloc_ranges.borrow_mut().iter_mut(base_offset, size) { - if let Err(DataRace) = op(range, &mut clocks, index, atomic) { - mem::drop(clocks); + if let Err(DataRace) = op(mem_clocks, &mut thread_clocks, index, atomic) + { + mem::drop(thread_clocks); return VClockAlloc::report_data_race( data_race, &this.machine.threads, - range, + mem_clocks, description, true, - Pointer::new(alloc_id, offset), + Pointer::new( + alloc_id, + Size::from_bytes(mem_clocks_range.start), + ), ) .map(|_| true); } @@ -1150,13 +1180,14 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // Log changes to atomic memory. if log::log_enabled!(log::Level::Trace) { - for (_offset, range) in alloc_meta.alloc_ranges.borrow().iter(base_offset, size) + for (_offset, mem_clocks) in + alloc_meta.alloc_ranges.borrow().iter(base_offset, size) { log::trace!( "Updated atomic memory({:?}, size={}) to {:#?}", place.ptr, size.bytes(), - range.atomic_ops + mem_clocks.atomic_ops ); } } 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/machine.rs b/src/tools/miri/src/machine.rs index 21c5a9c1b70..32717a0d28b 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -4,6 +4,8 @@ use std::borrow::Cow; use std::cell::RefCell; use std::fmt; +use std::path::Path; +use std::process; use rand::rngs::StdRng; use rand::SeedableRng; @@ -498,7 +500,21 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { let layouts = PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types"); let profiler = config.measureme_out.as_ref().map(|out| { - measureme::Profiler::new(out).expect("Couldn't create `measureme` profiler") + let crate_name = layout_cx + .tcx + .sess + .opts + .crate_name + .clone() + .unwrap_or_else(|| "unknown-crate".to_string()); + let pid = process::id(); + // We adopt the same naming scheme for the profiler output that rustc uses. In rustc, + // the PID is padded so that the nondeterministic value of the PID does not spread + // nondeterminisim to the allocator. In Miri we are not aiming for such performance + // control, we just pad for consistency with rustc. + let filename = format!("{crate_name}-{pid:07}"); + let path = Path::new(out).join(filename); + measureme::Profiler::new(path).expect("Couldn't create `measureme` profiler") }); let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0)); let borrow_tracker = config.borrow_tracker.map(|bt| bt.instantiate_global_state(config)); diff --git a/src/tools/miri/src/range_map.rs b/src/tools/miri/src/range_map.rs index 62198061827..146715ddda2 100644 --- a/src/tools/miri/src/range_map.rs +++ b/src/tools/miri/src/range_map.rs @@ -62,8 +62,10 @@ impl<T> RangeMap<T> { /// *not* split items if they overlap with the edges. Do not use this to mutate /// through interior mutability. /// - /// The iterator also provides the offset of the given element. - pub fn iter(&self, offset: Size, len: Size) -> impl Iterator<Item = (Size, &T)> { + /// The iterator also provides the range of the given element. + /// How exactly the ranges are split can differ even for otherwise identical + /// maps, so user-visible behavior should never depend on the exact range. + pub fn iter(&self, offset: Size, len: Size) -> impl Iterator<Item = (ops::Range<u64>, &T)> { let offset = offset.bytes(); let len = len.bytes(); // Compute a slice starting with the elements we care about. @@ -84,13 +86,21 @@ impl<T> RangeMap<T> { slice .iter() .take_while(move |elem| elem.range.start < end) - .map(|elem| (Size::from_bytes(elem.range.start), &elem.data)) + .map(|elem| (elem.range.clone(), &elem.data)) } - pub fn iter_mut_all(&mut self) -> impl Iterator<Item = &mut T> { - self.v.iter_mut().map(|elem| &mut elem.data) + /// Provides mutable iteration over all elements. + /// The iterator also provides the range of the given element. + /// How exactly the ranges are split can differ even for otherwise identical + /// maps, so user-visible behavior should never depend on the exact range. + pub fn iter_mut_all(&mut self) -> impl Iterator<Item = (ops::Range<u64>, &mut T)> { + self.v.iter_mut().map(|elem| (elem.range.clone(), &mut elem.data)) } + /// Provides iteration over all elements. + /// The iterator also provides the range of the given element. + /// How exactly the ranges are split can differ even for otherwise identical + /// maps, so user-visible behavior should never depend on the exact range. pub fn iter_all(&self) -> impl Iterator<Item = (ops::Range<u64>, &T)> { self.v.iter().map(|elem| (elem.range.clone(), &elem.data)) } @@ -126,8 +136,15 @@ impl<T> RangeMap<T> { /// to make sure that when they are mutated, the effect is constrained to the given range. /// Moreover, this will opportunistically merge neighbouring equal blocks. /// - /// The iterator also provides the offset of the given element. - pub fn iter_mut(&mut self, offset: Size, len: Size) -> impl Iterator<Item = (Size, &mut T)> + /// The iterator also provides the range of the given element. + /// How exactly the ranges are split (both prior to and resulting from the execution of this + /// function) can differ even for otherwise identical maps, + /// so user-visible behavior should never depend on the exact range. + pub fn iter_mut( + &mut self, + offset: Size, + len: Size, + ) -> impl Iterator<Item = (ops::Range<u64>, &mut T)> where T: Clone + PartialEq, { @@ -208,7 +225,25 @@ impl<T> RangeMap<T> { // Now we yield the slice. `end` is inclusive. &mut self.v[first_idx..=end_idx] }; - slice.iter_mut().map(|elem| (Size::from_bytes(elem.range.start), &mut elem.data)) + slice.iter_mut().map(|elem| (elem.range.clone(), &mut elem.data)) + } + + /// Remove all adjacent duplicates + pub fn merge_adjacent_thorough(&mut self) + where + T: PartialEq, + { + let clean = Vec::with_capacity(self.v.len()); + for elem in std::mem::replace(&mut self.v, clean) { + if let Some(prev) = self.v.last_mut() { + if prev.data == elem.data { + assert_eq!(prev.range.end, elem.range.start); + prev.range.end = elem.range.end; + continue; + } + } + self.v.push(elem); + } } } 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/test-cargo-miri/subcrate/src/lib.rs b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs index 2ccb6704b05..98c22fef076 100644 --- a/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs +++ b/src/tools/miri/test-cargo-miri/subcrate/src/lib.rs @@ -1,5 +1,16 @@ +// This is a proc-macro crate. + +extern crate proc_macro; // make sure proc_macro is in the sysroot + #[cfg(doctest)] compile_error!("rustdoc should not touch me"); -#[cfg(test)] +#[cfg(miri)] compile_error!("Miri should not touch me"); + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn make_answer(_item: TokenStream) -> TokenStream { + "fn answer() -> u32 { 42 }".parse().unwrap() +} diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs index 52deba9108c..fa06c4b6a12 100644 --- a/src/tools/miri/tests/compiletest.rs +++ b/src/tools/miri/tests/compiletest.rs @@ -1,7 +1,10 @@ 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; +use ui_test::CommandBuilder; use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling}; fn miri_path() -> PathBuf { @@ -43,18 +46,10 @@ fn build_so_for_c_ffi_tests() -> PathBuf { so_file_path } -fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> { - let mut config = Config { - target: Some(target.to_owned()), - stderr_filters: STDERR.clone(), - stdout_filters: STDOUT.clone(), - root_dir: PathBuf::from(path), - mode, - program: miri_path(), - quiet: false, - edition: Some("2018".into()), - ..Config::default() - }; +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(); let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some(); @@ -62,22 +57,20 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R if in_rustc_test_suite { // Less aggressive warnings to make the rustc toolstate management less painful. // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.) - config.args.push("-Astable-features".into()); - config.args.push("-Aunused".into()); + program.args.push("-Astable-features".into()); + program.args.push("-Aunused".into()); } else { - config.args.push("-Dwarnings".into()); - config.args.push("-Dunused".into()); + program.args.push("-Dwarnings".into()); + program.args.push("-Dunused".into()); } if let Ok(extra_flags) = env::var("MIRIFLAGS") { for flag in extra_flags.split_whitespace() { - config.args.push(flag.into()); + program.args.push(flag.into()); } } - config.args.push("-Zui-testing".into()); - if let Some(target) = &config.target { - config.args.push("--target".into()); - config.args.push(target.into()); - } + program.args.push("-Zui-testing".into()); + program.args.push("--target".into()); + program.args.push(target.into()); // If we're on linux, and we're testing the extern-so functionality, // then build the shared object file for testing external C function calls @@ -86,18 +79,51 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R let so_file_path = build_so_for_c_ffi_tests(); let mut flag = std::ffi::OsString::from("-Zmiri-extern-so-file="); flag.push(so_file_path.into_os_string()); - config.args.push(flag); + program.args.push(flag); } let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some(); - config.output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) { + let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) { (false, false) => OutputConflictHandling::Error, (true, false) => OutputConflictHandling::Bless, (false, true) => OutputConflictHandling::Ignore, (true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"), }; + let mut config = Config { + target: Some(target.to_owned()), + stderr_filters: STDERR.clone(), + stdout_filters: STDOUT.clone(), + root_dir: PathBuf::from(path), + mode, + program, + output_conflict_handling, + quiet: false, + edition: Some("2021".into()), + ..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| { @@ -121,21 +147,15 @@ 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`. - ]; - } - ui_test::run_tests(config) + eprintln!(" Compiler: {}", config.program.display()); + ui_test::run_tests_generic( + config, + // The files we're actually interested in (all `.rs` files). + |path| path.extension().is_some_and(|ext| ext == "rs"), + // This could be used to overwrite the `Config` on a per-test basis. + |_, _| None, + TextAndGha, + ) } macro_rules! regexes { @@ -212,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). @@ -235,3 +265,60 @@ 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; +impl StatusEmitter for TextAndGha { + fn failed_test<'a>( + &'a self, + revision: &'a str, + path: &'a Path, + cmd: &'a Command, + stderr: &'a [u8], + ) -> Box<dyn std::fmt::Debug + 'a> { + Box::new(( + ui_test::status_emitter::Gha::<false>.failed_test(revision, path, cmd, stderr), + ui_test::status_emitter::Text.failed_test(revision, path, cmd, stderr), + )) + } + + fn run_tests(&self, _config: &Config) -> Box<dyn ui_test::status_emitter::DuringTestRun> { + Box::new(TextAndGha) + } + + fn finalize( + &self, + failures: usize, + succeeded: usize, + ignored: usize, + filtered: usize, + ) -> Box<dyn ui_test::status_emitter::Summary> { + Box::new(( + ui_test::status_emitter::Gha::<false>.finalize(failures, succeeded, ignored, filtered), + ui_test::status_emitter::Text.finalize(failures, succeeded, ignored, filtered), + )) + } +} + +impl ui_test::status_emitter::DuringTestRun for TextAndGha { + fn test_result(&mut self, path: &Path, revision: &str, result: &ui_test::TestResult) { + ui_test::status_emitter::Text.test_result(path, revision, result); + ui_test::status_emitter::Gha::<false>.test_result(path, revision, result); + } +} diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs index a07d8254ad3..e8ba824db71 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs @@ -1,6 +1,6 @@ use std::alloc::{alloc, dealloc, Layout}; -//@error-pattern: has size 1 and alignment 1, but gave size 1 and alignment 2 +//@error-in-other-file: has size 1 and alignment 1, but gave size 1 and alignment 2 fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs index 47aaef1935e..e3f9a20ac3b 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs @@ -1,6 +1,6 @@ use std::alloc::{alloc, dealloc, Layout}; -//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1 +//@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1 fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs index 1eb9bbf91ca..f07bbda4a9b 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs +++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs @@ -1,6 +1,6 @@ use std::alloc::{alloc, dealloc, Layout}; -//@error-pattern: dereferenced after this allocation got freed +//@error-in-other-file: dereferenced after this allocation got freed fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs index 47b098c71a2..2e88e5644e4 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs @@ -1,6 +1,6 @@ // Make sure we detect when the `Global` and `System` allocators are mixed // (even when the default `Global` uses `System`). -//@error-pattern: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/ +//@error-in-other-file: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/ //@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation" //@normalize-stderr-test: "\| +\^+" -> "| ^" diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs index 145c3393d67..49b2c62d7e4 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs +++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs @@ -1,6 +1,6 @@ use std::alloc::{alloc, realloc, Layout}; -//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1 +//@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1 fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs index 34f1658344a..130e2a8301e 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs +++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs @@ -1,6 +1,6 @@ use std::alloc::{alloc, dealloc, realloc, Layout}; -//@error-pattern: dereferenced after this allocation got freed +//@error-in-other-file: dereferenced after this allocation got freed fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/alloc/stack_free.rs b/src/tools/miri/tests/fail/alloc/stack_free.rs index baf53decc44..15a17a25afe 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.rs +++ b/src/tools/miri/tests/fail/alloc/stack_free.rs @@ -1,7 +1,7 @@ // Validation/SB changes why we fail //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -//@error-pattern: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/ +//@error-in-other-file: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/ fn main() { let x = 42; diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs index 065ad2d725f..7e6f490bb3d 100644 --- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs +++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs @@ -1,5 +1,5 @@ //@ignore-target-windows: No libc on Windows -//@error-pattern: the main thread terminated without waiting for all remaining threads +//@error-in-other-file: the main thread terminated without waiting for all remaining threads // Check that we terminate the program when the main thread terminates. diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr index 94463bef8f0..c2de4afd68f 100644 --- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr +++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr @@ -7,8 +7,8 @@ LL | panic!() = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC - = 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: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC + = 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: aborting due to previous error diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr index fdbe91cc8a8..85ae930d439 100644 --- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr +++ b/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr @@ -7,8 +7,8 @@ LL | panic!() = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `thread_start` at RUSTLIB/std/src/panic.rs:LL:CC - = 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: inside `thread_start` at RUSTLIB/core/src/panic.rs:LL:CC + = 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: aborting due to previous error diff --git a/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs b/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs index 548ed63534d..b68a07797f8 100644 --- a/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs +++ b/src/tools/miri/tests/fail/concurrency/windows_join_detached.rs @@ -1,5 +1,5 @@ //@only-target-windows: Uses win32 api functions -//@error-pattern: Undefined Behavior: trying to join a detached thread +//@error-in-other-file: Undefined Behavior: trying to join a detached thread // Joining a detached thread is undefined behavior. diff --git a/src/tools/miri/tests/fail/const-ub-checks.rs b/src/tools/miri/tests/fail/const-ub-checks.rs index fa522c30cbd..9cc8b91ff50 100644 --- a/src/tools/miri/tests/fail/const-ub-checks.rs +++ b/src/tools/miri/tests/fail/const-ub-checks.rs @@ -1,5 +1,3 @@ -#![feature(const_ptr_read)] - const UNALIGNED_READ: () = unsafe { let x = &[0u8; 4]; let ptr = x.as_ptr().cast::<u32>(); diff --git a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs index 2698c63a445..42077dfae2d 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_read_race.rs +++ b/src/tools/miri/tests/fail/data_race/alloc_read_race.rs @@ -26,6 +26,7 @@ pub fn main() { // 2. write unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing // Concurrent allocate the memory. // Uses relaxed semantics to not generate // a release sequence. @@ -34,6 +35,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; // Note: could also error due to reading uninitialized memory, but the data-race detector triggers first. diff --git a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs index b78d5ef27d3..53f4e637a19 100644 --- a/src/tools/miri/tests/fail/data_race/alloc_write_race.rs +++ b/src/tools/miri/tests/fail/data_race/alloc_write_race.rs @@ -25,6 +25,7 @@ pub fn main() { // 2. write unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing // Concurrent allocate the memory. // Uses relaxed semantics to not generate // a release sequence. @@ -34,6 +35,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; *pointer.load(Ordering::Relaxed) = 2; //~ ERROR: Data race detected between (1) Allocate on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs index 3f811d0f64d..9606df1d6ff 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race1.rs @@ -16,10 +16,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *(c.0 as *mut usize) = 32; }); let j2 = spawn(move || { + let c = c; // avoid field capturing (&*c.0).load(Ordering::SeqCst) //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Load on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs index 34fb3ac066f..0e29ab32eef 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_read_na_write_race2.rs @@ -17,11 +17,13 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; atomic_ref.load(Ordering::SeqCst) }); let j2 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; *atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Load on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs index 63b0806f3bb..6f1792bc8f4 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race1.rs @@ -17,11 +17,13 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; atomic_ref.store(32, Ordering::SeqCst) }); let j2 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; *atomic_ref.get_mut() //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Read on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs index 9092254be21..e84207e655d 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_read_race2.rs @@ -16,10 +16,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing let _val = *(c.0 as *mut usize); }); let j2 = spawn(move || { + let c = c; // avoid field capturing (&*c.0).store(32, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs index 5a713905f4e..ca269b1bd2a 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race1.rs @@ -16,10 +16,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *(c.0 as *mut usize) = 32; }); let j2 = spawn(move || { + let c = c; // avoid field capturing (&*c.0).store(64, Ordering::SeqCst); //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Atomic Store on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs index 5848aa262b3..0d69a9a332d 100644 --- a/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs +++ b/src/tools/miri/tests/fail/data_race/atomic_write_na_write_race2.rs @@ -17,11 +17,13 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; atomic_ref.store(64, Ordering::SeqCst); }); let j2 = spawn(move || { + let c = c; // avoid field capturing let atomic_ref = &mut *c.0; *atomic_ref.get_mut() = 32; //~ ERROR: Data race detected between (1) Atomic Store on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs index eecb980e905..0679b81f012 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs @@ -18,6 +18,7 @@ fn main() { let join = unsafe { spawn(move || { + let c = c; // capture `c`, not just its field. *c.0 = 32; }) }; @@ -34,6 +35,7 @@ fn main() { let join2 = unsafe { spawn(move || { + let c = c; // capture `c`, not just its field. *c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` }) }; diff --git a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs index 4c7fbdd7fe6..3c5dd424eb1 100644 --- a/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs +++ b/src/tools/miri/tests/fail/data_race/dangling_thread_race.rs @@ -18,6 +18,7 @@ fn main() { let join = unsafe { spawn(move || { + let c = c; // avoid field capturing *c.0 = 32; }) }; diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs index 18593cf56ae..3c25cdc0d8d 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs @@ -20,10 +20,12 @@ pub fn main() { unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing let _val = *ptr.0; }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing __rust_dealloc( //~^ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` ptr.0 as *mut _, diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs index a6f83d489e5..5d7a0cc1dc9 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs @@ -20,6 +20,7 @@ pub fn main() { unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing __rust_dealloc( ptr.0 as *mut _, std::mem::size_of::<usize>(), @@ -28,6 +29,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing // Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Read on thread `<unnamed>` // but the invalid allocation is detected first. *ptr.0 //~ ERROR: dereferenced after this allocation got freed diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs index c82bfed09ee..87b5f204816 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs @@ -26,6 +26,7 @@ pub fn main() { // 3. stack-deallocate unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; { let mut stack_var = 0usize; @@ -39,6 +40,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; *pointer.load(Ordering::Acquire) }); diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs index 1e93a6cb094..b700f50ce19 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs @@ -19,10 +19,12 @@ pub fn main() { unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing *ptr.0 = 2; }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing __rust_dealloc( //~^ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Deallocate on thread `<unnamed>` ptr.0 as *mut _, diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs index 385584db27f..a7f43f03c02 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs @@ -19,6 +19,7 @@ pub fn main() { unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing __rust_dealloc( ptr.0 as *mut _, std::mem::size_of::<usize>(), @@ -27,6 +28,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing // Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Write on thread `<unnamed>` // but the invalid allocation is detected first. *ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs index 259fbdc497a..3d35187a018 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs @@ -26,6 +26,7 @@ pub fn main() { // 3. stack-deallocate unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; { let mut stack_var = 0usize; @@ -39,6 +40,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; *pointer.load(Ordering::Acquire) = 3; }); diff --git a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs index 3d47b1accb3..b44be4ac64e 100644 --- a/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs +++ b/src/tools/miri/tests/fail/data_race/enable_after_join_to_main.rs @@ -26,10 +26,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 32; }); let j2 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/read_write_race.rs b/src/tools/miri/tests/fail/data_race/read_write_race.rs index d996141db3e..aed3ca767f6 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race.rs +++ b/src/tools/miri/tests/fail/data_race/read_write_race.rs @@ -15,10 +15,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing let _val = *c.0; }); let j2 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 64; //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs index b4e371f430d..40224ced12d 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs @@ -31,6 +31,7 @@ pub fn main() { // 5. read-value unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing // Concurrent allocate the memory. // Uses relaxed semantics to not generate // a release sequence. @@ -46,6 +47,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; *pointer.load(Ordering::Acquire) = 3; }); diff --git a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs index b7226fa626f..1b691b996f1 100644 --- a/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs +++ b/src/tools/miri/tests/fail/data_race/relax_acquire_race.rs @@ -25,6 +25,7 @@ pub fn main() { // 4. load acquire : 2 unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 1; SYNC.store(1, Ordering::Release); }); @@ -36,6 +37,7 @@ pub fn main() { }); let j3 = spawn(move || { + let c = c; // avoid field capturing if SYNC.load(Ordering::Acquire) == 2 { *c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` } else { diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race.rs b/src/tools/miri/tests/fail/data_race/release_seq_race.rs index dff33a42a1c..80b30053fc7 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race.rs +++ b/src/tools/miri/tests/fail/data_race/release_seq_race.rs @@ -27,6 +27,7 @@ pub fn main() { // 4. load acquire : 3 unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 1; SYNC.store(1, Ordering::Release); sleep(Duration::from_millis(200)); @@ -39,6 +40,7 @@ pub fn main() { }); let j3 = spawn(move || { + let c = c; // avoid field capturing sleep(Duration::from_millis(500)); if SYNC.load(Ordering::Acquire) == 3 { *c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` diff --git a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs index f7a523841b8..33de1f17558 100644 --- a/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs +++ b/src/tools/miri/tests/fail/data_race/release_seq_race_same_thread.rs @@ -25,6 +25,7 @@ pub fn main() { // 3. load acquire : 2 unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 1; SYNC.store(1, Ordering::Release); @@ -36,6 +37,7 @@ pub fn main() { }); let j2 = spawn(move || { + let c = c; // avoid field capturing if SYNC.load(Ordering::Acquire) == 2 { *c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` } else { diff --git a/src/tools/miri/tests/fail/data_race/rmw_race.rs b/src/tools/miri/tests/fail/data_race/rmw_race.rs index 2201362b167..4d0ce8f9433 100644 --- a/src/tools/miri/tests/fail/data_race/rmw_race.rs +++ b/src/tools/miri/tests/fail/data_race/rmw_race.rs @@ -25,6 +25,7 @@ pub fn main() { // 4. load acquire : 3 unsafe { let j1 = spawn(move || { + let c = c; // capture `c`, not just its field. *c.0 = 1; SYNC.store(1, Ordering::Release); }); @@ -37,6 +38,7 @@ pub fn main() { }); let j3 = spawn(move || { + let c = c; // capture `c`, not just its field. if SYNC.load(Ordering::Acquire) == 3 { *c.0 //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Read on thread `<unnamed>` } else { diff --git a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs index dec5ff274cc..d3c2ab3e4a4 100644 --- a/src/tools/miri/tests/fail/data_race/stack_pop_race.rs +++ b/src/tools/miri/tests/fail/data_race/stack_pop_race.rs @@ -13,7 +13,7 @@ fn main() { fn race(local: i32) { let ptr = MakeSend(&local as *const i32); thread::spawn(move || { - let ptr = ptr; + let ptr = ptr; // avoid field capturing let _val = unsafe { *ptr.0 }; }); // Make the other thread go first so that it does not UAF. diff --git a/src/tools/miri/tests/fail/data_race/write_write_race.rs b/src/tools/miri/tests/fail/data_race/write_write_race.rs index fe02d02f9dc..30e3460f222 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race.rs +++ b/src/tools/miri/tests/fail/data_race/write_write_race.rs @@ -15,10 +15,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 32; }); let j2 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 64; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>` }); diff --git a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs index c1c1b1fa6e3..25be42bd4eb 100644 --- a/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/write_write_race_stack.rs @@ -28,6 +28,7 @@ pub fn main() { // 5. write-value unsafe { let j1 = spawn(move || { + let ptr = ptr; // avoid field capturing // Concurrent allocate the memory. // Uses relaxed semantics to not generate // a release sequence. @@ -46,6 +47,7 @@ pub fn main() { }); let j2 = spawn(move || { + let ptr = ptr; // avoid field capturing let pointer = &*ptr.0; *pointer.load(Ordering::Acquire) = 3; }); diff --git a/src/tools/miri/tests/fail/deny_lint.rs b/src/tools/miri/tests/fail/deny_lint.rs new file mode 100644 index 00000000000..f49fa49d09d --- /dev/null +++ b/src/tools/miri/tests/fail/deny_lint.rs @@ -0,0 +1,8 @@ +//@error-in-other-file: miri cannot be run on programs that fail compilation + +#![deny(warnings, unused)] + +struct Foo; +//~^ ERROR: struct `Foo` is never constructed + +fn main() {} diff --git a/src/tools/miri/tests/fail/deny_lint.stderr b/src/tools/miri/tests/fail/deny_lint.stderr new file mode 100644 index 00000000000..d1c9b481807 --- /dev/null +++ b/src/tools/miri/tests/fail/deny_lint.stderr @@ -0,0 +1,17 @@ +error: struct `Foo` is never constructed + --> $DIR/deny_lint.rs:LL:CC + | +LL | struct Foo; + | ^^^ + | +note: the lint level is defined here + --> $DIR/deny_lint.rs:LL:CC + | +LL | #![deny(warnings, unused)] + | ^^^^^^ + = note: `#[deny(dead_code)]` implied by `#[deny(unused)]` + +error: miri cannot be run on programs that fail compilation + +error: aborting due to 2 previous errors + diff --git a/src/tools/miri/tests/fail/erroneous_const.stderr b/src/tools/miri/tests/fail/erroneous_const.stderr index c32ebf67a11..209c4a932dc 100644 --- a/src/tools/miri/tests/fail/erroneous_const.stderr +++ b/src/tools/miri/tests/fail/erroneous_const.stderr @@ -4,7 +4,7 @@ error[E0080]: evaluation of `PrintName::<i32>::VOID` failed LL | const VOID: ! = panic!(); | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/erroneous_const.rs:LL:CC | - = 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: 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) note: erroneous constant used --> $DIR/erroneous_const.rs:LL:CC diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs index a5bae36d92a..10939c0f1c3 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs +++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.rs @@ -1,9 +1,8 @@ -//@error-pattern: cannot be represented in target type `i32` #![feature(portable_simd)] use std::simd::*; fn main() { unsafe { - let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); + let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); //~ERROR: cannot be represented in target type `i32` } } diff --git a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr index 5c73c76a161..ea5ad62aea9 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-float-to-int.stderr @@ -1,18 +1,13 @@ error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32` - --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC + --> $DIR/simd-float-to-int.rs:LL:CC | -LL | unsafe { intrinsics::simd_cast(self) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32` +LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32` | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `std::simd::Simd::<f32, 2>::to_int_unchecked::<i32>` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` - --> $DIR/simd-float-to-int.rs:LL:CC - | -LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at $DIR/simd-float-to-int.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.rs b/src/tools/miri/tests/fail/intrinsics/simd-gather.rs index e394cce9a4f..ceb7beebd8a 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-gather.rs +++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.rs @@ -1,4 +1,3 @@ -//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds #![feature(portable_simd)] use std::simd::*; @@ -6,6 +5,6 @@ fn main() { unsafe { let vec: &[i8] = &[10, 11, 12, 13, 14, 15, 16, 17, 18]; let idxs = Simd::from_array([9, 3, 0, 17]); - let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); + let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); //~ERROR: pointer to 1 byte starting at offset 9 is out-of-bounds } } diff --git a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr index 7512d57f672..f82b30a9633 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-gather.stderr @@ -1,18 +1,13 @@ error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds - --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC + --> $DIR/simd-gather.rs:LL:CC | -LL | unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds +LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `std::simd::Simd::<i8, 4>::gather_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` - --> $DIR/simd-gather.rs:LL:CC - | -LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at $DIR/simd-gather.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs b/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs index d2bc7339954..98b6749c584 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs +++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.rs @@ -1,4 +1,3 @@ -//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds #![feature(portable_simd)] use std::simd::*; @@ -7,6 +6,7 @@ fn main() { let mut vec: Vec<i8> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; let idxs = Simd::from_array([9, 3, 0, 17]); Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked( + //~^ERROR: pointer to 1 byte starting at offset 9 is out-of-bounds &mut vec, Mask::splat(true), idxs, diff --git a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr index a9ad60a0e5b..a745b61029d 100644 --- a/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr +++ b/src/tools/miri/tests/fail/intrinsics/simd-scatter.stderr @@ -1,22 +1,18 @@ error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds - --> RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC - | -LL | intrinsics::simd_scatter(self, ptrs, enable.to_int()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `std::simd::Simd::<i8, 4>::scatter_select_unchecked` at RUSTLIB/core/src/../../portable-simd/crates/core_simd/src/vector.rs:LL:CC -note: inside `main` --> $DIR/simd-scatter.rs:LL:CC | LL | / Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked( +LL | | LL | | &mut vec, LL | | Mask::splat(true), LL | | idxs, LL | | ); - | |_________^ + | |_________^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/simd-scatter.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/layout_cycle.rs b/src/tools/miri/tests/fail/layout_cycle.rs index d050310bd80..3e0dd881db8 100644 --- a/src/tools/miri/tests/fail/layout_cycle.rs +++ b/src/tools/miri/tests/fail/layout_cycle.rs @@ -1,4 +1,4 @@ -//@error-pattern: a cycle occurred during layout computation +//@error-in-other-file: a cycle occurred during layout computation //~^ ERROR: cycle detected when computing layout of use std::mem; diff --git a/src/tools/miri/tests/fail/memleak.rs b/src/tools/miri/tests/fail/memleak.rs index cbeb163b56c..984b44d6d40 100644 --- a/src/tools/miri/tests/fail/memleak.rs +++ b/src/tools/miri/tests/fail/memleak.rs @@ -1,4 +1,4 @@ -//@error-pattern: memory leaked +//@error-in-other-file: memory leaked //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" fn main() { diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.rs b/src/tools/miri/tests/fail/memleak_no_backtrace.rs index 24d4a02df71..a1f8d9957ff 100644 --- a/src/tools/miri/tests/fail/memleak_no_backtrace.rs +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-disable-leak-backtraces -//@error-pattern: the evaluated program leaked memory +//@error-in-other-file: the evaluated program leaked memory //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" fn main() { diff --git a/src/tools/miri/tests/fail/memleak_rc.rs b/src/tools/miri/tests/fail/memleak_rc.rs index cf4671912ad..0927612d08e 100644 --- a/src/tools/miri/tests/fail/memleak_rc.rs +++ b/src/tools/miri/tests/fail/memleak_rc.rs @@ -1,4 +1,4 @@ -//@error-pattern: memory leaked +//@error-in-other-file: memory leaked //@stderr-per-bitwidth //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" diff --git a/src/tools/miri/tests/fail/no_main.rs b/src/tools/miri/tests/fail/no_main.rs index e2820504087..01b8c7bd66b 100644 --- a/src/tools/miri/tests/fail/no_main.rs +++ b/src/tools/miri/tests/fail/no_main.rs @@ -1,2 +1,2 @@ -//@error-pattern: miri can only run programs that have a main function +//@error-in-other-file: miri can only run programs that have a main function #![no_main] diff --git a/src/tools/miri/tests/fail/panic/double_panic.rs b/src/tools/miri/tests/fail/panic/double_panic.rs index c9501d90b3b..9378adb8609 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.rs +++ b/src/tools/miri/tests/fail/panic/double_panic.rs @@ -1,4 +1,4 @@ -//@error-pattern: the program aborted +//@error-in-other-file: the program aborted //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1" diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr index 5384f6f6716..77d5fc5d7ce 100644 --- a/src/tools/miri/tests/fail/panic/double_panic.stderr +++ b/src/tools/miri/tests/fail/panic/double_panic.stderr @@ -12,7 +12,8 @@ LL | ABORT(); = note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC note: inside `<Foo as std::ops::Drop>::drop` --> $DIR/double_panic.rs:LL:CC | @@ -24,7 +25,7 @@ note: inside `main` | LL | } | ^ - = 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: 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) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/no_std.stderr b/src/tools/miri/tests/fail/panic/no_std.stderr index 39ad0d268b9..f8307c0c23b 100644 --- a/src/tools/miri/tests/fail/panic/no_std.stderr +++ b/src/tools/miri/tests/fail/panic/no_std.stderr @@ -11,7 +11,7 @@ note: inside `start` | LL | panic!("blarg I am dead") | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = 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: 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) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.rs b/src/tools/miri/tests/fail/panic/panic_abort1.rs index 00a01ce6e81..300bfa32ecb 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort1.rs @@ -1,4 +1,4 @@ -//@error-pattern: the program aborted execution +//@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr index d25dd7be635..d9303fd0d06 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr @@ -11,13 +11,14 @@ LL | ABORT(); = note: inside `std::panicking::rust_panic` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::rt::begin_panic<&str>::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC note: inside `main` --> $DIR/panic_abort1.rs:LL:CC | LL | std::panic!("panicking from libstd"); | ^ - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.rs b/src/tools/miri/tests/fail/panic/panic_abort2.rs index dee0de96703..5d691350577 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort2.rs @@ -1,4 +1,4 @@ -//@error-pattern: the program aborted execution +//@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr index f56d509a697..54cbc9b5f6d 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr @@ -18,7 +18,7 @@ note: inside `main` | LL | std::panic!("{}-panicking from libstd", 42); | ^ - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.rs b/src/tools/miri/tests/fail/panic/panic_abort3.rs index a448aab3ea4..25afc315628 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort3.rs @@ -1,4 +1,4 @@ -//@error-pattern: the program aborted execution +//@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr index 43792f76993..64eea47b14b 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr @@ -18,7 +18,7 @@ note: inside `main` | LL | core::panic!("panicking from libcore"); | ^ - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.rs b/src/tools/miri/tests/fail/panic/panic_abort4.rs index 4995dad9d71..025b51a5cf5 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.rs +++ b/src/tools/miri/tests/fail/panic/panic_abort4.rs @@ -1,4 +1,4 @@ -//@error-pattern: the program aborted execution +//@error-in-other-file: the program aborted execution //@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@compile-flags: -C panic=abort diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr index 89e181bfb27..21beb100645 100644 --- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr +++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr @@ -18,7 +18,7 @@ note: inside `main` | LL | core::panic!("{}-panicking from libcore", 42); | ^ - = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.rs b/src/tools/miri/tests/fail/shims/fs/isolated_file.rs index 9b664ffe52a..2f27e95297b 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.rs +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.rs @@ -1,5 +1,5 @@ //@ignore-target-windows: File handling is not implemented yet -//@error-pattern: `open` not available when isolation is enabled +//@error-in-other-file: `open` not available when isolation is enabled fn main() { let _file = std::fs::File::open("file.txt").unwrap(); diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs index 4036dce5beb..a34df7c7fe3 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.rs @@ -1,4 +1,4 @@ -//@error-pattern: /deallocating while item \[Unique for .*\] is strongly protected/ +//@error-in-other-file: /deallocating while item \[Unique for .*\] is strongly protected/ fn inner(x: &mut i32, f: fn(&mut i32)) { // `f` may mutate, but it may not deallocate! diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs index 8180e2f03a7..9126b7e8575 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs @@ -1,7 +1,7 @@ //! Test that drop_in_place mutably retags the entire place, even for a type that does not need //! dropping, ensuring among other things that it is writeable -//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/ +//@error-in-other-file: /retag .* for Unique permission .* only grants SharedReadOnly permission/ fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs index 670dd4baad8..b2ec23bda02 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs @@ -1,4 +1,4 @@ -//@error-pattern: /deallocation .* tag does not exist in the borrow stack/ +//@error-in-other-file: /deallocation .* tag does not exist in the borrow stack/ use std::alloc::{alloc, dealloc, Layout}; fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs index 70c51e671fe..bf4204c61fd 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs @@ -1,3 +1,5 @@ +#![allow(drop_ref)] + fn main() { let target = &mut 42; let target2 = target as *mut _; diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs index 1e44cc6c800..075efe49412 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-1.rs @@ -1,4 +1,4 @@ -//@error-pattern: pointer to 4 bytes starting at offset 0 is out-of-bounds +//@error-in-other-file: pointer to 4 bytes starting at offset 0 is out-of-bounds fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs index 6e90559a9ef..1b43daa9253 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/issue-miri-1050-2.rs @@ -1,4 +1,4 @@ -//@error-pattern: is a dangling pointer +//@error-in-other-file: is a dangling pointer use std::ptr::NonNull; fn main() { diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs index c19bcb99cc1..1ae6740924c 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_pair_retagging.rs @@ -1,4 +1,4 @@ -//@error-pattern: which is strongly protected +//@error-in-other-file: which is strongly protected struct Newtype<'a>(&'a mut i32, i32); fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs index 2bbe7122ec7..f106274b811 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/newtype_retagging.rs @@ -1,4 +1,4 @@ -//@error-pattern: which is strongly protected +//@error-in-other-file: which is strongly protected struct Newtype<'a>(&'a mut i32); fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { diff --git a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs index 77daa9c9811..fd51fa6468a 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/zst_slice.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-strict-provenance -//@error-pattern: /retag .* tag does not exist in the borrow stack/ +//@error-in-other-file: /retag .* tag does not exist in the borrow stack/ fn main() { unsafe { diff --git a/src/tools/miri/tests/fail/tokio/sleep.rs b/src/tools/miri/tests/fail/tokio/sleep.rs index 6fdfbc9913a..d96d778e6ca 100644 --- a/src/tools/miri/tests/fail/tokio/sleep.rs +++ b/src/tools/miri/tests/fail/tokio/sleep.rs @@ -1,6 +1,6 @@ //@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full //@only-target-x86_64-unknown-linux: support for tokio only on linux and x86 -//@error-pattern: returning ready events from epoll_wait is not yet implemented +//@error-in-other-file: returning ready events from epoll_wait is not yet implemented //@normalize-stderr-test: " += note:.*\n" -> "" use tokio::time::{sleep, Duration, Instant}; diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs index a68efea890c..484c7c3bbff 100644 --- a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs +++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-tree-borrows -//@error-pattern: /deallocation through .* is forbidden/ +//@error-in-other-file: /deallocation through .* is forbidden/ fn inner(x: &mut i32, f: fn(&mut i32)) { // `f` may mutate, but it may not deallocate! diff --git a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr index 97088d5854c..071b216ff98 100644 --- a/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr +++ b/src/tools/miri/tests/fail/tree-borrows/strongly-protected.stderr @@ -17,6 +17,12 @@ help: the strongly protected tag <TAG> was created here, in the initial state Re | LL | fn inner(x: &mut i32, f: fn(&mut i32)) { | ^ +help: the strongly protected tag <TAG> then transitioned from Reserved to Active due to a child write access at offsets [0x0..0x4] + --> $DIR/strongly-protected.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(raw) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: this corresponds to an activation = note: BACKTRACE (of the first span): = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs index 8a40e527f0e..d8cab68ac5d 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -13,7 +13,7 @@ struct PartialDrop { b: u8, } -//@error-pattern: /alignment 2 is required/ +//@error-in-other-file: /alignment 2 is required/ fn main() { unsafe { // Create an unaligned pointer diff --git a/src/tools/miri/tests/fail/uninit_buffer.rs b/src/tools/miri/tests/fail/uninit_buffer.rs index d21371225e5..8a330058375 100644 --- a/src/tools/miri/tests/fail/uninit_buffer.rs +++ b/src/tools/miri/tests/fail/uninit_buffer.rs @@ -1,4 +1,6 @@ -//@error-pattern: memory is uninitialized at [0x4..0x10] +//@error-in-other-file: memory is uninitialized at [0x4..0x10] + +#![allow(drop_copy)] use std::alloc::{alloc, dealloc, Layout}; use std::slice::from_raw_parts; 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 170bc6e1ed1..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,6 +1,7 @@ -//@error-pattern: memory is uninitialized at [0x4..0x8] +//@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/panic/panic1.stderr b/src/tools/miri/tests/panic/panic1.stderr index 15834d58bc6..0f4535e6792 100644 --- a/src/tools/miri/tests/panic/panic1.stderr +++ b/src/tools/miri/tests/panic/panic1.stderr @@ -1,9 +1,11 @@ thread 'main' panicked at 'panicking from libstd', $DIR/panic1.rs:LL:CC stack backtrace: - 0: std::rt::begin_panic + 0: std::panicking::begin_panic_handler at RUSTLIB/std/src/panicking.rs:LL:CC - 1: main + 1: std::rt::panic_fmt + at RUSTLIB/core/src/panicking.rs:LL:CC + 2: main at $DIR/panic1.rs:LL:CC - 2: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn()) + 3: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn()) at RUSTLIB/core/src/ops/function.rs:LL:CC note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs index 82ef59427ae..68504cb1c79 100644 --- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs +++ b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs @@ -101,7 +101,6 @@ fn test_posix_realpath_errors() { #[cfg(target_os = "linux")] fn test_posix_fadvise() { - use std::convert::TryInto; use std::io::Write; let path = tmp().join("miri_test_libc_posix_fadvise.txt"); diff --git a/src/tools/miri/tests/pass/0weak_memory_consistency.rs b/src/tools/miri/tests/pass/0weak_memory_consistency.rs index 3a531eede67..abfe3b0adeb 100644 --- a/src/tools/miri/tests/pass/0weak_memory_consistency.rs +++ b/src/tools/miri/tests/pass/0weak_memory_consistency.rs @@ -116,11 +116,13 @@ fn test_message_passing() { #[rustfmt::skip] let j1 = spawn(move || { + let x = x; // avoid field capturing unsafe { *x.0 = 1 }; // -----------------------------------------+ y.store(1, Release); // ---------------------+ | }); // | | #[rustfmt::skip] // |synchronizes-with | happens-before let j2 = spawn(move || { // | | + let x = x; // avoid field capturing | | acquires_value(&y, 1); // <------------------+ | unsafe { *x.0 } // <---------------------------------------------+ }); diff --git a/src/tools/miri/tests/pass/concurrency/data_race.rs b/src/tools/miri/tests/pass/concurrency/data_race.rs index 4e3c99058a0..d31420380a5 100644 --- a/src/tools/miri/tests/pass/concurrency/data_race.rs +++ b/src/tools/miri/tests/pass/concurrency/data_race.rs @@ -17,12 +17,14 @@ fn test_fence_sync() { let evil_ptr = EvilSend(ptr); let j1 = spawn(move || { + let evil_ptr = evil_ptr; // avoid field capturing unsafe { *evil_ptr.0 = 1 }; fence(Ordering::Release); SYNC.store(1, Ordering::Relaxed) }); let j2 = spawn(move || { + let evil_ptr = evil_ptr; // avoid field capturing if SYNC.load(Ordering::Relaxed) == 1 { fence(Ordering::Acquire); unsafe { *evil_ptr.0 } @@ -40,10 +42,10 @@ fn test_multiple_reads() { let ptr = &mut var as *mut u32; let evil_ptr = EvilSend(ptr); - let j1 = spawn(move || unsafe { *evil_ptr.0 }); - let j2 = spawn(move || unsafe { *evil_ptr.0 }); - let j3 = spawn(move || unsafe { *evil_ptr.0 }); - let j4 = spawn(move || unsafe { *evil_ptr.0 }); + let j1 = spawn(move || unsafe { *{ evil_ptr }.0 }); + let j2 = spawn(move || unsafe { *{ evil_ptr }.0 }); + let j3 = spawn(move || unsafe { *{ evil_ptr }.0 }); + let j4 = spawn(move || unsafe { *{ evil_ptr }.0 }); assert_eq!(j1.join().unwrap(), 42); assert_eq!(j2.join().unwrap(), 42); @@ -63,6 +65,7 @@ pub fn test_rmw_no_block() { unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 1; SYNC.store(1, Ordering::Release); }); @@ -73,7 +76,10 @@ pub fn test_rmw_no_block() { } }); - let j3 = spawn(move || if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 }); + let j3 = spawn(move || { + let c = c; // avoid field capturing + if SYNC.load(Ordering::Acquire) == 2 { *c.0 } else { 0 } + }); j1.join().unwrap(); j2.join().unwrap(); @@ -91,11 +97,15 @@ pub fn test_simple_release() { unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 1; SYNC.store(1, Ordering::Release); }); - let j2 = spawn(move || if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 }); + let j2 = spawn(move || { + let c = c; // avoid field capturing + if SYNC.load(Ordering::Acquire) == 1 { *c.0 } else { 0 } + }); j1.join().unwrap(); assert_eq!(j2.join().unwrap(), 1); // relies on thread 2 going last diff --git a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs index d71e51b0384..049b5e7f498 100644 --- a/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs +++ b/src/tools/miri/tests/pass/concurrency/disable_data_race_detector.rs @@ -14,10 +14,12 @@ pub fn main() { let c = EvilSend(b); unsafe { let j1 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 32; }); let j2 = spawn(move || { + let c = c; // avoid field capturing *c.0 = 64; // Data race (but not detected as the detector is disabled) }); diff --git a/src/tools/miri/tests/pass/concurrency/sync.rs b/src/tools/miri/tests/pass/concurrency/sync.rs index 3bd1e542407..dccc9d104dd 100644 --- a/src/tools/miri/tests/pass/concurrency/sync.rs +++ b/src/tools/miri/tests/pass/concurrency/sync.rs @@ -201,8 +201,10 @@ fn park_timeout() { thread::park_timeout(Duration::from_millis(200)); // Normally, waiting in park/park_timeout may spuriously wake up early, but we // know Miri's timed synchronization primitives do not do that. - - assert!((200..1000).contains(&start.elapsed().as_millis())); + // We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed + // and sometimes just pause for 1 second or more. + let elapsed = start.elapsed(); + assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}"); } fn park_unpark() { @@ -219,8 +221,10 @@ fn park_unpark() { thread::park(); // Normally, waiting in park/park_timeout may spuriously wake up early, but we // know Miri's timed synchronization primitives do not do that. - - assert!((200..1000).contains(&start.elapsed().as_millis())); + // We allow much longer sleeps as well since the macOS GHA runners seem very oversubscribed + // and sometimes just pause for 1 second or more. + let elapsed = start.elapsed(); + assert!((200..2000).contains(&elapsed.as_millis()), "bad sleep time: {elapsed:?}"); t2.join().unwrap(); } diff --git a/src/tools/miri/tests/pass/concurrency/thread_locals.rs b/src/tools/miri/tests/pass/concurrency/thread_locals.rs index 13c11b55775..fc4c8a283dd 100644 --- a/src/tools/miri/tests/pass/concurrency/thread_locals.rs +++ b/src/tools/miri/tests/pass/concurrency/thread_locals.rs @@ -42,6 +42,7 @@ fn main() { }; thread::spawn(move || unsafe { + let ptr = ptr; // avoid field capturing assert_eq!(*ptr.0, 5); assert_eq!(A, 0); assert_eq!(B, 0); diff --git a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs index d89320bfe59..3b27af9094c 100644 --- a/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs +++ b/src/tools/miri/tests/pass/concurrency/windows_condvar_shared.rs @@ -44,6 +44,8 @@ fn all_shared() { // waiters for i in 0..5 { handles.push(thread::spawn(move || { + let condvar_ptr = condvar_ptr; // avoid field capture + let lock_ptr = lock_ptr; // avoid field capture unsafe { AcquireSRWLockShared(lock_ptr.0); } @@ -71,6 +73,7 @@ fn all_shared() { // readers for i in 0..5 { handles.push(thread::spawn(move || { + let lock_ptr = lock_ptr; // avoid field capture unsafe { AcquireSRWLockShared(lock_ptr.0); } @@ -111,6 +114,8 @@ fn shared_sleep_and_exclusive_lock() { let mut waiters = Vec::with_capacity(5); for i in 0..5 { waiters.push(thread::spawn(move || { + let lock_ptr = lock_ptr; // avoid field capture + let condvar_ptr = condvar_ptr; // avoid field capture unsafe { AcquireSRWLockShared(lock_ptr.0); } @@ -170,6 +175,8 @@ fn exclusive_sleep_and_shared_lock() { let mut handles = Vec::with_capacity(10); for i in 0..5 { handles.push(thread::spawn(move || { + let lock_ptr = lock_ptr; // avoid field capture + let condvar_ptr = condvar_ptr; // avoid field capture unsafe { AcquireSRWLockExclusive(lock_ptr.0); } @@ -193,6 +200,7 @@ fn exclusive_sleep_and_shared_lock() { for i in 0..5 { handles.push(thread::spawn(move || { + let lock_ptr = lock_ptr; // avoid field capture unsafe { AcquireSRWLockShared(lock_ptr.0); } diff --git a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs index 4eb88379620..b2412f7dbb0 100644 --- a/src/tools/miri/tests/pass/concurrency/windows_init_once.rs +++ b/src/tools/miri/tests/pass/concurrency/windows_init_once.rs @@ -66,6 +66,7 @@ fn block_until_complete() { let init_once_ptr = SendPtr(&mut init_once); let waiter = move || unsafe { + let init_once_ptr = init_once_ptr; // avoid field capture let mut pending = 0; assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE); @@ -102,6 +103,7 @@ fn retry_on_fail() { let init_once_ptr = SendPtr(&mut init_once); let waiter = move || unsafe { + let init_once_ptr = init_once_ptr; // avoid field capture let mut pending = 0; assert_eq!(InitOnceBeginInitialize(init_once_ptr.0, 0, &mut pending, null_mut()), TRUE); @@ -146,6 +148,8 @@ fn no_data_race_after_complete() { let place_ptr = SendPtr(&mut place); let reader = thread::spawn(move || unsafe { + let init_once_ptr = init_once_ptr; // avoid field capture + let place_ptr = place_ptr; // avoid field capture let mut pending = 0; // this doesn't block because reader only executes after `InitOnceComplete` is called diff --git a/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs b/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs index 986e2b8cc10..5da5497f982 100644 --- a/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs +++ b/src/tools/miri/tests/pass/concurrency/windows_join_multiple.rs @@ -22,10 +22,8 @@ fn main() { }) .into_raw_handle() as usize; - let waiter = move || { - unsafe { - assert_eq!(WaitForSingleObject(blocker, INFINITE), 0); - } + let waiter = move || unsafe { + assert_eq!(WaitForSingleObject(blocker, INFINITE), 0); }; let waiter1 = thread::spawn(waiter); diff --git a/src/tools/miri/tests/pass/panic/catch_panic.rs b/src/tools/miri/tests/pass/panic/catch_panic.rs index 5d57df4e52b..1b00f7cea30 100644 --- a/src/tools/miri/tests/pass/panic/catch_panic.rs +++ b/src/tools/miri/tests/pass/panic/catch_panic.rs @@ -49,13 +49,12 @@ fn main() { // Std panics test(None, |_old_val| std::panic!("Hello from panic: std")); - test(None, |old_val| std::panic!(format!("Hello from panic: {:?}", old_val))); + test(None, |old_val| std::panic::panic_any(format!("Hello from panic: {:?}", old_val))); test(None, |old_val| std::panic!("Hello from panic: {:?}", old_val)); - test(None, |_old_val| std::panic!(1337)); + test(None, |_old_val| std::panic::panic_any(1337)); // Core panics test(None, |_old_val| core::panic!("Hello from panic: core")); - test(None, |old_val| core::panic!(&format!("Hello from panic: {:?}", old_val))); test(None, |old_val| core::panic!("Hello from panic: {:?}", old_val)); // Built-in panics; also make sure the message is right. diff --git a/src/tools/miri/tests/pass/panic/catch_panic.stderr b/src/tools/miri/tests/pass/panic/catch_panic.stderr index 0ced5588cc1..f43434582a2 100644 --- a/src/tools/miri/tests/pass/panic/catch_panic.stderr +++ b/src/tools/miri/tests/pass/panic/catch_panic.stderr @@ -11,8 +11,6 @@ thread 'main' panicked at 'Hello from panic: core', $DIR/catch_panic.rs:LL:CC Caught panic message (&str): Hello from panic: core thread 'main' panicked at 'Hello from panic: 5', $DIR/catch_panic.rs:LL:CC Caught panic message (String): Hello from panic: 5 -thread 'main' panicked at 'Hello from panic: 6', $DIR/catch_panic.rs:LL:CC -Caught panic message (String): Hello from panic: 6 thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4', $DIR/catch_panic.rs:LL:CC Caught panic message (String): index out of bounds: the len is 3 but the index is 4 thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:LL:CC diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.rs b/src/tools/miri/tests/pass/panic/concurrent-panic.rs index 776bc2057f3..7cc1e2a973f 100644 --- a/src/tools/miri/tests/pass/panic/concurrent-panic.rs +++ b/src/tools/miri/tests/pass/panic/concurrent-panic.rs @@ -57,7 +57,7 @@ fn main() { let t2_started_pair = t2_started_pair.clone(); let block_on_drop = BlockOnDrop::new(t1); spawn(move || { - let _ = block_on_drop; + let _capture = block_on_drop; let (mutex, condvar) = &*t2_started_pair; *mutex.lock().unwrap() = true; 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/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs index ce3c8b7d5f1..9f743f0b566 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs @@ -1,5 +1,8 @@ //@compile-flags: -Zmiri-retag-fields // Checks that the test does not run forever (which relies on a fast path). + +#![allow(drop_copy)] + fn main() { let array = [(); usize::MAX]; drop(array); // Pass the array to a function, retagging its fields diff --git a/src/tools/miri/tests/pass/sysroot.rs b/src/tools/miri/tests/pass/sysroot.rs new file mode 100644 index 00000000000..2c80e5bbd84 --- /dev/null +++ b/src/tools/miri/tests/pass/sysroot.rs @@ -0,0 +1,9 @@ +//! Just check that some things are available in the sysroot. +#![feature(test)] +#![allow(unused)] + +extern crate proc_macro; +extern crate std; +extern crate test; + +fn main() {} diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index 692d5e3fcef..b26480f668b 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -143,7 +143,7 @@ async function runTests(opts, framework_options, files, results, status_bar, sho const tests_queue = []; for (const testPath of files) { - const callback = runTest(testPath, framework_options) + const callback = runTest(testPath, {"options": framework_options}) .then(out => { const [output, nb_failures] = out; results[nb_failures === 0 ? "successful" : "failed"].push({ @@ -323,6 +323,7 @@ async function main(argv) { if (results.failed.length > 0 || results.errored.length > 0) { process.exit(1); } + process.exit(0); } main(process.argv); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index baef4bb0140..e1004c796c5 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -6,47 +6,53 @@ use std::path::Path; /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. +#[rustfmt::skip] const LICENSES: &[&str] = &[ - "MIT/Apache-2.0", - "MIT / Apache-2.0", - "Apache-2.0/MIT", + // tidy-alphabetical-start + "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident + "0BSD OR MIT OR Apache-2.0", // adler license + "0BSD", "Apache-2.0 / MIT", - "MIT OR Apache-2.0", "Apache-2.0 OR MIT", "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license - "MIT", + "Apache-2.0/MIT", "ISC", - "Unlicense/MIT", + "MIT / Apache-2.0", + "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros + "MIT OR Apache-2.0", + "MIT OR Zlib OR Apache-2.0", // miniz_oxide + "MIT", + "MIT/Apache-2.0", + "Unicode-DFS-2016", // tinystr and icu4x "Unlicense OR MIT", - "0BSD", - "0BSD OR MIT OR Apache-2.0", // adler license - "Zlib OR Apache-2.0 OR MIT", // tinyvec - "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros - "MIT OR Zlib OR Apache-2.0", // miniz_oxide - "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident - "Unicode-DFS-2016", // tinystr and icu4x + "Unlicense/MIT", + "Zlib OR Apache-2.0 OR MIT", // tinyvec + // tidy-alphabetical-end ]; /// These are exceptions to Rust's permissive licensing policy, and /// should be considered bugs. Exceptions are only allowed in Rust /// tooling. It is _crucial_ that no exception crates be dependencies /// of the Rust runtime (std/test). +#[rustfmt::skip] const EXCEPTIONS: &[(&str, &str)] = &[ + // tidy-alphabetical-start ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc - ("mdbook", "MPL-2.0"), // mdbook + ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku ("colored", "MPL-2.0"), // rustfmt + ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) + ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) + ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above. + ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot + ("mdbook", "MPL-2.0"), // mdbook ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde) - ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku - ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot - ("snap", "BSD-3-Clause"), // rustc - ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) - ("self_cell", "Apache-2.0"), // rustc (fluent translations) - // FIXME: this dependency violates the documentation comment above: - ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target - ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) + ("self_cell", "Apache-2.0"), // rustc (fluent translations) + ("snap", "BSD-3-Clause"), // rustc + // tidy-alphabetical-end ]; const EXCEPTIONS_CARGO: &[(&str, &str)] = &[ + // tidy-alphabetical-start ("bitmaps", "MPL-2.0+"), ("bytesize", "Apache-2.0"), ("dunce", "CC0-1.0 OR MIT-0"), @@ -62,9 +68,11 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[ ("sized-chunks", "MPL-2.0+"), ("subtle", "BSD-3-Clause"), ("unicode-bom", "Apache-2.0"), + // tidy-alphabetical-end ]; const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ + // tidy-alphabetical-start ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), ("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"), ("cranelift-codegen-meta", "Apache-2.0 WITH LLVM-exception"), @@ -80,6 +88,7 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ ("regalloc2", "Apache-2.0 WITH LLVM-exception"), ("target-lexicon", "Apache-2.0 WITH LLVM-exception"), ("wasmtime-jit-icache-coherence", "Apache-2.0 WITH LLVM-exception"), + // tidy-alphabetical-end ]; const EXCEPTIONS_BOOTSTRAP: &[(&str, &str)] = &[ @@ -95,6 +104,7 @@ const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", /// This list is here to provide a speed-bump to adding a new dependency to /// rustc. Please check with the compiler team before adding an entry. const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ + // tidy-alphabetical-start "addr2line", "adler", "ahash", @@ -113,8 +123,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "chalk-engine", "chalk-ir", "chalk-solve", - "convert_case", // dependency of derive_more "compiler_builtins", + "convert_case", // dependency of derive_more "cpufeatures", "crc32fast", "crossbeam-channel", @@ -135,6 +145,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "expect-test", "fallible-iterator", // dependency of `thorin` "fastrand", + "field-offset", "fixedbitset", "flate2", "fluent-bundle", @@ -187,8 +198,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "ppv-lite86", "proc-macro-hack", "proc-macro2", - "pulldown-cmark", "psm", + "pulldown-cmark", "punycode", "quote", "rand", @@ -227,6 +238,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "tempfile", "termcolor", "termize", + "thin-vec", "thiserror", "thiserror-impl", "thorin-dwp", @@ -234,7 +246,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "tinystr", "tinyvec", "tinyvec_macros", - "thin-vec", "tracing", "tracing-attributes", "tracing-core", @@ -263,29 +274,37 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "valuable", "version_check", "wasi", - "windows", "winapi", "winapi-i686-pc-windows-gnu", "winapi-util", "winapi-x86_64-pc-windows-gnu", + "windows", + "windows-targets", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", "writeable", - // this is a false-positive: it's only used by rustfmt, but because it's enabled through a - // feature, tidy thinks it's used by rustc as well. - "yansi-term", + "yansi-term", // this is a false-positive: it's only used by rustfmt, but because it's enabled through a feature, tidy thinks it's used by rustc as well. "yoke", "yoke-derive", "zerofrom", "zerofrom-derive", "zerovec", "zerovec-derive", + // tidy-alphabetical-end ]; const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ + // tidy-alphabetical-start "ahash", "anyhow", "autocfg", - "bumpalo", "bitflags", + "bumpalo", "byteorder", "cfg-if", "cranelift-bforest", @@ -324,6 +343,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", "windows-sys", + // tidy-alphabetical-end ]; /// Dependency checks. 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 e4f328ec0dd..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 = 1953; -const ROOT_ENTRY_LIMIT: usize = 895; +const ISSUES_ENTRY_LIMIT: usize = 1920; +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/fewer-names.rs b/tests/codegen/fewer-names.rs index 7f383a5c149..a09c795924c 100644 --- a/tests/codegen/fewer-names.rs +++ b/tests/codegen/fewer-names.rs @@ -7,14 +7,14 @@ #[no_mangle] pub fn sum(x: u32, y: u32) -> u32 { -// YES-LABEL: define{{.*}}i32 @sum(i32 noundef %0, i32 noundef %1) -// YES-NEXT: %3 = add i32 %1, %0 -// YES-NEXT: ret i32 %3 + // YES-LABEL: define{{.*}}i32 @sum(i32 noundef %0, i32 noundef %1) + // YES-NEXT: %3 = add i32 %1, %0 + // YES-NEXT: ret i32 %3 -// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y) -// NO-NEXT: start: -// NO-NEXT: %0 = add i32 %y, %x -// NO-NEXT: ret i32 %0 + // NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y) + // NO-NEXT: start: + // NO-NEXT: %0 = add i32 %y, %x + // NO-NEXT: ret i32 %0 let z = x + y; z } 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/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs index 81e56b5490d..c6b920cf599 100644 --- a/tests/codegen/mem-replace-big-type.rs +++ b/tests/codegen/mem-replace-big-type.rs @@ -13,7 +13,7 @@ pub struct Big([u64; 7]); pub fn replace_big(dst: &mut Big, src: Big) -> Big { // Back in 1.68, this emitted six `memcpy`s. // `read_via_copy` in 1.69 got that down to three. - // `write_via_move` has it down to just the two essential ones. + // `write_via_move` and nvro get this down to the essential two. std::mem::replace(dst, src) } @@ -22,13 +22,12 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big { // CHECK-NOT: call void @llvm.memcpy -// For a large type, we expect exactly two `memcpy`s +// For a large type, we expect exactly three `memcpy`s // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) - // CHECK-NOT: alloca - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) - // CHECK-NOT: call void @llvm.memcpy - // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false) - // CHECK-NOT: call void @llvm.memcpy +// CHECK-NOT: call void @llvm.memcpy +// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) +// CHECK-NOT: call void @llvm.memcpy +// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false) +// CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/nrvo.rs b/tests/codegen/nrvo.rs index fddb0d1fb3c..b2ae99f3761 100644 --- a/tests/codegen/nrvo.rs +++ b/tests/codegen/nrvo.rs @@ -8,7 +8,7 @@ pub fn nrvo(init: fn(&mut [u8; 4096])) -> [u8; 4096] { // CHECK-LABEL: nrvo // CHECK: @llvm.memset - // CHECK-NOT: @llvm.memcpy + // FIXME: turn on nrvo then check-not: @llvm.memcpy // CHECK: ret // CHECK-EMPTY let mut buf = [0; 4096]; diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs new file mode 100644 index 00000000000..ab5dcec7936 --- /dev/null +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-trait-objects.rs @@ -0,0 +1,44 @@ +// Verifies that type metadata identifiers for trait objects are emitted correctly. +// +// needs-sanitizer-cfi +// compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![crate_type="lib"] + +trait Trait1 { + fn foo(&self); +} + +struct Type1; + +impl Trait1 for Type1 { + fn foo(&self) { + } +} + +pub fn foo() { + let a = Type1; + a.foo(); + // CHECK-LABEL: define{{.*}}foo{{.*}}!type !{{[0-9]+}} + // CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo +} + +pub fn bar() { + let a = Type1; + let b = &a as &dyn Trait1; + b.foo(); + // CHECK-LABEL: define{{.*}}bar{{.*}}!type !{{[0-9]+}} + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]") +} + +pub fn baz() { + let a = Type1; + let b = &a as &dyn Trait1; + a.foo(); + b.foo(); + // CHECK-LABEL: define{{.*}}baz{{.*}}!type !{{[0-9]+}} + // CHECK: call <sanitizer_cfi_emit_type_metadata_trait_objects::Type1 as sanitizer_cfi_emit_type_metadata_trait_objects::Trait1>::foo + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0|%1}}, metadata !"[[TYPE1:[[:print:]]+]]") +} + +// CHECK: !{{[0-9]+}} = !{i64 0, !"[[TYPE1]]"} diff --git a/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs new file mode 100644 index 00000000000..81e0d9344f7 --- /dev/null +++ b/tests/codegen/sanitizer-kcfi-emit-type-metadata-trait-objects.rs @@ -0,0 +1,69 @@ +// Verifies that type metadata identifiers for trait objects are emitted correctly. +// +// revisions: aarch64 x86_64 +// [aarch64] compile-flags: --target aarch64-unknown-none +// [aarch64] needs-llvm-components: aarch64 +// [x86_64] compile-flags: --target x86_64-unknown-none +// [x86_64] needs-llvm-components: +// compile-flags: -Cno-prepopulate-passes -Zsanitizer=kcfi -Copt-level=0 + +#![crate_type="lib"] +#![feature(arbitrary_self_types, no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="copy"] +trait Copy { } +#[lang="receiver"] +trait Receiver { } +#[lang="dispatch_from_dyn"] +trait DispatchFromDyn<T> { } +impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +#[lang = "unsize"] +trait Unsize<T: ?Sized> { } +#[lang = "coerce_unsized"] +pub trait CoerceUnsized<T: ?Sized> { } +impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +#[lang="freeze"] +trait Freeze { } +#[lang="drop_in_place"] +fn drop_in_place_fn<T>() { } + +trait Trait1 { + fn foo(&self); +} + +struct Type1; + +impl Trait1 for Type1 { + fn foo(&self) { + } +} + +pub fn foo() { + let a = Type1; + a.foo(); + // CHECK-LABEL: define{{.*}}foo{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo +} + +pub fn bar() { + let a = Type1; + let b = &a as &dyn Trait1; + b.foo(); + // CHECK-LABEL: define{{.*}}bar{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] +} + +pub fn baz() { + let a = Type1; + let b = &a as &dyn Trait1; + a.foo(); + b.foo(); + // CHECK-LABEL: define{{.*}}baz{{.*}}!{{<unknown kind #36>|kcfi_type}} !{{[0-9]+}} + // CHECK: call <sanitizer_kcfi_emit_type_metadata_trait_objects::Type1 as sanitizer_kcfi_emit_type_metadata_trait_objects::Trait1>::foo + // CHECK: call void %0({{\{\}\*|ptr}} align 1 {{%b\.0|%_1}}){{.*}}[ "kcfi"(i32 [[TYPE1:[[:print:]]+]]) ] +} + +// CHECK: !{{[0-9]+}} = !{i32 [[TYPE1]]} diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs new file mode 100644 index 00000000000..997bdaf5636 --- /dev/null +++ b/tests/codegen/slice-iter-nonnull.rs @@ -0,0 +1,77 @@ +// no-system-llvm +// compile-flags: -O +// ignore-debug (these add extra checks that make it hard to verify) +#![crate_type = "lib"] + +// The slice iterator used to `assume` that the `start` pointer was non-null. +// That ought to be unneeded, though, since the type is `NonNull`, so this test +// confirms that the appropriate metadata is included to denote that. + +// CHECK-LABEL: @slice_iter_next( +#[no_mangle] +pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { + // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: icmp eq ptr %[[START]], %[[END]] + + // CHECK: store ptr{{.+}}, ptr %it, + + it.next() +} + +// CHECK-LABEL: @slice_iter_next_back( +#[no_mangle] +pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { + // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef + // CHECK: icmp eq ptr %[[START]], %[[END]] + + // CHECK: store ptr{{.+}}, ptr %[[ENDP]], + + it.next_back() +} + +// The slice iterator `new` methods used to `assume` that the pointer is non-null, +// but passing slices already requires that, to the extent that LLVM actually +// removed the `call @llvm.assume` anyway. These tests just demonstrate that the +// attribute is there, and confirms adding the assume back doesn't do anything. + +// CHECK-LABEL: @slice_iter_new +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +#[no_mangle] +pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { + // CHECK-NOT: slice + // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %slice.0, 0 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK-NOT: slice + // CHECK: } + slice.iter() +} + +// CHECK-LABEL: @slice_iter_mut_new +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +#[no_mangle] +pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { + // CHECK-NOT: slice + // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %slice.0, 0 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK-NOT: slice + // CHECK: } + slice.iter_mut() +} diff --git a/tests/codegen/vec-shrink-panik.rs b/tests/codegen/vec-shrink-panik.rs index b3c3483fea9..88b7edff260 100644 --- a/tests/codegen/vec-shrink-panik.rs +++ b/tests/codegen/vec-shrink-panik.rs @@ -25,7 +25,7 @@ pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> { // Call to panic_cannot_unwind in case of double-panic is expected // on LLVM 16 and older, but other panics are not. - // CHECK: cleanup + // old: filter // old-NEXT: ; call core::panicking::panic_cannot_unwind // old-NEXT: panic_cannot_unwind @@ -40,7 +40,7 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> { // Call to panic_cannot_unwind in case of double-panic is expected, // on LLVM 16 and older, but other panics are not. - // CHECK: cleanup + // old: filter // old-NEXT: ; call core::panicking::panic_cannot_unwind // old-NEXT: panic_cannot_unwind 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/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff index c5907e7cf18..15117ea890e 100644 --- a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff +++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff @@ -4,59 +4,29 @@ fn adt_transmutes() -> () { let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32 let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 - let mut _2: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - let mut _4: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+2:28: +2:41 - let mut _6: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+3:31: +3:47 - let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47 - let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52 - let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52 - let mut _14: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58 - let mut _16: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54 - let mut _18: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54 - let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47 - let mut _22: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+11:29: +11:47 - let mut _24: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+12:46: +12:77 + let mut _2: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + let mut _4: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+2:29: +2:54 + let mut _6: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+3:29: +3:54 + let mut _8: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+4:29: +4:47 + let mut _10: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+5:29: +5:47 + let mut _12: std::mem::MaybeUninit<std::string::String>; // in scope 0 at $DIR/combine_transmutes.rs:+6:46: +6:77 scope 1 { debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11 - let _3: i8; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 + let _3: i16; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 scope 2 { debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11 - let _5: usize; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 + let _5: u16; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 scope 3 { debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11 - let _7: isize; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 + let _7: u32; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 scope 4 { debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11 - let _9: u8; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 + let _9: i32; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 scope 5 { debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11 - let _11: i8; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 + let _11: std::mem::ManuallyDrop<std::string::String>; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 scope 6 { debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11 - let _13: u8; // in scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 - scope 7 { - debug _a => _13; // in scope 7 at $DIR/combine_transmutes.rs:+7:9: +7:11 - let _15: i16; // in scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 - scope 8 { - debug _a => _15; // in scope 8 at $DIR/combine_transmutes.rs:+8:9: +8:11 - let _17: u16; // in scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 - scope 9 { - debug _a => _17; // in scope 9 at $DIR/combine_transmutes.rs:+9:9: +9:11 - let _19: u32; // in scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 - scope 10 { - debug _a => _19; // in scope 10 at $DIR/combine_transmutes.rs:+10:9: +10:11 - let _21: i32; // in scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 - scope 11 { - debug _a => _21; // in scope 11 at $DIR/combine_transmutes.rs:+11:9: +11:11 - let _23: std::mem::ManuallyDrop<std::string::String>; // in scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 - scope 12 { - debug _a => _23; // in scope 12 at $DIR/combine_transmutes.rs:+12:9: +12:11 - } - } - } - } - } - } } } } @@ -66,93 +36,55 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 - StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - _2 = EnumNoRepr::A; // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:42 - StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:41: +1:42 + StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + _2 = Option::<NonZeroU8>::Some(const _); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + // mir::Constant + // + span: $DIR/combine_transmutes.rs:35:33: 35:57 + // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } + _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:59 + StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:58: +1:59 StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 - StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 - _4 = EnumNoRepr::B; // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 - _3 = move _4 as i8 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:18: +2:42 - StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:41: +2:42 + StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54 + _4 = Wrapping::<i16>(const 0_i16); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54 +- _3 = move _4 as i16 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55 ++ _3 = move (_4.0: i16); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55 + StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:54: +2:55 StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 - StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 - _6 = EnumReprIsize::A; // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 - _5 = move _6 as usize (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:21: +3:48 - StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:47: +3:48 + StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54 + _6 = Wrapping::<i16>(const 0_i16); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54 + _5 = move _6 as u16 (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:19: +3:55 + StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:54: +3:55 StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 - StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 - _8 = EnumReprIsize::B; // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 -- _7 = move _8 as isize (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 -+ _7 = discriminant(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 + StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47 + _8 = Union32 { u32: const 0_i32 }; // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47 + _7 = move _8 as u32 (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:19: +4:48 StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48 StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 - StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 - _10 = Less; // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 - _9 = move _10 as u8 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:18: +5:53 - StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:52: +5:53 + StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47 + _10 = Union32 { u32: const 0_u32 }; // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47 + _9 = move _10 as i32 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:19: +5:48 + StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:47: +5:48 StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 - StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 - _12 = Less; // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 -- _11 = move _12 as i8 (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 -+ _11 = discriminant(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 - StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53 - StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 - StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 - _14 = Option::<NonZeroU8>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 - // mir::Constant - // + span: $DIR/combine_transmutes.rs:41:33: 41:57 - // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } - _13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59 - StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59 - StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 - StorageLive(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 - _16 = Wrapping::<i16>(const 0_i16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 -- _15 = move _16 as i16 (Transmute); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 -+ _15 = move (_16.0: i16); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 - StorageDead(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:54: +8:55 - StorageLive(_17); // scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 - StorageLive(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 - _18 = Wrapping::<i16>(const 0_i16); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 - _17 = move _18 as u16 (Transmute); // scope 8 at $DIR/combine_transmutes.rs:+9:19: +9:55 - StorageDead(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:54: +9:55 - StorageLive(_19); // scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 - StorageLive(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 - _20 = Union32 { u32: const 0_i32 }; // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 - _19 = move _20 as u32 (Transmute); // scope 9 at $DIR/combine_transmutes.rs:+10:19: +10:48 - StorageDead(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:47: +10:48 - StorageLive(_21); // scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 - StorageLive(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 - _22 = Union32 { u32: const 0_u32 }; // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 - _21 = move _22 as i32 (Transmute); // scope 10 at $DIR/combine_transmutes.rs:+11:19: +11:48 - StorageDead(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:47: +11:48 - StorageLive(_23); // scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 - StorageLive(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 - _24 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 + StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77 + _12 = MaybeUninit::<String>::uninit() -> [return: bb1, unwind unreachable]; // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77 // mir::Constant - // + span: $DIR/combine_transmutes.rs:46:46: 46:75 - // + user_ty: UserType(23) + // + span: $DIR/combine_transmutes.rs:40:46: 40:75 + // + user_ty: UserType(11) // + literal: Const { ty: fn() -> MaybeUninit<String> {MaybeUninit::<String>::uninit}, val: Value(<ZST>) } } bb1: { -- _23 = move _24 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 -+ _23 = move (_24.1: std::mem::ManuallyDrop<std::string::String>); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 - StorageDead(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:77: +12:78 - _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +13:2 - StorageDead(_23); // scope 11 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_21); // scope 10 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_19); // scope 9 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_17); // scope 8 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_15); // scope 7 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_13); // scope 6 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+13:1: +13:2 - return; // scope 0 at $DIR/combine_transmutes.rs:+13:2: +13:2 +- _11 = move _12 as std::mem::ManuallyDrop<std::string::String> (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78 ++ _11 = move (_12.1: std::mem::ManuallyDrop<std::string::String>); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78 + StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:77: +6:78 + _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +7:2 + StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+7:1: +7:2 + return; // scope 0 at $DIR/combine_transmutes.rs:+7:2: +7:2 } } diff --git a/tests/mir-opt/combine_transmutes.rs b/tests/mir-opt/combine_transmutes.rs index 7088488c1b8..403f9356ce2 100644 --- a/tests/mir-opt/combine_transmutes.rs +++ b/tests/mir-opt/combine_transmutes.rs @@ -32,12 +32,6 @@ pub unsafe fn integer_transmutes() { // EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff pub unsafe fn adt_transmutes() { - let _a: u8 = transmute(EnumNoRepr::A); - let _a: i8 = transmute(EnumNoRepr::B); - let _a: usize = transmute(EnumReprIsize::A); - let _a: isize = transmute(EnumReprIsize::B); - let _a: u8 = transmute(std::cmp::Ordering::Less); - let _a: i8 = transmute(std::cmp::Ordering::Less); let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX)); let _a: i16 = transmute(std::num::Wrapping(0_i16)); let _a: u16 = transmute(std::num::Wrapping(0_i16)); @@ -46,20 +40,4 @@ pub unsafe fn adt_transmutes() { let _a: ManuallyDrop<String> = transmute(MaybeUninit::<String>::uninit()); } -#[inline(always)] -#[custom_mir(dialect = "runtime", phase = "initial")] -const unsafe fn mir_transmute<T, U>(x: T) -> U { - mir!{ - { - RET = CastTransmute(x); - Return() - } - } -} - -pub enum EnumNoRepr { A, B, C } - -#[repr(isize)] -pub enum EnumReprIsize { A, B, C } - pub union Union32 { u32: u32, i32: i32 } diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index f63ee705d92..d72675c2d11 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -45,7 +45,8 @@ } bb1: { - _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index f63ee705d92..d72675c2d11 100644 --- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -45,7 +45,8 @@ } bb1: { - _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _5 = (*_1)[3 of 4]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 _0 = const (); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff index 36336d967a9..33bbad2f422 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff @@ -27,7 +27,8 @@ } bb1: { - _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 diff --git a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff index 36336d967a9..33bbad2f422 100644 --- a/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff +++ b/tests/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff @@ -27,7 +27,8 @@ } bb1: { - _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 +- _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 ++ _1 = _2[2 of 3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 _0 = const (); // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff index e768a47a96d..e3757941c8c 100644 --- a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff +++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff @@ -22,17 +22,17 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:10 -- _1 = OffsetOf(Alpha, [0]); // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 -+ _1 = const 4_usize; // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 +- _1 = OffsetOf(Alpha, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL ++ _1 = const 4_usize; // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:10 -- _2 = OffsetOf(Alpha, [1]); // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 -+ _2 = const 0_usize; // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 +- _2 = OffsetOf(Alpha, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL ++ _2 = const 0_usize; // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 -- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 -+ _3 = const 2_usize; // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 +- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL ++ _3 = const 2_usize; // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 -- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 -+ _4 = const 3_usize; // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 +- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL ++ _4 = const 3_usize; // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL _0 = const (); // scope 0 at $DIR/offset_of.rs:+0:15: +5:2 StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff index e40fdbd79d8..4a655604cd1 100644 --- a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff +++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff @@ -22,13 +22,13 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:11 - _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $DIR/offset_of.rs:+1:14: +1:37 + _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:11 - _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $DIR/offset_of.rs:+2:14: +2:37 + _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 - _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:37 + _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 - _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:37 + _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL _0 = const (); // scope 0 at $DIR/offset_of.rs:+0:17: +5:2 StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 diff --git a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff index 2a0bff57db9..51707e71661 100644 --- a/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff +++ b/tests/mir-opt/copy-prop/borrowed_local.f.CopyProp.diff @@ -20,8 +20,7 @@ } bb1: { -- _0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38 -+ _0 = opaque::<u8>(_1) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38 + _0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38 // mir::Constant // + span: $DIR/borrowed_local.rs:28:28: 28:34 // + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff index 69acebf7642..1c7b6494d6d 100644 --- a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff @@ -6,15 +6,17 @@ let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30 let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 scope 1 { - debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 } bb0: { - StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 - _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12 - _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 - StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff b/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff new file mode 100644 index 00000000000..5866439055e --- /dev/null +++ b/tests/mir-opt/copy-prop/partial_init.main.CopyProp.diff @@ -0,0 +1,13 @@ +- // MIR for `main` before CopyProp ++ // MIR for `main` after CopyProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/partial_init.rs:+0:15: +0:15 + let mut _1: (isize,); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + (_1.0: isize) = const 1_isize; // scope 0 at $DIR/partial_init.rs:+4:13: +4:20 + return; // scope 0 at $DIR/partial_init.rs:+5:13: +5:21 + } + } + diff --git a/tests/mir-opt/copy-prop/partial_init.rs b/tests/mir-opt/copy-prop/partial_init.rs new file mode 100644 index 00000000000..f5ab9974f71 --- /dev/null +++ b/tests/mir-opt/copy-prop/partial_init.rs @@ -0,0 +1,18 @@ +// unit-test: CopyProp +// Verify that we do not ICE on partial initializations. + +#![feature(custom_mir, core_intrinsics)] +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR partial_init.main.CopyProp.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn main() { + mir! ( + let x: (isize, ); + { + x.0 = 1; + Return() + } + ) +} 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/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir index f0c9ef419bd..0424ce3abeb 100644 --- a/tests/mir-opt/issue_99325.main.built.after.mir +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)]) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated([], DefId(0:8 ~ issue_99325[22bb]::main::{constant#1})) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15 diff --git a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff index 0bfb34acac2..217f27efe5c 100644 --- a/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff +++ b/tests/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff @@ -30,10 +30,10 @@ _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:45: +1:46 StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49 -- _3 = wrapping_add::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 +- _3 = std::intrinsics::wrapping_add::<i32>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:9:14: 9:44 -- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) } +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::wrapping_add::<i32>}, val: Value(<ZST>) } + _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50 } @@ -46,10 +46,10 @@ _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+2:45: +2:46 StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49 -- _6 = wrapping_sub::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 +- _6 = std::intrinsics::wrapping_sub::<i32>(move _7, move _8) -> [return: bb2, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:10:14: 10:44 -- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) } +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {std::intrinsics::wrapping_sub::<i32>}, val: Value(<ZST>) } + _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 + goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50 } diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 71bdfcc5c49..c425f3cd506 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 - let mut _1: [usize; Const(Value(Leaf(0x00000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let mut _1: [usize; Const { ty: usize, kind: Leaf(0x00000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 9fa8609b751..22ad24f8d77 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 - let mut _1: [usize; Const(Value(Leaf(0x0000000000000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let mut _1: [usize; Const { ty: usize, kind: Leaf(0x0000000000000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 diff --git a/tests/mir-opt/nrvo_miscompile_111005.rs b/tests/mir-opt/nrvo_miscompile_111005.rs new file mode 100644 index 00000000000..a9f391b79d5 --- /dev/null +++ b/tests/mir-opt/nrvo_miscompile_111005.rs @@ -0,0 +1,22 @@ +// This is a miscompilation, #111005 to track + +// unit-test: RenameReturnPlace + +#![feature(custom_mir, core_intrinsics)] +extern crate core; +use core::intrinsics::mir::*; + +// EMIT_MIR nrvo_miscompile_111005.wrong.RenameReturnPlace.diff +#[custom_mir(dialect = "runtime", phase = "initial")] +pub fn wrong(arg: char) -> char { + mir!({ + let temp = arg; + RET = temp; + temp = 'b'; + Return() + }) +} + +fn main() { + assert_eq!(wrong('a'), 'a'); +} diff --git a/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff new file mode 100644 index 00000000000..a0acb6e7e11 --- /dev/null +++ b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff @@ -0,0 +1,18 @@ +- // MIR for `wrong` before RenameReturnPlace ++ // MIR for `wrong` after RenameReturnPlace + + fn wrong(_1: char) -> char { +- let mut _0: char; // return place in scope 0 at $DIR/nrvo_miscompile_111005.rs:+0:28: +0:32 ++ let mut _0: char; // return place in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: char; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = _2; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+3:9: +3:19 +- _2 = const 'b'; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+4:9: +4:19 ++ _0 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _0 = const 'b'; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+4:9: +4:19 + return; // scope 0 at $DIR/nrvo_miscompile_111005.rs:+5:9: +5:17 + } + } + diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir index 2b4971e2ef9..1d23871029d 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir @@ -3,7 +3,7 @@ fn manual_replace(_1: &mut u32, _2: u32) -> u32 { debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:23: +0:24 debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:36: +0:37 - let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+1:9: +1:13 + let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+0:47: +0:50 scope 1 { debug temp => _0; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13 } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir index ea0a44cf3bf..7a10b929ebd 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir @@ -3,7 +3,7 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) -> &mut [u32] { debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:45: +0:50 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:64: +0:69 - let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+1:5: +1:35 + let mut _0: &mut [u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98 scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { // at $DIR/slice_index.rs:26:11: 26:35 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir index 35dd973b55f..dcf79a4a4e7 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir @@ -3,15 +3,15 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] { debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46 - let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+1:5: +1:18 - let _3: &[u32]; // in scope 0 at $DIR/slice_index.rs:+1:6: +1:18 + let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:65: +0:71 scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) { // at $DIR/slice_index.rs:21:6: 21:18 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _3: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL } bb0: { - StorageLive(_3); // scope 0 at $DIR/slice_index.rs:+1:6: +1:18 + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL _3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, _1) -> bb1; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL @@ -19,8 +19,8 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] { } bb1: { - _0 = _3; // scope 0 at $DIR/slice_index.rs:+1:5: +1:18 - StorageDead(_3); // scope 0 at $DIR/slice_index.rs:+2:1: +2:2 + _0 = _3; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir index f27525bf3d9..0da7e5536ae 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir @@ -6,58 +6,120 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 let mut _3: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _5: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _8: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 - let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 - let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + let _5: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _6: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _7: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _8: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _10: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _11: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 scope 1 { - debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + debug iter => _4; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + let _9: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 scope 2 { - debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + debug x => _9; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } } scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:28:20: 28:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _14: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _15: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _17: std::ptr::NonNull<T>; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _18: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _19: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _12; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _13: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _13; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _18; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _21: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _22: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _22; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _22; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _23: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _23; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _23; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _23; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::<T>) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::<impl *const T>::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _12; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _16; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::<impl [T]>::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _20: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } } - scope 4 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 - debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + scope 22 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 + debug self => _3; // in scope 22 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } bb0: { - StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb10, unwind: bb8]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL - // + user_ty: UserType(0) - // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) } + StorageLive(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _20 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _12 = move _20 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _14) -> [0: bb11, otherwise: bb10]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL } bb1: { - StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - _7 = <std::slice::Iter<'_, T> as Iterator>::next(_8) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _7 = &mut _4; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _6 = <std::slice::Iter<'_, T> as Iterator>::next(_7) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 // mir::Constant // + span: $DIR/slice_iter.rs:28:14: 28:26 // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) } } bb2: { - _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - switchInt(move _9) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _8 = discriminant(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 } bb3: { - _10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 - StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 - _11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 - StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 - _12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 - _6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _9 = ((_6 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_10); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _10 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _11 = (_9,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _5 = <impl Fn(&T) as Fn<(&T,)>>::call(move _10, move _11) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 // mir::Constant // + span: $DIR/slice_iter.rs:29:9: 29:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) } @@ -68,16 +130,15 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb5: { - StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 - StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 - StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 drop(_2) -> bb7; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 } bb6: { - StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 - StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_10); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } @@ -94,10 +155,49 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb10: { - _3 = move _4; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:25: +1:26 - StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _15 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = _15 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb11: { + StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = Offset(_12, _16); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb12: { + StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _18 = _12 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _21 = _18 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _17 = NonNull::<T> { pointer: _21 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _19 = _13; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _3 = std::slice::Iter::<'_, T> { ptr: move _17, end: move _19, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value(<ZST>) } + // adt + // + user_ty: UserType(1) + StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _4 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir index 62dd9667d96..45b41b54c8b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir @@ -19,39 +19,104 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } - scope 7 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 - debug self => _8; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - let mut _13: &mut std::slice::Iter<'_, T>; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + scope 25 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _8; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + let mut _25: &mut std::slice::Iter<'_, T>; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL } } scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:35:20: 35:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _13: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _15: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _17: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _18: std::ptr::NonNull<T>; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _19: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _20: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _13; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _14: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _14; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _19; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _22: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _23: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _23; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _23; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::<T>) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _16; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::<impl *const T>::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _13; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _17; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::<impl [T]>::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _21: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } } - scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 - debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - scope 5 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - debug iter => _4; // in scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 + debug self => _4; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + scope 23 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + debug iter => _4; // in scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL } } - scope 6 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 - debug self => _3; // in scope 6 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + scope 24 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _3; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } bb0: { StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb9, unwind: bb7]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL - // + user_ty: UserType(0) - // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) } + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _21 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _13 = move _21 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _15 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _15) -> [0: bb10, otherwise: bb9]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL } bb1: { StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 - StorageLive(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - _13 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - _7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _13) -> [return: bb10, unwind: bb7]; // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageLive(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _25 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _25) -> [return: bb12, unwind: bb7]; // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) } @@ -99,15 +164,56 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb9: { - _3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = _16 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb10: { + StorageLive(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _17 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = Offset(_13, _17); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb11: { + StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _19 = _13 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _22 = _19 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _18 = NonNull::<T> { pointer: _22 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _20 = _14; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _4 = std::slice::Iter::<'_, T> { ptr: move _18, end: move _20, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value(<ZST>) } + // adt + // + user_ty: UserType(1) + StorageDead(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32 StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } - bb10: { - StorageDead(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + bb12: { + StorageDead(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 } 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 new file mode 100644 index 00000000000..e158f64e9c3 --- /dev/null +++ b/tests/mir-opt/reference_prop.dominate_storage.ReferencePropagation.diff @@ -0,0 +1,38 @@ +- // MIR for `dominate_storage` before ReferencePropagation ++ // MIR for `dominate_storage` after ReferencePropagation + + fn dominate_storage() -> () { + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23 + let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + goto -> bb1; // scope 0 at $DIR/reference_prop.rs:+8:11: +8:20 + } + + bb1: { + _1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18 + _2 = &_1; // scope 0 at $DIR/reference_prop.rs:+11:13: +11:19 + goto -> bb2; // scope 0 at $DIR/reference_prop.rs:+12:13: +12:22 + } + + bb2: { + _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:455:28: 455:34 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb3: { + StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+19:13: +19:27 + StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27 + _6 = const true; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + switchInt(_6) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:47 + } + } + diff --git a/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff new file mode 100644 index 00000000000..38ab16cedb7 --- /dev/null +++ b/tests/mir-opt/reference_prop.maybe_dead.ReferencePropagation.diff @@ -0,0 +1,56 @@ +- // MIR for `maybe_dead` before ReferencePropagation ++ // MIR for `maybe_dead` after ReferencePropagation + + fn maybe_dead(_1: bool) -> () { + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:24: +0:24 + let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: &mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _6: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _7: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _8: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+7:13: +7:27 + StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+8:13: +8:27 + _2 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+9:13: +9:18 + _3 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18 + _4 = &_2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _5 = &mut _3; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + (*_5) = const 7_i32; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:19 +- _6 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _6 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + switchInt(_1) -> [1: bb1, otherwise: bb2]; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:46 + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27 + 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:489:28: 489:34 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb2: { + _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:494:28: 494:34 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb3: { + _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:500:33: 500:39 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb4: { + return; // scope 0 at $DIR/reference_prop.rs:+36:13: +36:21 + } + } + diff --git a/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff new file mode 100644 index 00000000000..6e451786870 --- /dev/null +++ b/tests/mir-opt/reference_prop.multiple_storage.ReferencePropagation.diff @@ -0,0 +1,27 @@ +- // MIR for `multiple_storage` before ReferencePropagation ++ // MIR for `multiple_storage` after ReferencePropagation + + fn multiple_storage() -> () { + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23 + let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { + StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+6:13: +6:27 + _1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+7:13: +7:18 + _2 = &_1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:13: +9:27 + StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:27 + _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:429:33: 429:39 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/reference_prop.rs:+18:13: +18:21 + } + } + 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 new file mode 100644 index 00000000000..d99e110359f --- /dev/null +++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff @@ -0,0 +1,75 @@ +- // MIR for `mut_raw_then_mut_shr` before ReferencePropagation ++ // MIR for `mut_raw_then_mut_shr` after ReferencePropagation + + fn mut_raw_then_mut_shr() -> (i32, i32) { + let mut _0: (i32, i32); // return place in scope 0 at $DIR/reference_prop.rs:+0:30: +0:40 + let mut _1: i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:14 + let mut _4: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:36 + let mut _5: &mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:26 + let _8: (); // in scope 0 at $DIR/reference_prop.rs:+7:5: +7:26 + let mut _9: i32; // in scope 0 at $DIR/reference_prop.rs:+8:6: +8:7 + let mut _10: i32; // in scope 0 at $DIR/reference_prop.rs:+8:9: +8:10 + scope 1 { + 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 => &_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 => &_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 => &_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 + scope 6 { + } + } + } + } + } + } + + bb0: { + 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 +- 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 +- _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 +- _6 = &(*_2); // 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 +- (*_3) = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23 +- _8 = const (); // scope 6 at $DIR/reference_prop.rs:+7:5: +7:26 +- StorageDead(_8); // scope 5 at $DIR/reference_prop.rs:+7:25: +7:26 ++ _7 = _1; // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18 ++ _1 = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23 + StorageLive(_9); // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7 + _9 = _7; // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7 + StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10 + _10 = _1; // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10 + _0 = (move _9, move _10); // scope 5 at $DIR/reference_prop.rs:+8:5: +8:11 + 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(_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.read_through_raw.ReferencePropagation.diff b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff new file mode 100644 index 00000000000..75c1f8f57cc --- /dev/null +++ b/tests/mir-opt/reference_prop.read_through_raw.ReferencePropagation.diff @@ -0,0 +1,23 @@ +- // MIR for `read_through_raw` before ReferencePropagation ++ // MIR for `read_through_raw` after ReferencePropagation + + fn read_through_raw(_1: &mut usize) -> usize { + let mut _0: usize; // return place in scope 0 at $DIR/reference_prop.rs:+0:39: +0:44 + let mut _2: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _2 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25 +- _3 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26 +- _4 = &raw mut (*_2); // scope 0 at $DIR/reference_prop.rs:+12:13: +12:30 +- _5 = &raw mut (*_3); // scope 0 at $DIR/reference_prop.rs:+13:13: +13:30 +- _0 = (*_4); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22 +- _0 = (*_5); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22 ++ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22 ++ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22 + return; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:21 + } + } + diff --git a/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff new file mode 100644 index 00000000000..7b31ee695ce --- /dev/null +++ b/tests/mir-opt/reference_prop.reference_propagation.ReferencePropagation.diff @@ -0,0 +1,475 @@ +- // MIR for `reference_propagation` before ReferencePropagation ++ // MIR for `reference_propagation` after ReferencePropagation + + fn reference_propagation(_1: &T, _2: &T) -> () { + debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:39: +0:45 + debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:54: +0:66 + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:75: +0:75 + let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 + let _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:14 + let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19 + let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18 + let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + let _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:14 + let mut _13: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16 + let _14: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16 + let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19 + 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: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: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 + let mut _37: &usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17 + let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + let _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:14 + let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19 + let mut _46: &usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18 + let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 + 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: (); // 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 => &_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 + } + } + } + scope 4 { + debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:14 + let _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:15 + scope 5 { + debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:15 + let mut _12: &usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18 + scope 6 { + debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18 + let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14 + scope 7 { + debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14 + } + } + } + } + scope 8 { + debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:14 + let _20: &usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14 + scope 9 { + debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14 + let _21: &&usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14 + scope 10 { + debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14 + let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14 + scope 11 { + debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14 + } + } + } + } + scope 12 { + debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:14 + 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 + 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 + scope 15 { + debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14 + } + } + } + } + scope 16 { + debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:14 + let _34: &usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14 + scope 17 { + debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14 + let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14 + scope 18 { + debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14 + } + } + } + scope 19 { + debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:14 + let _40: &usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15 + scope 20 { + debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15 + let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14 + scope 21 { + debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14 + let _42: &usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15 + scope 22 { + debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15 + let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15 + scope 23 { + debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15 + let _44: &usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15 + scope 24 { + debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15 + } + } + } + } + } + } + scope 25 { +- 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 => _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 => _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 + } + } + } + } + + bb0: { +- 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(_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 + StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19 + StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18 + _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:16:9: 16:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19 + 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(_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 + StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:14 + _10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:17: +11:24 + StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:15 + _11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:18: +12:25 + StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18 + _12 = &_10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:23 + StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16 +- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16 +- _14 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16 +- _13 = &(*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16 ++ _13 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16 + _12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:16 + StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:15: +14:16 +- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:16: +14:17 + StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14 + _15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19 + StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19 + StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18 + _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:27:9: 27:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19 + StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20 +- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 + StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:14 + _19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:17: +22:24 + StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14 + _20 = &_19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:19 + StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14 + _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: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(&&usize) {opaque::<&&usize>}, val: Value(<ZST>) } + } + + bb3: { + 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 + StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6 + StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 + StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:14 + _26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:17: +31:24 + 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 = &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: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(*mut &usize) {opaque::<*mut &usize>}, val: Value(<ZST>) } + } + + bb4: { + 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 + StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6 + StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:14 + _33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:17: +40:24 + StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14 + _34 = &_33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:19 + StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14 +- _35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19 ++ _35 = _33; // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19 + StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18 + StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17 + _37 = _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17 + _36 = opaque::<&usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18 + // mir::Constant + // + span: $DIR/reference_prop.rs:53:9: 53:15 + // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18 + StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19 +- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:14 + _39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:17: +48:24 + StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15 + _40 = &_39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:20 + StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14 +- _41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20 ++ _41 = _39; // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20 + StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15 + _42 = _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20 + StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15 +- _43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21 ++ _43 = _39; // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21 + StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15 + _44 = _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20 + StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19 + StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18 + _46 = _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18 + _45 = opaque::<&usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19 + // mir::Constant + // + span: $DIR/reference_prop.rs:66:9: 66:15 + // + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19 + StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20 +- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6 + 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(_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 + StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19 + StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18 + _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:73:9: 73:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19 + 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(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 +- 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(_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 new file mode 100644 index 00000000000..ddeb04e50c7 --- /dev/null +++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff @@ -0,0 +1,536 @@ +- // MIR for `reference_propagation_const_ptr` before ReferencePropagation ++ // MIR for `reference_propagation_const_ptr` after ReferencePropagation + + fn reference_propagation_const_ptr(_1: *const T, _2: *const T) -> () { + debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:45: +0:51 + debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:63: +0:75 + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87 + let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 + let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19 + let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18 + let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + let mut _13: *const usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:26 + 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: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: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 + let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19 + let mut _45: *const usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18 + 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 _51: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6 + 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 _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 => &_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 + } + } + } + } + scope 5 { + let _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:14 + scope 6 { + debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:14 + let _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:15 + scope 7 { + debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:15 + let mut _12: *const usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18 + scope 8 { + debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18 + let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14 + scope 9 { + debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14 + } + } + } + } + } + scope 10 { + let _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:14 + scope 11 { + debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:14 + let _19: *const usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14 + scope 12 { + debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14 + let _20: &*const usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14 + scope 13 { + debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14 + let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14 + scope 14 { + debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14 + } + } + } + } + } + scope 15 { + let _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:14 + scope 16 { + debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:14 + 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 + 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 + scope 19 { + debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14 + } + } + } + } + } + scope 20 { + let _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:14 + scope 21 { + debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:14 + let _33: *const usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14 + scope 22 { + debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14 + let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14 + scope 23 { + debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14 + } + } + } + } + scope 24 { + let _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:14 + scope 25 { + debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:14 + let _39: *const usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15 + scope 26 { + debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15 + let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14 + scope 27 { + debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14 + let _41: *const usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15 + scope 28 { + debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15 + let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15 + scope 29 { + debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15 + let _43: *const usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15 + scope 30 { + debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15 + } + } + } + } + } + } + } + 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 => _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 + } + } + } + scope 34 { + let _52: *const T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 + scope 35 { + 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 => _54; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14 + } + } + } + scope 37 { + let _58: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14 + scope 38 { + 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 => _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 => _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 => _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 + } + } + } + } + } + + bb0: { +- 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(_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 + StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19 + StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18 + _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:202:9: 202:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19 + 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(_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 + StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:14 + _10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:17: +11:24 + StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:15 + _11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:18: +12:25 + StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18 + _12 = &raw const _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:33 + StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26 + _13 = &raw const _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26 + _12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:26 + StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:25: +14:26 + StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14 + _14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19 + StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19 + StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18 + _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:213:9: 213:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19 + StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20 +- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6 + StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 + StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:14 + _18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:17: +22:24 + StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14 + _19 = &raw const _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:29 + StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14 + _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: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: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: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 + StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6 + StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 + StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:14 + _25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:17: +31:24 + 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 = &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: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: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: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 + StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6 + StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:14 + _32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:17: +40:24 + StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14 + _33 = &raw const _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:29 + StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14 +- _34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19 ++ _34 = _32; // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19 + StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18 + StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17 + _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:239:9: 239:15 + // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18 + StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19 +- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:14 + _38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:17: +48:24 + StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15 + _39 = &raw const _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:30 + StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14 +- _40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20 ++ _40 = _38; // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20 + StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15 + _41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20 + StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15 +- _42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21 ++ _42 = _38; // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21 + StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15 + _43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20 + StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19 + StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18 + _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:252:9: 252:15 + // + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19 + StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20 +- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6 + 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(_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 + StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19 + StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18 + _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:259:9: 259:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19 + 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(_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 + _52 = &raw const (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:37 + StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38 + _53 = &raw const (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38 + _2 = move _53; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:38 + StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+69:37: +69:38 + 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:267:9: 267:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb8: { + 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: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:276:9: 276: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 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 new file mode 100644 index 00000000000..8d059de5b87 --- /dev/null +++ b/tests/mir-opt/reference_prop.reference_propagation_mut.ReferencePropagation.diff @@ -0,0 +1,472 @@ +- // MIR for `reference_propagation_mut` before ReferencePropagation ++ // MIR for `reference_propagation_mut` after ReferencePropagation + + fn reference_propagation_mut(_1: &mut T, _2: &mut T) -> () { + debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49 + debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:62: +0:74 + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87 + let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 + let mut _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:18 + let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19 + let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18 + let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + let mut _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:18 + let mut _13: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20 + let mut _14: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20 + let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19 + 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: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: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 + let mut _37: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17 + let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + let mut _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:18 + let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19 + let mut _46: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18 + let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6 + 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: (); // 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 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 => &_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 + } + } + } + scope 4 { + debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:18 + let mut _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:19 + scope 5 { + debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:19 + let mut _12: &mut usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18 + scope 6 { + debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18 + let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14 + scope 7 { + debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14 + } + } + } + } + scope 8 { + debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:18 + let _20: &mut usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14 + scope 9 { + debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14 + let _21: &&mut usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14 + scope 10 { + debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14 + let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14 + scope 11 { + debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14 + } + } + } + } + scope 12 { + debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:18 + 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 + 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 + scope 15 { + debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14 + } + } + } + } + scope 16 { + debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:18 + let _34: &mut usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14 + scope 17 { + debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14 + let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14 + scope 18 { + debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14 + } + } + } + scope 19 { + debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:18 + let _40: &mut usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15 + scope 20 { + debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15 + let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14 + scope 21 { + debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14 + let _42: &mut usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15 + scope 22 { + debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15 + let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15 + scope 23 { + debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15 + let _44: &mut usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15 + scope 24 { + debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15 + } + } + } + } + } + } + scope 25 { +- 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 => _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 => _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 + } + } + } + } + + bb0: { +- 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(_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 + StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19 + StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18 + _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:109:9: 109:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19 + 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(_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 + StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:18 + _10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:21: +11:28 + StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:19 + _11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:22: +12:29 + StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18 + _12 = &mut _10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:27 + StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20 +- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20 +- _14 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20 +- _13 = &mut (*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20 ++ _13 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20 + _12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:20 + StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:19: +14:20 +- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:20: +14:21 + StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14 + _15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19 + StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19 + StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18 + _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:120:9: 120:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19 + StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20 +- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 + StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:18 + _19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:21: +22:28 + StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14 + _20 = &mut _19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:23 + StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14 + _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: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: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: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 + StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6 + StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 + StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:18 + _26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:21: +31:28 + 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 = &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: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: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: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 + StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6 + StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:18 + _33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:21: +40:28 + StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14 + _34 = &mut _33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:23 + StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14 + _35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19 + StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18 + StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17 + _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:146:9: 146:15 + // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18 + StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19 +- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:18 + _39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:21: +48:28 + StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15 + _40 = &mut _39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:24 + StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14 + _41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20 + StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15 + _42 = move _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20 + StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15 + _43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21 + StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15 + _44 = move _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20 + StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19 + StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18 + _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:159:9: 159:15 + // + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19 + StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20 +- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6 + 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(_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 + StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19 + StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18 + _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:166:9: 166:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19 + 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(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6 +- 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:174:9: 174:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb8: { + 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 new file mode 100644 index 00000000000..c93aa52be11 --- /dev/null +++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff @@ -0,0 +1,482 @@ +- // MIR for `reference_propagation_mut_ptr` before ReferencePropagation ++ // MIR for `reference_propagation_mut_ptr` after ReferencePropagation + + fn reference_propagation_mut_ptr(_1: *mut T, _2: *mut T) -> () { + debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49 + debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:59: +0:71 + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:81: +0:81 + let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6 + let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19 + let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18 + let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6 + let mut _13: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:24 + 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: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: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 + let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19 + let mut _45: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18 + 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 _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 => &_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 + } + } + } + } + scope 5 { + let mut _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:18 + scope 6 { + debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:18 + let mut _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:19 + scope 7 { + debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:19 + let mut _12: *mut usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18 + scope 8 { + debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18 + let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14 + scope 9 { + debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14 + } + } + } + } + } + scope 10 { + let mut _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:18 + scope 11 { + debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:18 + let _19: *mut usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14 + scope 12 { + debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14 + let _20: &*mut usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14 + scope 13 { + debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14 + let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14 + scope 14 { + debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14 + } + } + } + } + } + scope 15 { + let mut _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:18 + scope 16 { + debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:18 + 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 + 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 + scope 19 { + debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14 + } + } + } + } + } + scope 20 { + let mut _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:18 + scope 21 { + debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:18 + let _33: *mut usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14 + scope 22 { + debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14 + let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14 + scope 23 { + debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14 + } + } + } + } + scope 24 { + let mut _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:18 + scope 25 { + debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:18 + let _39: *mut usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15 + scope 26 { + debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15 + let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14 + scope 27 { + debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14 + let _41: *mut usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15 + scope 28 { + debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15 + let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15 + scope 29 { + debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15 + let _43: *mut usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15 + scope 30 { + debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15 + } + } + } + } + } + } + } + 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 => _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 + } + } + } + scope 34 { + let _52: *mut T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14 + scope 35 { + 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 => _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 + } + } + } + } + } + + bb0: { +- 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(_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 + StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19 + StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18 + _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:304:9: 304:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19 + 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(_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 + StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:18 + _10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:21: +11:28 + StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:19 + _11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:22: +12:29 + StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18 + _12 = &raw mut _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:31 + StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24 + _13 = &raw mut _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24 + _12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:24 + StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:23: +14:24 + StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14 + _14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19 + StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19 + StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18 + _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:315:9: 315:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19 + StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20 +- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6 + StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6 + StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6 +- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6 + StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:18 + _18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:21: +22:28 + StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14 + _19 = &raw mut _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:27 + StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14 + _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: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: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: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 + StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6 + StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6 +- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6 + StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:18 + _25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:21: +31:28 + 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 = &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: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: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: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 + StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6 + StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6 +- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:18 + _32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:21: +40:28 + StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14 + _33 = &raw mut _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:27 + StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14 + _34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19 + StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18 + StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17 + _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:341:9: 341:15 + // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) } + } + + bb5: { + StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18 + StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19 +- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6 + StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6 + StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6 +- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:18 + _38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:21: +48:28 + StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15 + _39 = &raw mut _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:28 + StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14 + _40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20 + StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15 + _41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20 + StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15 + _42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21 + StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15 + _43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20 + StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19 + StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18 + _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:354:9: 354:15 + // + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) } + } + + bb6: { + StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19 + StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20 +- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6 + StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6 + StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6 + 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(_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 + StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19 + StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18 + _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:361:9: 361:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb7: { + StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19 + 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(_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 + _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:369:9: 369:15 + // + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) } + } + + bb8: { + 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 new file mode 100644 index 00000000000..4083b45470b --- /dev/null +++ b/tests/mir-opt/reference_prop.rs @@ -0,0 +1,592 @@ +// unit-test: ReferencePropagation +// needs-unwind + +#![feature(raw_ref_op)] +#![feature(core_intrinsics, custom_mir)] + +#[inline(never)] +fn opaque(_: impl Sized) {} + +fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) { + // Propagation through a reference. + { + let a = 5_usize; + let b = &a; // This borrow is only used once. + let c = *b; // This should be optimized. + opaque(()); // We use opaque to separate cases into basic blocks in the MIR. + } + + // Propagation through a two references. + { + let a = 5_usize; + let a2 = 7_usize; + let mut b = &a; + b = &a2; + // `b` is assigned twice, so we cannot propagate it. + let c = *b; + opaque(()); + } + + // Propagation through a borrowed reference. + { + let a = 5_usize; + let b = &a; + let d = &b; + let c = *b; // `b` is immutably borrowed, we know its value, but do not propagate it + opaque(d); // prevent `d` from being removed. + } + + // Propagation through a borrowed reference. + { + let a = 5_usize; + let mut b = &a; + let d = &raw mut b; + let c = *b; // `b` is mutably borrowed, we cannot know its value. + opaque(d); // prevent `d` from being removed. + } + + // Propagation through an escaping borrow. + { + let a = 7_usize; + let b = &a; + let c = *b; + opaque(b); // `b` escapes here, but we can still replace immutable borrow + } + + // Propagation through a transitively escaping borrow. + { + let a = 7_usize; + let b1 = &a; + let c = *b1; + let b2 = b1; + let c2 = *b2; + let b3 = b2; + // `b3` escapes here, so we can only replace immutable borrow, + // for either `b`, `b2` or `b3`. + opaque(b3); + } + + // Propagation a reborrow of an argument. + { + let a = &*single; + let b = *a; // This should be optimized as `*single`. + opaque(()); + } + + // Propagation a reborrow of a mutated argument. + { + let a = &*multiple; + multiple = &*single; + 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) { + // Propagation through a reference. + { + let mut a = 5_usize; + let b = &mut a; // This borrow is only used once. + let c = *b; // This should be optimized. + opaque(()); + } + + // Propagation through a two references. + { + let mut a = 5_usize; + let mut a2 = 7_usize; + let mut b = &mut a; + b = &mut a2; + // `b` is assigned twice, so we cannot propagate it. + let c = *b; + opaque(()); + } + + // Propagation through a borrowed reference. + { + let mut a = 5_usize; + let b = &mut a; + let d = &b; + let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. + opaque(d); // prevent `d` from being removed. + } + + // Propagation through a borrowed reference. + { + let mut a = 5_usize; + let mut b = &mut a; + let d = &raw mut b; + let c = *b; // `b` is mutably borrowed, we cannot know its value. + opaque(d); // prevent `d` from being removed. + } + + // Propagation through an escaping borrow. + { + let mut a = 7_usize; + let b = &mut a; + let c = *b; + opaque(b); // `b` escapes here, so we can only replace immutable borrow + } + + // Propagation through a transitively escaping borrow. + { + let mut a = 7_usize; + let b1 = &mut a; + let c = *b1; + let b2 = b1; + let c2 = *b2; + let b3 = b2; + // `b3` escapes here, so we can only replace immutable borrow, + // for either `b`, `b2` or `b3`. + opaque(b3); + } + + // Propagation a reborrow of an argument. + { + let a = &mut *single; + let b = *a; // This should be optimized as `*single`. + opaque(()); + } + + // Propagation a reborrow of a mutated argument. + { + let a = &mut *multiple; + multiple = &mut *single; + 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) { + // Propagation through a reference. + unsafe { + let a = 5_usize; + let b = &raw const a; // This borrow is only used once. + let c = *b; // This should be optimized. + opaque(()); + } + + // Propagation through a two references. + unsafe { + let a = 5_usize; + let a2 = 7_usize; + let mut b = &raw const a; + b = &raw const a2; + // `b` is assigned twice, so we cannot propagate it. + let c = *b; + opaque(()); + } + + // Propagation through a borrowed reference. + unsafe { + let a = 5_usize; + let b = &raw const a; + let d = &b; + let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. + 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 = &raw mut b; + let c = *b; // `b` is mutably borrowed, we cannot know its value. + opaque(d); // prevent `d` from being removed. + } + + // Propagation through an escaping borrow. + unsafe { + let a = 7_usize; + let b = &raw const a; + let c = *b; + opaque(b); // `b` escapes here, so we can only replace immutable borrow + } + + // Propagation through a transitively escaping borrow. + unsafe { + let a = 7_usize; + let b1 = &raw const a; + let c = *b1; + let b2 = b1; + let c2 = *b2; + let b3 = b2; + // `b3` escapes here, so we can only replace immutable borrow, + // for either `b`, `b2` or `b3`. + opaque(b3); + } + + // Propagation a reborrow of an argument. + unsafe { + let a = &raw const *single; + let b = *a; // This should be optimized as `*single`. + opaque(()); + } + + // Propagation a reborrow of a mutated argument. + unsafe { + let a = &raw const *multiple; + multiple = &raw const *single; + let b = *a; // This should not be optimized. + opaque(()); + } + + // Propagation through a reborrow. + unsafe { + let a = 13_usize; + let b = &raw const a; + let c = &raw const *b; + 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) { + // Propagation through a reference. + unsafe { + let mut a = 5_usize; + let b = &raw mut a; // This borrow is only used once. + let c = *b; // This should be optimized. + opaque(()); + } + + // Propagation through a two references. + unsafe { + let mut a = 5_usize; + let mut a2 = 7_usize; + let mut b = &raw mut a; + b = &raw mut a2; + // `b` is assigned twice, so we cannot propagate it. + let c = *b; + opaque(()); + } + + // Propagation through a borrowed reference. + unsafe { + let mut a = 5_usize; + let b = &raw mut a; + let d = &b; + let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed. + 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 = &raw mut b; + let c = *b; // `b` is mutably borrowed, we cannot know its value. + opaque(d); // prevent `d` from being removed. + } + + // Propagation through an escaping borrow. + unsafe { + let mut a = 7_usize; + let b = &raw mut a; + let c = *b; + opaque(b); // `b` escapes here, so we can only replace immutable borrow + } + + // Propagation through a transitively escaping borrow. + unsafe { + let mut a = 7_usize; + let b1 = &raw mut a; + let c = *b1; + let b2 = b1; + let c2 = *b2; + let b3 = b2; + // `b3` escapes here, so we can only replace immutable borrow, + // for either `b`, `b2` or `b3`. + opaque(b3); + } + + // Propagation a reborrow of an argument. + unsafe { + let a = &raw mut *single; + let b = *a; // This should be optimized as `*single`. + opaque(()); + } + + // Propagation a reborrow of a mutated argument. + unsafe { + let a = &raw mut *multiple; + multiple = &raw mut *single; + 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")] +fn read_through_raw(x: &mut usize) -> usize { + use std::intrinsics::mir::*; + + mir!( + let r1: &mut usize; + let r2: &mut usize; + let p1: *mut usize; + let p2: *mut usize; + + { + r1 = &mut *x; + r2 = &mut *r1; + p1 = &raw mut *r1; + p2 = &raw mut *r2; + + RET = *p1; + RET = *p2; + Return() + } + ) +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn multiple_storage() { + use std::intrinsics::mir::*; + + mir!( + let x: i32; + { + StorageLive(x); + x = 5; + let z = &x; + StorageDead(x); + StorageLive(x); + // As there are multiple `StorageLive` statements for `x`, we cannot know if this `z`'s + // pointer address is the address of `x`, so do nothing. + let y = *z; + Call(RET, retblock, opaque(y)) + } + + retblock = { + Return() + } + ) +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn dominate_storage() { + use std::intrinsics::mir::*; + + mir!( + let x: i32; + let r: &i32; + let c: i32; + let d: bool; + { Goto(bb0) } + bb0 = { + x = 5; + r = &x; + Goto(bb1) + } + bb1 = { + let c = *r; + Call(RET, bb2, opaque(c)) + } + bb2 = { + StorageDead(x); + StorageLive(x); + let d = true; + match d { false => bb2, _ => bb0 } + } + ) +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +fn maybe_dead(m: bool) { + use std::intrinsics::mir::*; + + mir!( + let x: i32; + let y: i32; + { + StorageLive(x); + StorageLive(y); + x = 5; + y = 5; + let a = &x; + let b = &mut y; + // As we don't replace `b` in `bb2`, we cannot replace it here either. + *b = 7; + // But this can still be replaced. + let u = *a; + match m { true => bb1, _ => bb2 } + } + bb1 = { + StorageDead(x); + StorageDead(y); + Call(RET, bb2, opaque(u)) + } + bb2 = { + // As `x` may be `StorageDead`, `a` may be dangling, so we do nothing. + let z = *a; + Call(RET, bb3, opaque(z)) + } + bb3 = { + // As `y` may be `StorageDead`, `b` may be dangling, so we do nothing. + // This implies that we also do not substitute `b` in `bb0`. + let t = *b; + Call(RET, retblock, opaque(t)) + } + retblock = { + Return() + } + ) +} + +fn mut_raw_then_mut_shr() -> (i32, i32) { + let mut x = 2; + let xref = &mut x; + let xraw = &mut *xref as *mut _; + let xshr = &*xref; + // Verify that we completely replace with `x` in both cases. + let a = *xshr; + unsafe { *xraw = 4; } + (a, x) +} + +fn unique_with_copies() { + let y = { + let mut a = 0; + let x = &raw mut a; + // `*y` is not replacable below, so we must not replace `*x`. + unsafe { opaque(*x) }; + x + }; + // But rewriting as `*x` is ok. + 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; + reference_propagation(&x, &y); + reference_propagation_mut(&mut x, &mut y); + reference_propagation_const_ptr(&raw const x, &raw const y); + reference_propagation_mut_ptr(&raw mut x, &raw mut y); + read_through_raw(&mut x); + multiple_storage(); + dominate_storage(); + maybe_dead(true); + mut_raw_then_mut_shr(); + unique_with_copies(); + debuginfo(); + many_debuginfo(); +} + +// EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff +// EMIT_MIR reference_prop.reference_propagation_mut.ReferencePropagation.diff +// EMIT_MIR reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff +// EMIT_MIR reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff +// EMIT_MIR reference_prop.read_through_raw.ReferencePropagation.diff +// EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff +// EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff +// 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 new file mode 100644 index 00000000000..b754aff4755 --- /dev/null +++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff @@ -0,0 +1,67 @@ +- // MIR for `unique_with_copies` before ReferencePropagation ++ // MIR for `unique_with_copies` after ReferencePropagation + + fn unique_with_copies() -> () { + let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:25: +0:25 + let _1: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:10 + let mut _2: i32; // in scope 0 at $DIR/reference_prop.rs:+2:13: +2:18 + let _4: (); // in scope 0 at $DIR/reference_prop.rs:+5:18: +5:28 + let mut _5: i32; // in scope 0 at $DIR/reference_prop.rs:+5:25: +5:27 + 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 => _3; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10 + scope 5 { + } + } + scope 2 { + debug a => _2; // in scope 2 at $DIR/reference_prop.rs:+2:13: +2:18 + let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14 + scope 3 { + debug x => _3; // in scope 3 at $DIR/reference_prop.rs:+3:13: +3:14 + scope 4 { + } + } + } + + bb0: { +- 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 + _3 = &raw mut _2; // scope 2 at $DIR/reference_prop.rs:+3:17: +3:27 + StorageLive(_4); // scope 3 at $DIR/reference_prop.rs:+5:9: +5:30 + StorageLive(_5); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27 + _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: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 +- 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 + StorageLive(_7); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23 +- _7 = (*_1); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23 ++ _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:528:14: 528:20 + // + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) } + } + + bb2: { + 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 + return; // scope 0 at $DIR/reference_prop.rs:+10:2: +10:2 + } + } + diff --git a/tests/mir-opt/slice_filter.rs b/tests/mir-opt/slice_filter.rs index 97c18af31de..be32f40f132 100644 --- a/tests/mir-opt/slice_filter.rs +++ b/tests/mir-opt/slice_filter.rs @@ -12,7 +12,9 @@ pub fn variant_b(input: &[(usize, usize, usize, usize)]) -> usize { input.iter().filter(|&&(a, b, c, d)| a <= c && d <= b || c <= a && b <= d).count() } +// EMIT_MIR slice_filter.variant_a-{closure#0}.ReferencePropagation.diff // EMIT_MIR slice_filter.variant_a-{closure#0}.CopyProp.diff // EMIT_MIR slice_filter.variant_a-{closure#0}.DestinationPropagation.diff // EMIT_MIR slice_filter.variant_b-{closure#0}.CopyProp.diff +// EMIT_MIR slice_filter.variant_b-{closure#0}.ReferencePropagation.diff // EMIT_MIR slice_filter.variant_b-{closure#0}.DestinationPropagation.diff diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff index 3bb0358ffe3..60e5056c7a9 100644 --- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff +++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff @@ -101,16 +101,16 @@ } 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 + 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 + 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 + 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 StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 @@ -184,10 +184,10 @@ 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 } 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 294c3272f4f..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,118 +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 => &((*_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: { - _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 - _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 - _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 - _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 + _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 - _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 - 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 - 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: { @@ -123,113 +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 - _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 - _33 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - _34 = deref_copy (*_19); // 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 - 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 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 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 - _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 - _37 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - _38 = deref_copy (*_14); // 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 - 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 - _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 - _41 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - _42 = deref_copy (*_23); // 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 - 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 new file mode 100644 index 00000000000..2534eeef432 --- /dev/null +++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.ReferencePropagation.diff @@ -0,0 +1,267 @@ +- // MIR for `variant_a::{closure#0}` before ReferencePropagation ++ // MIR for `variant_a::{closure#0}` after ReferencePropagation + + 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 _31: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _37: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _38: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _43: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _44: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + 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 => &((*_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 => &&((*_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 => &((*_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 => &&((*_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 => &((*_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 => &&((*_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 => &((*_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 => &&((*_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 => &((*_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 + } + } + } + + bb0: { +- 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 + _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 + _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 + _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 + 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 +- _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 + 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 = ((*_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 = ((*_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 + switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56 + } + + bb1: { + _0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + } + + 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 +- _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 + 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 = ((*_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 = ((*_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 + 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 + return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76 + } + + bb4: { + _7 = const false; // 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 + 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(_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 + 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 = ((*_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 = ((*_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 + _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 + switchInt(move _7) -> [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 + 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(_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 + 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 = ((*_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 = ((*_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 + _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 + } + + bb8: { + StorageDead(_21); // 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 + goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76 + } + } + diff --git a/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff new file mode 100644 index 00000000000..d1241c6b024 --- /dev/null +++ b/tests/mir-opt/slice_filter.variant_b-{closure#0}.ReferencePropagation.diff @@ -0,0 +1,103 @@ +- // MIR for `variant_b::{closure#0}` before ReferencePropagation ++ // MIR for `variant_b::{closure#0}` after ReferencePropagation + + fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:12:25: 12:41], _2: &&(usize, usize, usize, usize)) -> bool { + let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:42: +0:42 + let _3: usize; // in scope 0 at $DIR/slice_filter.rs:+0:29: +0:30 + let _4: usize; // in scope 0 at $DIR/slice_filter.rs:+0:32: +0:33 + let _5: usize; // in scope 0 at $DIR/slice_filter.rs:+0:35: +0:36 + let _6: usize; // in scope 0 at $DIR/slice_filter.rs:+0:38: +0:39 + let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:58 + let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:48 + let mut _9: usize; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:43 + let mut _10: usize; // in scope 0 at $DIR/slice_filter.rs:+0:47: +0:48 + let mut _11: bool; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:58 + let mut _12: usize; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:53 + let mut _13: usize; // in scope 0 at $DIR/slice_filter.rs:+0:57: +0:58 + let mut _14: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:78 + let mut _15: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:68 + let mut _16: usize; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:63 + let mut _17: usize; // in scope 0 at $DIR/slice_filter.rs:+0:67: +0:68 + let mut _18: bool; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:78 + let mut _19: usize; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:73 + let mut _20: usize; // in scope 0 at $DIR/slice_filter.rs:+0:77: +0:78 + let mut _21: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40 + let mut _22: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40 + let mut _23: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40 + let mut _24: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40 + scope 1 { + debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:29: +0:30 + debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:32: +0:33 + debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:35: +0:36 + debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:38: +0:39 + } + + bb0: { + _21 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30 + _3 = ((*_21).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30 + _22 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33 + _4 = ((*_22).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33 + _23 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36 + _5 = ((*_23).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36 + _24 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39 + _6 = ((*_24).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39 + StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58 + StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48 + _8 = Le(_3, _5); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48 + switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58 + } + + bb1: { + _0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78 + goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78 + } + + bb2: { + StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68 + _15 = Le(_5, _3); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68 + switchInt(move _15) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + } + + bb3: { + StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78 + StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78 + return; // scope 0 at $DIR/slice_filter.rs:+0:78: +0:78 + } + + bb4: { + _7 = const false; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58 + StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58 + StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58 + goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58 + } + + bb5: { + StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58 + _11 = Le(_6, _4); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58 + _7 = move _11; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58 + StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58 + StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58 + switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78 + } + + bb6: { + _14 = const false; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + } + + bb7: { + StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78 + _18 = Le(_4, _6); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78 + _14 = move _18; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78 + } + + bb8: { + StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78 + StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78 + _0 = move _14; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78 + goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78 + } + } + 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/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile new file mode 100644 index 00000000000..cabe951e1c5 --- /dev/null +++ b/tests/run-make/branch-protection-check-IBT/Makefile @@ -0,0 +1,15 @@ +# Check for GNU Property Note + +include ../tools.mk + +# How to run this +# python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/ + +# only-x86_64 + +all: +ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64) + $(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles' -C save-temps ./main.rs -o $(TMPDIR)/rsmain + readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property" +endif + diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs new file mode 100644 index 00000000000..ad379d6ea43 --- /dev/null +++ b/tests/run-make/branch-protection-check-IBT/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("hello world"); +} diff --git a/tests/run-make/coverage-llvmir/filecheck.testprog.txt b/tests/run-make/coverage-llvmir/filecheck.testprog.txt index c943261d799..b3a8808df05 100644 --- a/tests/run-make/coverage-llvmir/filecheck.testprog.txt +++ b/tests/run-make/coverage-llvmir/filecheck.testprog.txt @@ -36,7 +36,7 @@ CHECK-SAME: section "llvm.metadata" CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} { CHECK-NEXT: start: CHECK-NOT: [[DEFINE_INTERNAL]] -CHECK: %pgocount = load i64, {{i64\*|ptr}} +CHECK: atomicrmw add ptr CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, CHECK: declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]] diff --git a/tests/run-make/coverage-reports/Makefile b/tests/run-make/coverage-reports/Makefile index d4ae03e590a..0ae409c4119 100644 --- a/tests/run-make/coverage-reports/Makefile +++ b/tests/run-make/coverage-reports/Makefile @@ -138,6 +138,7 @@ endif ) \ 2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \ | "$(PYTHON)" $(BASEDIR)/normalize_paths.py \ + | "$(PYTHON)" $(BASEDIR)/sort_subviews.py \ > "$(TMPDIR)"/actual_show_coverage.$@.txt || \ ( status=$$? ; \ >&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \ @@ -158,23 +159,15 @@ ifdef RUSTC_BLESS_TEST else # Compare the show coverage output (`--bless` refreshes `typical` files). # - # FIXME(richkadel): None of the Rust test source samples have the - # `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation - # with `llvm-cov show`. When reporting coverage for multiple instantiations of a generic function, - # with different type substitutions, `llvm-cov show` prints these in a non-deterministic order, - # breaking the `diff` comparison. + # `llvm-cov show` normally prints instantiation groups in an unpredictable + # order, but we have used `sort_subviews.py` to sort them, so we can still + # check the output directly with `diff`. # - # A partial workaround is implemented below, with `diff --ignore-matching-lines=RE` - # to ignore each line prefixing each generic instantiation coverage code region. - # - # This workaround only works if the coverage counts are identical across all reported - # instantiations. If there is no way to ensure this, you may need to apply the - # `// ignore-llvm-cov-show-diffs` directive, and check for differences using the - # `.json` files to validate that results have not changed. (Until then, the JSON - # files are redundant, so there is no need to generate `expected_*.json` files or - # compare actual JSON results.) - - $(DIFF) --ignore-matching-lines='^ \| .*::<.*>.*:$$' --ignore-matching-lines='^ \| <.*>::.*:$$' \ + # Some of the test cases are currently not working (since #110393) and have + # been marked with `// ignore-llvm-cov-show-diffs` so that they don't fail + # the build. + + $(DIFF) \ expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \ ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \ >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \ diff --git a/tests/run-make/coverage-reports/expected_show_coverage.async.txt b/tests/run-make/coverage-reports/expected_show_coverage.async.txt index 87ccb6c43ea..93c1535b06b 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.async.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.async.txt @@ -41,9 +41,9 @@ 41| 1| // executed asynchronously. 42| 1| match x { 43| 1| y if c(x).await == y + 1 => { d().await; } - ^0 ^0 ^0 ^0 + ^0 ^0 ^0 ^0 44| 1| y if f().await == y + 1 => (), - ^0 ^0 ^0 + ^0 ^0 ^0 45| 1| _ => (), 46| | } 47| 1|} diff --git a/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt b/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt new file mode 100644 index 00000000000..81468cb35da --- /dev/null +++ b/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt @@ -0,0 +1,49 @@ + 1| |// compile-flags: --edition=2021 + 2| | + 3| |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a + 4| |// predictable order, while preserving their heterogeneous contents. + 5| | + 6| 1|fn main() { + 7| 1| let cond = std::env::args().len() > 1; + 8| 1| generic_fn::<()>(cond); + 9| 1| generic_fn::<&'static str>(!cond); + 10| 1| if false { + 11| 0| generic_fn::<char>(cond); + 12| 1| } + 13| 1| generic_fn::<i32>(cond); + 14| 1| other_fn(); + 15| 1|} + 16| | + 17| 3|fn generic_fn<T>(cond: bool) { + 18| 3| if cond { + 19| 1| println!("{}", std::any::type_name::<T>()); + 20| 2| } + 21| 3|} + ------------------ + | Unexecuted instantiation: sort_groups::generic_fn::<char> + ------------------ + | sort_groups::generic_fn::<&str>: + | 17| 1|fn generic_fn<T>(cond: bool) { + | 18| 1| if cond { + | 19| 1| println!("{}", std::any::type_name::<T>()); + | 20| 1| } + | ^0 + | 21| 1|} + ------------------ + | sort_groups::generic_fn::<()>: + | 17| 1|fn generic_fn<T>(cond: bool) { + | 18| 1| if cond { + | 19| 0| println!("{}", std::any::type_name::<T>()); + | 20| 1| } + | 21| 1|} + ------------------ + | sort_groups::generic_fn::<i32>: + | 17| 1|fn generic_fn<T>(cond: bool) { + | 18| 1| if cond { + | 19| 0| println!("{}", std::any::type_name::<T>()); + | 20| 1| } + | 21| 1|} + ------------------ + 22| | + 23| 1|fn other_fn() {} + diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt b/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt index 65eb1008dd8..412f4a93b9c 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt @@ -19,29 +19,29 @@ 18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); 19| 2|} ------------------ - | used_crate::used_only_from_bin_crate_generic_function::<&str>: + | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_> + ------------------ + | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>: | 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} ------------------ - | used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>: + | used_crate::used_only_from_bin_crate_generic_function::<&str>: | 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { | 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 19| 1|} ------------------ - | Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_> - ------------------ 20| |// Expect for above function: `Unexecuted instantiation` (see below) 21| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { 22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); 23| 2|} ------------------ - | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>: + | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} ------------------ - | used_crate::used_only_from_this_lib_crate_generic_function::<&str>: + | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>: | 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) { | 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg); | 23| 1|} @@ -51,12 +51,12 @@ 26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); 27| 2|} ------------------ - | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>: + | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); | 27| 1|} ------------------ - | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: + | used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>: | 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { | 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); | 27| 1|} diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt index 748343885de..66ca9e80a32 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt @@ -42,6 +42,8 @@ 40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg); 41| 2|} ------------------ + | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_> + ------------------ | used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>: | 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) { | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); @@ -52,8 +54,6 @@ | 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg); | 41| 1|} ------------------ - | Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_> - ------------------ 42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`) 43| | 44| |#[inline(always)] @@ -77,16 +77,16 @@ 51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); 52| 3|} ------------------ - | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>: - | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { - | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); - | 52| 1|} - ------------------ | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>: | 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { | 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); | 52| 2|} ------------------ + | used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>: + | 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { + | 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg); + | 52| 1|} + ------------------ 53| | 54| |#[inline(always)] 55| 3|pub fn used_with_same_type_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) { diff --git a/tests/run-make/coverage-reports/sort_subviews.py b/tests/run-make/coverage-reports/sort_subviews.py new file mode 100644 index 00000000000..10cfc51d447 --- /dev/null +++ b/tests/run-make/coverage-reports/sort_subviews.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +# `llvm-cov show` prints grouped subviews (e.g. for generic functions) in an +# unstable order, which is inconvenient when checking output snapshots with +# `diff`. To work around that, this script detects consecutive subviews in its +# piped input, and sorts them while preserving their contents. + +from __future__ import print_function + +import sys + + +def main(): + subviews = [] + + def flush_subviews(): + if not subviews: + return + + # The last "subview" should be just a boundary line on its own, so + # temporarily remove it before sorting the accumulated subviews. + terminator = subviews.pop() + subviews.sort() + subviews.append(terminator) + + for view in subviews: + for line in view: + print(line, end="") + + subviews.clear() + + for line in sys.stdin: + if line.startswith(" ------------------"): + # This is a subview boundary line, so start a new subview. + subviews.append([line]) + elif line.startswith(" |"): + # Add this line to the current subview. + subviews[-1].append(line) + else: + # This line is not part of a subview, so sort and print any + # accumulated subviews, and then print the line as-is. + flush_subviews() + print(line, end="") + + flush_subviews() + assert not subviews + + +if __name__ == "__main__": + main() diff --git a/tests/run-make/coverage/sort_groups.rs b/tests/run-make/coverage/sort_groups.rs new file mode 100644 index 00000000000..f89f9f3ec61 --- /dev/null +++ b/tests/run-make/coverage/sort_groups.rs @@ -0,0 +1,23 @@ +// compile-flags: --edition=2021 + +// Demonstrate that `sort_subviews.py` can sort instantiation groups into a +// predictable order, while preserving their heterogeneous contents. + +fn main() { + let cond = std::env::args().len() > 1; + generic_fn::<()>(cond); + generic_fn::<&'static str>(!cond); + if false { + generic_fn::<char>(cond); + } + generic_fn::<i32>(cond); + other_fn(); +} + +fn generic_fn<T>(cond: bool) { + if cond { + println!("{}", std::any::type_name::<T>()); + } +} + +fn other_fn() {} diff --git a/tests/run-make/forced-unwind-terminate-pof/Makefile b/tests/run-make/forced-unwind-terminate-pof/Makefile new file mode 100644 index 00000000000..871621520b9 --- /dev/null +++ b/tests/run-make/forced-unwind-terminate-pof/Makefile @@ -0,0 +1,9 @@ +# ignore-cross-compile +# only-linux +include ../tools.mk + +all: foo + $(call RUN,foo) | $(CGREP) -v "cannot unwind" + +foo: foo.rs + $(RUSTC) $< diff --git a/tests/run-make/forced-unwind-terminate-pof/foo.rs b/tests/run-make/forced-unwind-terminate-pof/foo.rs new file mode 100644 index 00000000000..0a51287313f --- /dev/null +++ b/tests/run-make/forced-unwind-terminate-pof/foo.rs @@ -0,0 +1,17 @@ +// Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards. + +#![feature(c_unwind)] +#![no_main] + +extern "C-unwind" { + fn pthread_exit(v: *mut core::ffi::c_void) -> !; +} + +unsafe extern "C" fn call_pthread_exit() { + pthread_exit(core::ptr::null_mut()); +} + +#[no_mangle] +unsafe extern "C-unwind" fn main(_argc: core::ffi::c_int, _argv: *mut *mut core::ffi::c_char) { + call_pthread_exit(); +} diff --git a/tests/run-make/staticlib-dylib-linkage/Makefile b/tests/run-make/staticlib-dylib-linkage/Makefile new file mode 100644 index 00000000000..a1e86a7ce4b --- /dev/null +++ b/tests/run-make/staticlib-dylib-linkage/Makefile @@ -0,0 +1,21 @@ +include ../tools.mk + +# ignore-cross-compile +# ignore-msvc FIXME(bjorn3) can't figure out how to link with the MSVC toolchain +# ignore-wasm wasm doesn't support dynamic libraries + +all: + $(RUSTC) -C prefer-dynamic bar.rs + $(RUSTC) foo.rs --crate-type staticlib --print native-static-libs \ + -Z staticlib-allow-rdylib-deps 2>&1 | grep 'note: native-static-libs: ' \ + | sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt + cat $(TMPDIR)/libs.txt + +ifdef IS_MSVC + $(CC) $(CFLAGS) /c foo.c /Fo:$(TMPDIR)/foo.o + $(RUSTC_LINKER) $(TMPDIR)/foo.o $(TMPDIR)/foo.lib $$(cat $(TMPDIR)/libs.txt) $(call OUT_EXE,foo) +else + $(CC) $(CFLAGS) foo.c -L $(TMPDIR) -lfoo $$(cat $(TMPDIR)/libs.txt) -o $(call RUN_BINFILE,foo) +endif + + $(call RUN,foo) diff --git a/tests/run-make/staticlib-dylib-linkage/bar.rs b/tests/run-make/staticlib-dylib-linkage/bar.rs new file mode 100644 index 00000000000..b3a7539abae --- /dev/null +++ b/tests/run-make/staticlib-dylib-linkage/bar.rs @@ -0,0 +1,5 @@ +#![crate_type = "dylib"] + +pub fn bar() { + println!("hello!"); +} diff --git a/tests/run-make/staticlib-dylib-linkage/foo.c b/tests/run-make/staticlib-dylib-linkage/foo.c new file mode 100644 index 00000000000..154f9682ef8 --- /dev/null +++ b/tests/run-make/staticlib-dylib-linkage/foo.c @@ -0,0 +1,10 @@ +#include <assert.h> + +extern void foo(); +extern unsigned bar(unsigned a, unsigned b); + +int main() { + foo(); + assert(bar(1, 2) == 3); + return 0; +} diff --git a/tests/run-make/staticlib-dylib-linkage/foo.rs b/tests/run-make/staticlib-dylib-linkage/foo.rs new file mode 100644 index 00000000000..af439391c75 --- /dev/null +++ b/tests/run-make/staticlib-dylib-linkage/foo.rs @@ -0,0 +1,13 @@ +#![crate_type = "staticlib"] + +extern crate bar; + +#[no_mangle] +pub extern "C" fn foo() { + bar::bar(); +} + +#[no_mangle] +pub extern "C" fn bar(a: u32, b: u32) -> u32 { + a + b +} diff --git a/tests/rustdoc-gui/check-stab-in-docblock.goml b/tests/rustdoc-gui/check-stab-in-docblock.goml index 2f62636211b..f25c88690e5 100644 --- a/tests/rustdoc-gui/check-stab-in-docblock.goml +++ b/tests/rustdoc-gui/check-stab-in-docblock.goml @@ -7,20 +7,26 @@ set-window-size: (786, 600) // Confirms that there 3 paragraphs. assert-count: (".top-doc .docblock p", 3) // Checking that there is no scrollable content. -store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(1)", "clientHeight") -store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(1)", "clientWidth") +store-property: (".top-doc .docblock p:nth-of-type(1)", { + "clientHeight": clientHeight, + "clientWidth": clientWidth, +}) assert-property: ( ".top-doc .docblock p:nth-of-type(1)", {"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|}, ) -store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(2)", "clientHeight") -store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(2)", "clientWidth") +store-property: (".top-doc .docblock p:nth-of-type(2)", { + "clientHeight": clientHeight, + "clientWidth": clientWidth, +}) assert-property: ( ".top-doc .docblock p:nth-of-type(2)", {"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|}, ) -store-property: (clientHeight, ".top-doc .docblock p:nth-of-type(3)", "clientHeight") -store-property: (clientWidth, ".top-doc .docblock p:nth-of-type(3)", "clientWidth") +store-property: (".top-doc .docblock p:nth-of-type(3)", { + "clientHeight": clientHeight, + "clientWidth": clientWidth, +}) assert-property: ( ".top-doc .docblock p:nth-of-type(3)", {"scrollHeight": |clientHeight|, "scrollWidth": |clientWidth|}, diff --git a/tests/rustdoc-gui/codeblock-sub.goml b/tests/rustdoc-gui/codeblock-sub.goml index 03575cc6aaa..a4b0558765a 100644 --- a/tests/rustdoc-gui/codeblock-sub.goml +++ b/tests/rustdoc-gui/codeblock-sub.goml @@ -1,5 +1,5 @@ // Test that code blocks nested within <sub> do not have a line height of 0. go-to: "file://" + |DOC_PATH| + "/test_docs/codeblock_sub/index.html" -store-property: (codeblock_sub_1, "#codeblock-sub-1", "offsetHeight") +store-property: ("#codeblock-sub-1", {"offsetHeight": codeblock_sub_1}) assert-property-false: ("#codeblock-sub-3", { "offsetHeight": |codeblock_sub_1| }) diff --git a/tests/rustdoc-gui/docblock-details.goml b/tests/rustdoc-gui/docblock-details.goml index 58ff17619f6..8e6d2ba824f 100644 --- a/tests/rustdoc-gui/docblock-details.goml +++ b/tests/rustdoc-gui/docblock-details.goml @@ -9,7 +9,7 @@ reload: assert-text: (".top-doc .docblock > h3", "Hello") assert-css: ( ".top-doc .docblock > h3", - {"border-bottom": "1px solid rgb(210, 210, 210)"}, + {"border-bottom": "1px solid #d2d2d2"}, ) // We now check that the `<summary>` doesn't have a bottom border and has the correct display. assert-css: ( diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml index 60fd7c4e198..030ff8f8a3e 100644 --- a/tests/rustdoc-gui/item-info.goml +++ b/tests/rustdoc-gui/item-info.goml @@ -4,8 +4,8 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" // We set a fixed size so there is no chance of "random" resize. set-window-size: (1100, 800) // We check that ".item-info" is bigger than its content. -assert-css: (".item-info", {"width": "840px"}) -assert-css: (".item-info .stab", {"width": "289px"}) +assert-size: (".item-info", {"width": 840}) +assert-size: (".item-info .stab", {"width": 289}) assert-position: (".item-info .stab", {"x": 245}) // Now we ensure that they're not rendered on the same line. diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index f65da577478..ecb57c274a5 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -225,12 +225,12 @@ assert: "#method\.create_an_iterator_from_read .tooltip:focus" // Now we check that the focus isn't given back to the wrong item when opening // another popover. -store-window-property: (scroll, "scrollY") +store-window-property: {"scrollY": scroll} click: "#method\.create_an_iterator_from_read .fn" // We ensure that the scroll position changed. assert-window-property-false: {"scrollY": |scroll|} // Store the new position. -store-window-property: (scroll, "scrollY") +store-window-property: {"scrollY": scroll} click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" wait-for: "//*[@class='tooltip popover']" click: "#settings-menu a" @@ -239,12 +239,12 @@ click: ".search-input" assert-window-property-false: {"scrollY": |scroll|} // Same but with Escape handling. -store-window-property: (scroll, "scrollY") +store-window-property: {"scrollY": scroll} click: "#method\.create_an_iterator_from_read .fn" // We ensure that the scroll position changed. assert-window-property-false: {"scrollY": |scroll|} // Store the new position. -store-window-property: (scroll, "scrollY") +store-window-property: {"scrollY": scroll} click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" wait-for: "//*[@class='tooltip popover']" click: "#settings-menu a" diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml index 77061ea2a3f..af4293dfc00 100644 --- a/tests/rustdoc-gui/scrape-examples-button-focus.goml +++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml @@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html" // The next/prev buttons vertically scroll the code viewport between examples -store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre", "scrollTop") +store-property: (".scraped-example-list > .scraped-example pre", {"scrollTop": initialScrollTop}) focus: ".scraped-example-list > .scraped-example .next" press-key: "Enter" assert-property-false: (".scraped-example-list > .scraped-example pre", { @@ -16,7 +16,7 @@ assert-property: (".scraped-example-list > .scraped-example pre", { }, NEAR) // The expand button increases the scrollHeight of the minimized code viewport -store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") +store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": smallOffsetHeight}) assert-property-false: (".scraped-example-list > .scraped-example pre", { "scrollHeight": |smallOffsetHeight| }, NEAR) @@ -25,7 +25,7 @@ press-key: "Enter" assert-property-false: (".scraped-example-list > .scraped-example pre", { "offsetHeight": |smallOffsetHeight| }, NEAR) -store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") +store-property: (".scraped-example-list > .scraped-example pre", {"offsetHeight": fullOffsetHeight}) assert-property: (".scraped-example-list > .scraped-example pre", { "scrollHeight": |fullOffsetHeight| }, NEAR) diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml index 160056d6d05..4fc1c1ac065 100644 --- a/tests/rustdoc-gui/scrape-examples-layout.goml +++ b/tests/rustdoc-gui/scrape-examples-layout.goml @@ -9,9 +9,8 @@ assert-property-false: ( // Check that examples with very long lines have the same width as ones that don't. store-property: ( - clientWidth, ".more-scraped-examples .scraped-example:nth-child(2) .code-wrapper .src-line-numbers", - "clientWidth" + {"clientWidth": clientWidth}, ) assert-property: ( @@ -40,8 +39,8 @@ assert-property: ( store-value: (offset_y, 4) // First with desktop -assert-position: (".scraped-example .code-wrapper", {"y": 253}) -assert-position: (".scraped-example .code-wrapper .prev", {"y": 253 + |offset_y|}) +assert-position: (".scraped-example .code-wrapper", {"y": 226}) +assert-position: (".scraped-example .code-wrapper .prev", {"y": 226 + |offset_y|}) // Then with mobile set-window-size: (600, 600) 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-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml index 93c71f23f24..ee5598e4b21 100644 --- a/tests/rustdoc-gui/search-result-display.goml +++ b/tests/rustdoc-gui/search-result-display.goml @@ -32,8 +32,8 @@ set-text: ( ) // Then we compare again to confirm the height didn't change. -assert-css: ("#crate-search", {"width": "527px"}) -assert-css: (".search-results-title", {"height": "50px", "width": "640px"}) +assert-size: ("#crate-search", {"width": 527}) +assert-size: (".search-results-title", {"height": 50, "width": 640}) // And we check that the `<select>` isn't bigger than its container (".search-results-title"). assert-css: ("#search", {"width": "640px"}) diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index a44ff9d3e4a..bf1fe7be910 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -10,7 +10,7 @@ wait-for: "#settings" assert-css: ("#settings", {"display": "block"}) // Store the line margin to compare with the settings.html later. -store-css: (setting_line_margin, ".setting-line", "margin") +store-css: (".setting-line", {"margin": setting_line_margin}) // Let's close it by clicking on the same button. click: "#settings-menu" diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 20bf0596f95..0c680bcc9fb 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -121,28 +121,28 @@ define-function: ( call-function: ("check-colors", { "theme": "light", - "color": "rgb(0, 0, 0)", - "color_hover": "rgb(0, 0, 0)", - "background": "rgb(255, 255, 255)", - "background_hover": "rgb(224, 224, 224)", + "color": "black", + "color_hover": "#000", + "background": "#fff", + "background_hover": "#e0e0e0", "background_toggle": "rgba(0, 0, 0, 0)", - "background_toggle_hover": "rgb(224, 224, 224)", + "background_toggle_hover": "#e0e0e0", }) call-function: ("check-colors", { "theme": "dark", - "color": "rgb(221, 221, 221)", - "color_hover": "rgb(221, 221, 221)", - "background": "rgb(51, 51, 51)", - "background_hover": "rgb(68, 68, 68)", + "color": "#ddd", + "color_hover": "#ddd", + "background": "#333", + "background_hover": "#444", "background_toggle": "rgba(0, 0, 0, 0)", - "background_toggle_hover": "rgb(103, 103, 103)", + "background_toggle_hover": "#676767", }) call-function: ("check-colors", { "theme": "ayu", - "color": "rgb(197, 197, 197)", - "color_hover": "rgb(255, 180, 76)", + "color": "#c5c5c5", + "color_hover": "#ffb44c", "background": "rgb(20, 25, 31)", - "background_hover": "rgb(20, 25, 31)", + "background_hover": "#14191f", "background_toggle": "rgba(0, 0, 0, 0)", "background_toggle_hover": "rgba(70, 70, 70, 0.33)", }) diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 3c1ed009a33..574cc629a04 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -152,14 +152,16 @@ assert-property: (".sidebar", {"clientWidth": "200"}) // Checks that all.html and index.html have their sidebar link in the same place. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -store-property: (index_sidebar_width, ".sidebar .location a", "clientWidth") -store-property: (index_sidebar_height, ".sidebar .location a", "clientHeight") -store-property: (index_sidebar_x, ".sidebar .location a", "offsetTop") -store-property: (index_sidebar_y, ".sidebar .location a", "offsetLeft") +store-property: (".sidebar .location a", { + "clientWidth": index_sidebar_width, + "clientHeight": index_sidebar_height, + "offsetTop": index_sidebar_y, + "offsetLeft": index_sidebar_x, +}) go-to: "file://" + |DOC_PATH| + "/test_docs/all.html" assert-property: (".sidebar .location a", { "clientWidth": |index_sidebar_width|, "clientHeight": |index_sidebar_height|, - "offsetTop": |index_sidebar_x|, - "offsetLeft": |index_sidebar_y|, + "offsetTop": |index_sidebar_y|, + "offsetLeft": |index_sidebar_x|, }) diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml index 42f3200e967..5c795928bdc 100644 --- a/tests/rustdoc-gui/source-code-page.goml +++ b/tests/rustdoc-gui/source-code-page.goml @@ -117,9 +117,8 @@ assert-property: ("#source-sidebar details:first-of-type", {"open": "true"}) // Check the sidebar directory entries have a marker and spacing (desktop). store-property: ( - link_height, "#source-sidebar > details:first-of-type.dir-entry[open] > .files > a", - "offsetHeight" + {"offsetHeight": link_height}, ) define-function: ( "check-sidebar-dir-entry", @@ -147,16 +146,10 @@ define-function: ( ) } ) -store-property: ( - source_sidebar_title_height, - "#source-sidebar > .title", - "offsetHeight" -) -store-property: ( - source_sidebar_title_y, - "#source-sidebar > .title", - "offsetTop" -) +store-property: ("#source-sidebar > .title", { + "offsetHeight": source_sidebar_title_height, + "offsetTop": source_sidebar_title_y, +}) call-function: ("check-sidebar-dir-entry", { "x": 0, // border + margin = 6 @@ -182,16 +175,10 @@ assert-property: ("#main-content", {"offsetTop": 76}) // 21 = 76 - 34 - 21 // Check the sidebar directory entries have a marker and spacing (tablet). -store-property: ( - source_sidebar_title_height, - "#source-sidebar > .title", - "offsetHeight" -) -store-property: ( - source_sidebar_title_y, - "#source-sidebar > .title", - "offsetTop" -) +store-property: ("#source-sidebar > .title", { + "offsetHeight": source_sidebar_title_height, + "offsetTop": source_sidebar_title_y, +}) call-function: ("check-sidebar-dir-entry", { "x": 0, "y": |source_sidebar_title_y| + |source_sidebar_title_height| + 6, @@ -202,16 +189,10 @@ set-window-size: (450, 700) assert-css: ("nav.sub", {"flex-direction": "column"}) // Check the sidebar directory entries have a marker and spacing (phone). -store-property: ( - source_sidebar_title_height, - "#source-sidebar > .title", - "offsetHeight" -) -store-property: ( - source_sidebar_title_y, - "#source-sidebar > .title", - "offsetTop" -) +store-property: ("#source-sidebar > .title", { + "offsetHeight": source_sidebar_title_height, + "offsetTop": source_sidebar_title_y, +}) call-function: ("check-sidebar-dir-entry", { "x": 0, "y": |source_sidebar_title_y| + |source_sidebar_title_height| + 6, @@ -219,5 +200,5 @@ call-function: ("check-sidebar-dir-entry", { // Now we check that the logo has a bottom margin so it's not stuck to the search input. assert-css: (".sub-logo-container > img", {"margin-bottom": "8px"}) -store-property: (logo_height, ".sub-logo-container", "clientHeight") +store-property: (".sub-logo-container", {"clientHeight": logo_height}) assert-position: (".search-form", {"y": |logo_height| + 8}) diff --git a/tests/rustdoc-gui/src-font-size.goml b/tests/rustdoc-gui/src-font-size.goml index 790aeba529c..ff30bcdf2a2 100644 --- a/tests/rustdoc-gui/src-font-size.goml +++ b/tests/rustdoc-gui/src-font-size.goml @@ -11,6 +11,6 @@ assert-css: (".impl-items .srclink", {"font-size": "16px", "font-weight": 400}, assert-css: (".impl-items .code-header", {"font-size": "16px", "font-weight": 600}, ALL) // Check that we can click on source link -store-document-property: (url, "URL") +store-document-property: {"URL": url} click: ".impl-items .srclink" assert-document-property-false: {"URL": |url|} diff --git a/tests/rustdoc-gui/struct-fields.goml b/tests/rustdoc-gui/struct-fields.goml index da0467de13a..3c87a4cd654 100644 --- a/tests/rustdoc-gui/struct-fields.goml +++ b/tests/rustdoc-gui/struct-fields.goml @@ -1,5 +1,5 @@ // This test ensures that each field is on its own line (In other words, they have display: block). go-to: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html" -store-property: (first_top, "//*[@id='structfield.first']", "offsetTop") +store-property: ("//*[@id='structfield.first']", {"offsetTop": first_top}) assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| }) diff --git a/tests/rustdoc-gui/type-declation-overflow.goml b/tests/rustdoc-gui/type-declation-overflow.goml index e8e42e4004b..f212781e9b3 100644 --- a/tests/rustdoc-gui/type-declation-overflow.goml +++ b/tests/rustdoc-gui/type-declation-overflow.goml @@ -39,7 +39,7 @@ assert-property: ("pre.item-decl", {"scrollWidth": "950"}) set-window-size: (600, 600) go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" // It shouldn't have an overflow in the topbar either. -store-property: (scrollWidth, ".mobile-topbar h2", "scrollWidth") +store-property: (".mobile-topbar h2", {"scrollWidth": scrollWidth}) assert-property: (".mobile-topbar h2", {"clientWidth": |scrollWidth|}) assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"}) diff --git a/tests/rustdoc-json/impls/impl_item_visibility.rs b/tests/rustdoc-json/impls/impl_item_visibility.rs new file mode 100644 index 00000000000..efa54d91dca --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility.rs @@ -0,0 +1,26 @@ +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// @!has '$.index[*][?(@.docs=="impl Foo priv")]' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs new file mode 100644 index 00000000000..3c6fefc4ca2 --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs @@ -0,0 +1,28 @@ +// compile-flags: --document-hidden-items +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs new file mode 100644 index 00000000000..b98d1e4167c --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs @@ -0,0 +1,27 @@ +// compile-flags: --document-private-items +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' 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/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index cc066447d31..8ede91cf8f4 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -6,8 +6,8 @@ // normalize-stderr-test "note: compiler flags.*\n\n" -> "" // normalize-stderr-test "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" // normalize-stderr-test "thread.*panicked at .*, compiler.*" -> "thread panicked at 'aborting due to `-Z treat-err-as-bug`'" -// normalize-stderr-test "\s*\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test " +\d{1,}: .*\n" -> "" +// normalize-stderr-test " + at .*\n" -> "" // normalize-stderr-test ".*note: Some details are omitted.*\n" -> "" fn wrong() diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr index cfb73a9b919..98c08b9a894 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.stderr +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -6,6 +6,7 @@ LL | fn wrong() thread panicked at 'aborting due to `-Z treat-err-as-bug`' stack backtrace: + error: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md diff --git a/tests/rustdoc/impl-alias-substituted.rs b/tests/rustdoc/impl-alias-substituted.rs new file mode 100644 index 00000000000..82dfffe5f1c --- /dev/null +++ b/tests/rustdoc/impl-alias-substituted.rs @@ -0,0 +1,9 @@ +pub struct Matrix<T, const N: usize, const M: usize>([[T; N]; M]); + +pub type Vector<T, const N: usize> = Matrix<T, N, 1>; + +// @has "impl_alias_substituted/struct.Matrix.html" '//*[@class="impl"]//h3[@class="code-header"]' \ +// "impl<T: Copy> Matrix<T, 3, 1>" +impl<T: Copy> Vector<T, 3> { + pub fn test() {} +} diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc/inherent-projections.rs new file mode 100644 index 00000000000..9bda0acaf83 --- /dev/null +++ b/tests/rustdoc/inherent-projections.rs @@ -0,0 +1,44 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// @has 'inherent_projections/fn.create.html' +// @has - '//pre[@class="rust item-decl"]' "create() -> Owner::Metadata" +// @has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Owner.html#associatedtype.Metadata' +pub fn create() -> Owner::Metadata {} + +pub struct Owner; + +impl Owner { + pub type Metadata = (); +} + +// Make sure we handle bound vars correctly. +// @has 'inherent_projections/type.User.html' '//pre[@class="rust item-decl"]' "for<'a> fn(_: Carrier<'a>::Focus)" +pub type User = for<'a> fn(Carrier<'a>::Focus); + +pub struct Carrier<'a>(&'a ()); + +impl<'a> Carrier<'a> { + pub type Focus = &'a mut i32; +} + +//////////////////////////////////////// + +// FIXME(inherent_associated_types): Below we link to `Proj` but we should link to `Proj-1`. +// The current test checks for the buggy behavior for demonstration purposes. + +// @has 'inherent_projections/type.Test.html' +// @has - '//pre[@class="rust item-decl"]' "Parametrized<i32>" +// @has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Parametrized.html#associatedtype.Proj' +// @!has - '//pre[@class="rust item-decl"]//a[@class="associatedtype"]/@href' 'struct.Parametrized.html#associatedtype.Proj-1' +pub type Test = Parametrized<i32>::Proj; + +pub struct Parametrized<T>(T); + +impl Parametrized<bool> { + pub type Proj = (); +} + +impl Parametrized<i32> { + pub type Proj = String; +} diff --git a/tests/rustdoc/intra-doc/inherent-associated-types.rs b/tests/rustdoc/intra-doc/inherent-associated-types.rs new file mode 100644 index 00000000000..2b28d2ae60b --- /dev/null +++ b/tests/rustdoc/intra-doc/inherent-associated-types.rs @@ -0,0 +1,45 @@ +#![feature(inherent_associated_types)] + +#![allow(incomplete_features)] +#![deny(rustdoc::broken_intra_doc_links)] + +// @has inherent_associated_types/index.html + +// @has - '//a/@href' 'enum.Simple.html#associatedtype.Type' +//! [`Simple::Type`] + +pub enum Simple {} + +impl Simple { + pub type Type = (); +} + +//////////////////////////////////////// + +// @has 'inherent_associated_types/type.Test0.html' '//a/@href' \ +// 'struct.Parametrized.html#associatedtype.Proj' +/// [`Parametrized<bool>::Proj`] +pub type Test0 = (); + +// FIXME(inherent_associated_types): The intra-doc link below should point to `Proj-1` not `Proj`. +// The current test checks for the buggy behavior for demonstration purposes. +// The same bug happens for inherent associated functions and constants (see #85960, #93398). +// +// Further, at some point we should reject the intra-doc link `Parametrized::Proj`. +// It currently links to `Parametrized<bool>::Proj`. + +// @has 'inherent_associated_types/type.Test1.html' +// @has - '//a/@href' 'struct.Parametrized.html#associatedtype.Proj' +// @!has - '//a/@href' 'struct.Parametrized.html#associatedtype.Proj-1' +/// [`Parametrized<i32>::Proj`] +pub type Test1 = (); + +pub struct Parametrized<T>(T); + +impl Parametrized<bool> { + pub type Proj = (); +} + +impl Parametrized<i32> { + pub type Proj = String; +} diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs new file mode 100644 index 00000000000..8e1029a1ca3 --- /dev/null +++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden-2.rs @@ -0,0 +1,31 @@ +#![feature(no_core)] +#![no_core] +#![crate_name = "foo"] + +// @!has 'foo/hidden/index.html' +// FIXME: add missing `@` for the two next tests once issue is fixed! +// To be done in <https://github.com/rust-lang/rust/issues/111249>. +// !has 'foo/hidden/inner/index.html' +// !has 'foo/hidden/inner/trait.Foo.html' +#[doc(hidden)] +pub mod hidden { + pub mod inner { + pub trait Foo { + /// Hello, world! + fn test(); + } + } +} + +// @has 'foo/visible/index.html' +// @has 'foo/visible/trait.Foo.html' +#[doc(inline)] +pub use hidden::inner as visible; + +// @has 'foo/struct.Bar.html' +// @count - '//*[@id="impl-Foo-for-Bar"]' 1 +pub struct Bar; + +impl visible::Foo for Bar { + fn test() {} +} diff --git a/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs b/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs new file mode 100644 index 00000000000..a9ce4a34507 --- /dev/null +++ b/tests/rustdoc/issue-111064-reexport-trait-from-hidden.rs @@ -0,0 +1,21 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/111064>. +// Methods from a re-exported trait inside a `#[doc(hidden)]` item should +// be visible. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// @has - '//*[@id="main-content"]//*[@class="item-name"]/a[@href="trait.Foo.html"]' 'Foo' + +// @has 'foo/trait.Foo.html' +// @has - '//*[@id="main-content"]//*[@class="code-header"]' 'fn test()' + +#[doc(hidden)] +mod hidden { + pub trait Foo { + /// Hello, world! + fn test(); + } +} + +pub use hidden::Foo; diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs new file mode 100644 index 00000000000..9b7688c332c --- /dev/null +++ b/tests/rustdoc/nested-items-issue-111415.rs @@ -0,0 +1,36 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/111415>. +// This test ensures that only impl blocks are documented in bodies. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// Checking there are only three sections. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// Checking that there are only three items. +// @count - '//*[@id="main-content"]//*[@class="item-name"]' 3 +// @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar' +// @has - '//*[@id="main-content"]//a[@href="fn.foo.html"]' 'foo' +// @has - '//*[@id="main-content"]//a[@href="trait.Foo.html"]' 'Foo' + +// Now checking that the `foo` method is visible in `Bar` page. +// @has 'foo/struct.Bar.html' +// @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub fn foo()' +// @has - '//*[@id="method.bar"]/*[@class="code-header"]' 'fn bar()' +pub struct Bar; + +pub trait Foo { + fn bar() {} +} + +pub fn foo() { + pub mod inaccessible {} + pub fn inner() {} + pub const BAR: u32 = 0; + impl Bar { + pub fn foo() {} + } + impl Foo for Bar {} +} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs new file mode 100644 index 00000000000..642b58b0753 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -0,0 +1,49 @@ +// check-fail +// Tests that a doc comment will not preclude a field from being considered a diagnostic argument +// normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +// normalize-stderr-test "diagnostic_builder\.rs:[0-9]+:[0-9]+" -> "diagnostic_builder.rs:LL:CC" + +// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, +// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler +// the test is just ignored on stable and beta: +// ignore-stage1 +// ignore-beta +// ignore-stable + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_errors; +extern crate rustc_fluent_macro; +extern crate rustc_macros; +extern crate rustc_session; +extern crate rustc_span; + +use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_span::Span; + +fluent_messages! { "./example.ftl" } + +struct NotIntoDiagnosticArg; + +#[derive(Diagnostic)] +#[diag(no_crate_example)] +struct Test { + #[primary_span] + span: Span, + /// A doc comment + arg: NotIntoDiagnosticArg, + //~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied +} + +#[derive(Subdiagnostic)] +#[label(no_crate_example)] +struct SubTest { + #[primary_span] + span: Span, + /// A doc comment + arg: NotIntoDiagnosticArg, + //~^ ERROR the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied +} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr new file mode 100644 index 00000000000..e4b8958b4fa --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied + --> $DIR/diagnostic-derive-doc-comment-field.rs:37:10 + | +LL | #[derive(Diagnostic)] + | ---------- required by a bound introduced by this call +... +LL | arg: NotIntoDiagnosticArg, + | ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg` + | + = help: normalized in stderr +note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` + --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC + = note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied + --> $DIR/diagnostic-derive-doc-comment-field.rs:47:10 + | +LL | #[derive(Subdiagnostic)] + | ------------- required by a bound introduced by this call +... +LL | arg: NotIntoDiagnosticArg, + | ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg` + | + = help: normalized in stderr +note: required by a bound in `Diagnostic::set_arg` + --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:964:5 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 80ab03ab24c..39e34d73f9a 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -339,12 +339,12 @@ struct ErrorWithDefaultLabelAttr<'a> { } #[derive(Diagnostic)] -//~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied #[diag(no_crate_example, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, other: Hello, + //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied } #[derive(Diagnostic)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 5e1bea4e38c..801e4b5793c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -641,15 +641,18 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:341:10 + --> $DIR/diagnostic-derive.rs:346:12 | LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` + | ---------- required by a bound introduced by this call +... +LL | other: Hello, + | ^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` | = help: normalized in stderr note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC - = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 84 previous errors diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 1454d6dde6c..a3db2e9ef24 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -40,6 +40,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); let body = bar.body(); + assert_eq!(body.locals.len(), 2); assert_eq!(body.blocks.len(), 1); let block = &body.blocks[0]; assert_eq!(block.statements.len(), 1); @@ -54,6 +55,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); let body = foo_bar.body(); + assert_eq!(body.locals.len(), 7); assert_eq!(body.blocks.len(), 4); let block = &body.blocks[0]; match &block.terminator { @@ -123,7 +125,7 @@ impl Callbacks for SMirCalls { queries: &'tcx Queries<'tcx>, ) -> Compilation { queries.global_ctxt().unwrap().enter(|tcx| { - test_stable_mir(tcx); + rustc_smir::rustc_internal::run(tcx, || test_stable_mir(tcx)); }); // No need to keep going. Compilation::Stop diff --git a/tests/ui/argument-suggestions/issue-97484.stderr b/tests/ui/argument-suggestions/issue-97484.stderr index a86cbbf1802..082564fbc7f 100644 --- a/tests/ui/argument-suggestions/issue-97484.stderr +++ b/tests/ui/argument-suggestions/issue-97484.stderr @@ -16,7 +16,7 @@ LL | fn foo(a: &A, d: D, e: &E, g: G) {} help: consider borrowing here | LL | foo(&&A, B, C, D, &E, F, G); - | ~~ + | + help: remove the extra arguments | LL - foo(&&A, B, C, D, E, F, G); diff --git a/tests/ui/array-slice-vec/slice-mut-2.stderr b/tests/ui/array-slice-vec/slice-mut-2.stderr index 5b040d3e4d3..c33919c41cd 100644 --- a/tests/ui/array-slice-vec/slice-mut-2.stderr +++ b/tests/ui/array-slice-vec/slice-mut-2.stderr @@ -7,7 +7,7 @@ LL | let _ = &mut x[2..4]; help: consider changing this to be a mutable reference | LL | let x: &[isize] = &mut [1, 2, 3, 4, 5]; - | ~~~~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs new file mode 100644 index 00000000000..f41574403d8 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.rs @@ -0,0 +1,10 @@ +// known-bug: #108491 + +// FIXME(inherent_associated_types): This should pass. + +struct Foo { + bar: Self::Bar, +} +impl Foo { + pub type Bar = usize; +} diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr new file mode 100644 index 00000000000..f313c494671 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -0,0 +1,49 @@ +error[E0601]: `main` function not found in crate `cycle_iat_inside_of_adt` + --> $DIR/cycle-iat-inside-of-adt.rs:10:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/cycle-iat-inside-of-adt.rs` + +error[E0391]: cycle detected when computing predicates of `Foo` + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + | +note: ...which requires computing predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ +note: ...which requires computing inferred outlives predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + = note: ...which requires computing the inferred outlives predicates for items in this crate... +note: ...which requires computing type of `Foo::bar`... + --> $DIR/cycle-iat-inside-of-adt.rs:6:5 + | +LL | bar: Self::Bar, + | ^^^^^^^^^^^^^^ +note: ...which requires computing normalized predicates of `Foo`... + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | struct Foo { + | ^^^^^^^^^^ + = note: ...which again requires computing predicates of `Foo`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cycle-iat-inside-of-adt.rs:5:1 + | +LL | / struct Foo { +LL | | bar: Self::Bar, +LL | | } +LL | | impl Foo { +LL | | pub type Bar = usize; +LL | | } + | |_^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0601. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs new file mode 100644 index 00000000000..0c2a38b1173 --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.rs @@ -0,0 +1,16 @@ +// known-bug: unknown + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(inherent_associated_types): This shouldn't lead to a cycle error. + +fn user<T>() where S<T>::P: std::fmt::Debug {} + +struct S<T>; + +impl<T: Copy> S<T> { + type P = (); +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr new file mode 100644 index 00000000000..aaa9a39ea0f --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-where-predicate.stderr @@ -0,0 +1,37 @@ +error[E0391]: cycle detected when computing predicates of `user` + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires computing predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing explicit predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing normalized predicates of `user`... + --> $DIR/cycle-iat-inside-of-where-predicate.rs:8:1 + | +LL | fn user<T>() where S<T>::P: std::fmt::Debug {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires computing predicates of `user`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/cycle-iat-inside-of-where-predicate.rs:3:1 + | +LL | / #![feature(inherent_associated_types)] +LL | | #![allow(incomplete_features)] +LL | | +LL | | // FIXME(inherent_associated_types): This shouldn't lead to a cycle error. +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs deleted file mode 100644 index 53ac79e0561..00000000000 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs +++ /dev/null @@ -1,23 +0,0 @@ -// known-bug: unknown -// failure-status: 101 -// normalize-stderr-test "note: .*\n\n" -> "" -// normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -// rustc-env:RUST_BACKTRACE=0 - -// FIXME: I presume a type variable that couldn't be solved by `resolve_vars_if_possible` -// escapes the InferCtxt snapshot. - -#![feature(inherent_associated_types)] -#![allow(incomplete_features)] - -struct Cont<T>(T); - -impl<T: Copy> Cont<T> { - type Out = Vec<T>; -} - -pub fn weird<T: Copy>(x: T) { - let _: Cont<_>::Out = vec![true]; -} - -fn main() {} diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr deleted file mode 100644 index 1648cfb266b..00000000000 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: the compiler unexpectedly panicked. this is a bug. - -query stack during panic: -#0 [typeck] type-checking `weird` -#1 [used_trait_imports] finding used_trait_imports `weird` -end of query stack diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.rs b/tests/ui/associated-inherent-types/bugs/inference-fail.rs deleted file mode 100644 index a920b412b1a..00000000000 --- a/tests/ui/associated-inherent-types/bugs/inference-fail.rs +++ /dev/null @@ -1,15 +0,0 @@ -// known-bug: unknown - -#![feature(inherent_associated_types)] -#![allow(incomplete_features)] - -struct S<T>(T); - -impl S<()> { - type P = i128; -} - -fn main() { - // We fail to infer `_ == ()` here. - let _: S<_>::P; -} diff --git a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs deleted file mode 100644 index 632dbf3854b..00000000000 --- a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs +++ /dev/null @@ -1,19 +0,0 @@ -// known-bug: unknown -// check-pass - -// We currently don't region-check inherent associated type projections at all. - -#![feature(inherent_associated_types)] -#![allow(incomplete_features, dead_code)] - -struct S<T>(T); - -impl S<&'static ()> { - type T = (); -} - -fn usr<'a>() { - let _: S::<&'a ()>::T; // this should *fail* but it doesn't! -} - -fn main() {} diff --git a/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs new file mode 100644 index 00000000000..c7f66e645bb --- /dev/null +++ b/tests/ui/associated-inherent-types/bugs/wf-check-skipped.rs @@ -0,0 +1,15 @@ +// known-bug: #100041 +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(inherent_associated_types): This should fail. + +struct Foo; + +impl Foo { + type Bar<T> = (); +} + +fn main() -> Foo::Bar::<Vec<[u32]>> {} diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs index f846bfa4168..83be4f43b5e 100644 --- a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs @@ -31,7 +31,7 @@ fn main() { let _: Select<u8>::Projection = (); let _: Choose<NonCopy>::Result = (); - let _: Choose<bool>::Result = vec![true]; + let _: Choose<&str>::Result = vec!["…"]; // regression test for issue #108957 } // Test if we use the correct `ParamEnv` when proving obligations. diff --git a/tests/ui/associated-inherent-types/former-subst-ice.rs b/tests/ui/associated-inherent-types/former-subst-ice.rs new file mode 100644 index 00000000000..48390b9430b --- /dev/null +++ b/tests/ui/associated-inherent-types/former-subst-ice.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Cont<T>(T); + +impl<T: Copy> Cont<T> { + type Out = Vec<T>; +} + +pub fn weird<T: Copy>(x: T) { + let _: Cont<_>::Out = vec![true]; +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr new file mode 100644 index 00000000000..464b59c249f --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.item.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/generic-associated-types-bad.rs:16:10 + | +LL | const _: Ty::Pr<String> = String::new(); + | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `Ty::Pr` + --> $DIR/generic-associated-types-bad.rs:10:16 + | +LL | type Pr<T: Copy> = T; + | ^^^^ required by this bound in `Ty::Pr` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr new file mode 100644 index 00000000000..4f371b24e80 --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.local.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `Vec<()>: Copy` is not satisfied + --> $DIR/generic-associated-types-bad.rs:20:12 + | +LL | let _: Ty::Pr<Vec<()>>; + | ^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<()>` + | +note: required by a bound in `Ty::Pr` + --> $DIR/generic-associated-types-bad.rs:10:16 + | +LL | type Pr<T: Copy> = T; + | ^^^^ required by this bound in `Ty::Pr` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr new file mode 100644 index 00000000000..74ec39424ed --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.region.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/generic-associated-types-bad.rs:25:12 + | +LL | fn user<'a>() { + | -- lifetime `'a` defined here +LL | #[cfg(region)] +LL | let _: Ty::Static<&'a str> = ""; + | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/generic-associated-types-bad.rs b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs new file mode 100644 index 00000000000..e66392a0a94 --- /dev/null +++ b/tests/ui/associated-inherent-types/generic-associated-types-bad.rs @@ -0,0 +1,26 @@ +// revisions: item local region + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +#[derive(Clone, Copy)] +pub enum Ty {} + +impl Ty { + type Pr<T: Copy> = T; + + type Static<Q: 'static> = Q; +} + +#[cfg(item)] +const _: Ty::Pr<String> = String::new(); //[item]~ the trait bound `String: Copy` is not satisfied + +fn main() { + #[cfg(local)] + let _: Ty::Pr<Vec<()>>; //[local]~ ERROR the trait bound `Vec<()>: Copy` is not satisfied +} + +fn user<'a>() { + #[cfg(region)] + let _: Ty::Static<&'a str> = ""; //[region]~ ERROR lifetime may not live long enough +} diff --git a/tests/ui/associated-inherent-types/inference-fail.rs b/tests/ui/associated-inherent-types/inference-fail.rs new file mode 100644 index 00000000000..939a4ff60f2 --- /dev/null +++ b/tests/ui/associated-inherent-types/inference-fail.rs @@ -0,0 +1,11 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T> S<T> { type P = (); } + +fn main() { + // There is no way to infer this type. + let _: S<_>::P = (); //~ ERROR type annotations needed +} diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr index 425691bd6c4..f29144e4aa7 100644 --- a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr +++ b/tests/ui/associated-inherent-types/inference-fail.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/inference-fail.rs:14:14 + --> $DIR/inference-fail.rs:10:12 | -LL | let _: S<_>::P; - | ^ cannot infer type +LL | let _: S<_>::P = (); + | ^^^^^^^ cannot infer type for type parameter `T` error: aborting due to previous error diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs new file mode 100644 index 00000000000..7d6d26003f6 --- /dev/null +++ b/tests/ui/associated-inherent-types/inference.rs @@ -0,0 +1,40 @@ +// Testing inference capabilities. +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![allow(drop_copy)] + +use std::convert::identity; + +struct Container<T>(T); + +impl Container<u32> { + type Sink = (); +} + +impl<Any> Container<Any> { + type Thing = Any; +} + +impl<T> Container<(T, ())> { + type Output = ((), Wrapped<T>); +} + +fn main() { + // Inferred via the Self type of the impl. + let _: Container<_>::Sink; + + // Inferred via the RHS: + + let _: Container<_>::Thing = 0; + + let _: Container<Wrapped<_>>::Thing = Wrapped(false); + + let _: Container<_>::Output = (drop(1), Wrapped("...")); + + let binding: Container<_>::Thing = Default::default(); // unsolved at this point + identity::<String>(binding); // constrained and solved here +} + +struct Wrapped<T>(T); diff --git a/tests/ui/associated-inherent-types/issue-109768.rs b/tests/ui/associated-inherent-types/issue-109768.rs new file mode 100644 index 00000000000..a3ae2e2ab44 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109768.rs @@ -0,0 +1,12 @@ +// incremental + +struct Wrapper<T>(T); + +struct Local<T, U>(T, U); + +impl<T> Local { //~ ERROR missing generics for struct `Local` + type AssocType3 = T; //~ ERROR inherent associated types are unstable + + const WRAPPED_ASSOC_3: Wrapper<Self::AssocType3> = Wrapper(); +} +//~^ ERROR `main` function not found diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr new file mode 100644 index 00000000000..97706d4062a --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -0,0 +1,35 @@ +error[E0601]: `main` function not found in crate `issue_109768` + --> $DIR/issue-109768.rs:11:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/issue-109768.rs` + +error[E0107]: missing generics for struct `Local` + --> $DIR/issue-109768.rs:7:9 + | +LL | impl<T> Local { + | ^^^^^ expected 2 generic arguments + | +note: struct defined here, with 2 generic parameters: `T`, `U` + --> $DIR/issue-109768.rs:5:8 + | +LL | struct Local<T, U>(T, U); + | ^^^^^ - - +help: add missing generic arguments + | +LL | impl<T> Local<T, U> { + | ++++++ + +error[E0658]: inherent associated types are unstable + --> $DIR/issue-109768.rs:8:5 + | +LL | type AssocType3 = T; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information + = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0601, E0658. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs new file mode 100644 index 00000000000..0b5ba7d1fb5 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109789.rs @@ -0,0 +1,22 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Foo<T>(T); + +impl Foo<fn(&'static ())> { + type Assoc = u32; +} + +trait Other {} +impl Other for u32 {} + +// FIXME(inherent_associated_types): Avoid emitting two diagnostics (they only differ in span). +// FIXME(inherent_associated_types): Enhancement: Spruce up the diagnostic by saying something like +// "implementation is not general enough" as is done for traits via +// `try_report_trait_placeholder_mismatch`. + +fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} +//~^ ERROR mismatched types +//~| ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr new file mode 100644 index 00000000000..7af338274a1 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109789.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-109789.rs:18:1 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo<fn(&'static ())>` + found struct `Foo<for<'a> fn(&'a ())>` + +error[E0308]: mismatched types + --> $DIR/issue-109789.rs:18:11 + | +LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo<fn(&'static ())>` + found struct `Foo<for<'a> fn(&'a ())>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/issue-109790.rs b/tests/ui/associated-inherent-types/issue-109790.rs new file mode 100644 index 00000000000..88327f86423 --- /dev/null +++ b/tests/ui/associated-inherent-types/issue-109790.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![deny(single_use_lifetimes)] + +struct Foo<T>(T); + +impl<'a> Foo<fn(&'a ())> { + type Assoc = &'a (); +} + +trait Other {} +impl Other for u32 {} + +fn bar(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/late-bound-regions.rs b/tests/ui/associated-inherent-types/late-bound-regions.rs new file mode 100644 index 00000000000..488a2cda649 --- /dev/null +++ b/tests/ui/associated-inherent-types/late-bound-regions.rs @@ -0,0 +1,25 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Test if we correctly normalize `S<'a>::P` with respect to late-bound regions. + +type Function = for<'a> fn(&'a i32) -> S<'a>::P; + +struct S<'a>(&'a ()); + +trait Inter { + type P; +} + +impl<'a> S<'a> { + type P = &'a i32; +} + +fn ret_ref_local<'e>() -> &'e i32 { + let f: Function = |x| x; + + let local = 0; + f(&local) //~ ERROR cannot return value referencing local variable `local` +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/late-bound-regions.stderr b/tests/ui/associated-inherent-types/late-bound-regions.stderr new file mode 100644 index 00000000000..4706fcca91d --- /dev/null +++ b/tests/ui/associated-inherent-types/late-bound-regions.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return value referencing local variable `local` + --> $DIR/late-bound-regions.rs:22:5 + | +LL | f(&local) + | ^^------^ + | | | + | | `local` is borrowed here + | returns a value referencing data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/associated-inherent-types/normalization-overflow.rs b/tests/ui/associated-inherent-types/normalization-overflow.rs new file mode 100644 index 00000000000..4228238aa7b --- /dev/null +++ b/tests/ui/associated-inherent-types/normalization-overflow.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// FIXME(fmease): I'd prefer to report a cycle error here instead of an overflow one. + +struct T; + +impl T { + type This = Self::This; //~ ERROR overflow evaluating associated type `T::This` +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/normalization-overflow.stderr b/tests/ui/associated-inherent-types/normalization-overflow.stderr new file mode 100644 index 00000000000..16bb64281e3 --- /dev/null +++ b/tests/ui/associated-inherent-types/normalization-overflow.stderr @@ -0,0 +1,8 @@ +error: overflow evaluating associated type `T::This` + --> $DIR/normalization-overflow.rs:9:17 + | +LL | type This = Self::This; + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs new file mode 100644 index 00000000000..a4b372537c7 --- /dev/null +++ b/tests/ui/associated-inherent-types/private-in-public.rs @@ -0,0 +1,26 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] +#![crate_type = "lib"] + +#![deny(private_in_public)] + +pub type PubAlias0 = PubTy::PrivAssocTy; +//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446) +//~| WARNING this was previously accepted +pub type PubAlias1 = PrivTy::PubAssocTy; +//~^ ERROR private type `PrivTy` in public interface (error E0446) +//~| WARNING this was previously accepted +pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; +//~^ ERROR private type `PrivTy` in public interface (error E0446) +//~| WARNING this was previously accepted + +pub struct PubTy; +impl PubTy { + type PrivAssocTy = (); + pub type PubAssocTy<T> = T; +} + +struct PrivTy; +impl PrivTy { + pub type PubAssocTy = (); +} diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr new file mode 100644 index 00000000000..f0a64e96179 --- /dev/null +++ b/tests/ui/associated-inherent-types/private-in-public.stderr @@ -0,0 +1,34 @@ +error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:7:1 + | +LL | pub type PubAlias0 = PubTy::PrivAssocTy; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> +note: the lint level is defined here + --> $DIR/private-in-public.rs:5:9 + | +LL | #![deny(private_in_public)] + | ^^^^^^^^^^^^^^^^^ + +error: private type `PrivTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:10:1 + | +LL | pub type PubAlias1 = PrivTy::PubAssocTy; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + +error: private type `PrivTy` in public interface (error E0446) + --> $DIR/private-in-public.rs:13:1 + | +LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>; + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + +error: aborting due to 3 previous errors + diff --git a/tests/ui/associated-inherent-types/regionck-0.rs b/tests/ui/associated-inherent-types/regionck-0.rs new file mode 100644 index 00000000000..7c94539ace1 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-0.rs @@ -0,0 +1,14 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl S<&'static ()> { + type T = (); +} + +fn user<'a>() { + let _: S::<&'a ()>::T; //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-0.stderr b/tests/ui/associated-inherent-types/regionck-0.stderr new file mode 100644 index 00000000000..3a438ee630e --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-0.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/regionck-0.rs:11:12 + | +LL | fn user<'a>() { + | -- lifetime `'a` defined here +LL | let _: S::<&'a ()>::T; + | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/associated-inherent-types/regionck-1.rs b/tests/ui/associated-inherent-types/regionck-1.rs new file mode 100644 index 00000000000..ec663cd0f77 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-1.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct U; + +impl U { + // Don't imply any bounds here. + + type NoTyOutliv<'a, T> = &'a T; //~ ERROR the parameter type `T` may not live long enough + type NoReOutliv<'a, 'b> = &'a &'b (); //~ ERROR reference has a longer lifetime than the data it references +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-1.stderr b/tests/ui/associated-inherent-types/regionck-1.stderr new file mode 100644 index 00000000000..b17d89ca306 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-1.stderr @@ -0,0 +1,29 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regionck-1.rs:9:30 + | +LL | type NoTyOutliv<'a, T> = &'a T; + | ^^^^^- help: consider adding a where clause: `where T: 'a` + | | + | ...so that the reference type `&'a T` does not outlive the data it points at + +error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references + --> $DIR/regionck-1.rs:10:31 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^^^^^^^^^ + | +note: the pointer is valid for the lifetime `'a` as defined here + --> $DIR/regionck-1.rs:10:21 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^ +note: but the referenced data is only valid for the lifetime `'b` as defined here + --> $DIR/regionck-1.rs:10:25 + | +LL | type NoReOutliv<'a, 'b> = &'a &'b (); + | ^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0309, E0491. +For more information about an error, try `rustc --explain E0309`. diff --git a/tests/ui/associated-inherent-types/regionck-2.rs b/tests/ui/associated-inherent-types/regionck-2.rs new file mode 100644 index 00000000000..7a0b8b08300 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-2.rs @@ -0,0 +1,14 @@ +// Regression test for issue #109299. + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct Lexer<'d>(&'d ()); + +impl Lexer<'static> { + type Cursor = (); +} + +fn test(_: Lexer::Cursor) {} //~ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-inherent-types/regionck-2.stderr b/tests/ui/associated-inherent-types/regionck-2.stderr new file mode 100644 index 00000000000..b0a4ed35d56 --- /dev/null +++ b/tests/ui/associated-inherent-types/regionck-2.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/regionck-2.rs:12:12 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected struct `Lexer<'static>` + found struct `Lexer<'_>` +note: the anonymous lifetime defined here... + --> $DIR/regionck-2.rs:12:12 + | +LL | fn test(_: Lexer::Cursor) {} + | ^^^^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs new file mode 100644 index 00000000000..b32b4288ac9 --- /dev/null +++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs @@ -0,0 +1,26 @@ +// check-pass +// compile-flags: --crate-type=lib + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Bounds on the self type play a major role in the resolution of inherent associated types (*). +// As a result of that, if a type alias contains any then its bounds have to be respected and the +// lint `type_alias_bounds` should not fire. +// +// FIXME(inherent_associated_types): In the current implementation that is. We might move the +// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the +// ParamEnv that early allowing us to ignore bounds on type aliases again. +// Triage this before stabilization. + +#![deny(type_alias_bounds)] + +pub type Alias<T: Bound> = (Source<T>::Assoc,); + + +pub struct Source<T>(T); +pub trait Bound {} + +impl<T: Bound> Source<T> { + pub type Assoc = (); +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs new file mode 100644 index 00000000000..d081c4d5b78 --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T: Copy> S<T> { + type T = T; +} + +fn main() { + let _: S<_>::T = String::new(); //~ ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr new file mode 100644 index 00000000000..ecf30f4cdec --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-inferred-type.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/unsatisfied-bounds-inferred-type.rs:11:12 + | +LL | let _: S<_>::T = String::new(); + | ^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `S<T>::T` + --> $DIR/unsatisfied-bounds-inferred-type.rs:6:9 + | +LL | impl<T: Copy> S<T> { + | ^^^^ required by this bound in `S<T>::T` +LL | type T = T; + | - required by a bound in this associated type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs new file mode 100644 index 00000000000..97bd2c42160 --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.rs @@ -0,0 +1,14 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S<T>(T); + +impl<T> S<T> { + type X = () + where + T: Copy; +} + +fn main() { + let _: S::<String>::X; //~ ERROR the trait bound `String: Copy` is not satisfied +} diff --git a/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr new file mode 100644 index 00000000000..d4968cd05dc --- /dev/null +++ b/tests/ui/associated-inherent-types/unsatisfied-bounds-where-clause-on-assoc-ty.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:13:12 + | +LL | let _: S::<String>::X; + | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `S<T>::X` + --> $DIR/unsatisfied-bounds-where-clause-on-assoc-ty.rs:9:12 + | +LL | type X = () + | - required by a bound in this associated type +LL | where +LL | T: Copy; + | ^^^^ required by this bound in `S<T>::X` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-types-eq-3.stderr b/tests/ui/associated-types/associated-types-eq-3.stderr index 15ce4fc91cb..c3377eed20a 100644 --- a/tests/ui/associated-types/associated-types-eq-3.stderr +++ b/tests/ui/associated-types/associated-types-eq-3.stderr @@ -43,7 +43,7 @@ note: expected this to be `Bar` | LL | type A = usize; | ^^^^^ - = note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>` + = note: required for the cast from `&isize` to `&dyn Foo<A = Bar>` error: aborting due to 3 previous errors diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index a28a0b74e4a..fdec01b95e3 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -4,7 +4,7 @@ error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `i32`, but LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter(); | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | - = note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>` + = note: required for the cast from `&std::vec::IntoIter<u32>` to `&dyn Iterator<Item = u32, Item = i32>` error: aborting due to previous error diff --git a/tests/ui/associated-types/issue-65774-1.stderr b/tests/ui/associated-types/issue-65774-1.stderr index 91b557555d5..9c77a25c432 100644 --- a/tests/ui/associated-types/issue-65774-1.stderr +++ b/tests/ui/associated-types/issue-65774-1.stderr @@ -25,7 +25,7 @@ LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { } | --------- ^^^^^^^^^ ^^^^^^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `&mut T` to the object type `dyn MyDisplay` + = note: required for the cast from `&&mut T` to `&dyn MyDisplay` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/issue-65774-2.stderr b/tests/ui/associated-types/issue-65774-2.stderr index c22302cdc26..ca8a727f0fe 100644 --- a/tests/ui/associated-types/issue-65774-2.stderr +++ b/tests/ui/associated-types/issue-65774-2.stderr @@ -18,7 +18,7 @@ LL | writer.my_write(valref) | ^^^^^^ the trait `MyDisplay` is not implemented for `T` | = help: the trait `MyDisplay` is implemented for `&'a mut T` - = note: required for the cast from `T` to the object type `dyn MyDisplay` + = note: required for the cast from `&mut T` to `&dyn MyDisplay` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr index a6dbb071614..bbd5a822d8d 100644 --- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -35,7 +35,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant LL | let _: &dyn Future<Output = ()> = █ | ^^^^^^ expected `()`, found `u8` | - = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>` + = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to `&dyn Future<Output = ()>` error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:12:43 @@ -51,7 +51,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant LL | let _: &dyn Future<Output = ()> = █ | ^^^^^^ expected `()`, found `u8` | - = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>` + = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to `&dyn Future<Output = ()>` error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:49:44 diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.drop_tracking.stderr index 5c8b7ef1b71..adb7b9bf4bf 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send` + = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr index 5c8b7ef1b71..adb7b9bf4bf 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send` + = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr index 5c8b7ef1b71..adb7b9bf4bf 100644 --- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send` + = note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/async-await/issues/issue-102206.stderr b/tests/ui/async-await/issues/issue-102206.stderr index 750b7a886ef..cd845056805 100644 --- a/tests/ui/async-await/issues/issue-102206.stderr +++ b/tests/ui/async-await/issues/issue-102206.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/issue-102206.rs:6:27 | LL | std::mem::size_of_val(foo()); - | --------------------- ^^^^^ - | | | - | | expected `&_`, found future - | | help: consider borrowing here: `&foo()` + | --------------------- ^^^^^ expected `&_`, found future + | | | arguments to this function are incorrect | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | std::mem::size_of_val(&foo()); + | + error: aborting due to previous error diff --git a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs index 02b105999f5..7375cb6d3a0 100644 --- a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs +++ b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs @@ -4,7 +4,7 @@ async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32) where 'b: 'a { - drop((a, c)); + let _ = (a, c); (b, b) } 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/borrow-raw-address-of-deref-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr index 4cc1d821d0a..cfc86ff0dc1 100644 --- a/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr +++ b/tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr @@ -7,7 +7,7 @@ LL | let q = &raw mut *x; help: consider changing this to be a mutable reference | LL | let x = &mut 0; - | ~~~~~~ + | +++ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer --> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13 @@ -18,7 +18,7 @@ LL | let q = &raw mut *x; help: consider changing this to be a mutable pointer | LL | let x = &mut 0 as *const i32; - | ~~~~~~ + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr index 26f3e2bbdb7..c161e2d95b4 100644 --- a/tests/ui/borrowck/borrowck-access-permissions.stderr +++ b/tests/ui/borrowck/borrowck-access-permissions.stderr @@ -35,7 +35,7 @@ LL | let _y1 = &mut *ref_x; help: consider changing this to be a mutable reference | LL | let ref_x = &mut x; - | ~~~~~~ + | +++ error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer --> $DIR/borrowck-access-permissions.rs:39:23 @@ -46,7 +46,7 @@ LL | let _y1 = &mut *ptr_x; help: consider changing this to be a mutable pointer | LL | let ptr_x : *const _ = &mut x; - | ~~~~~~ + | +++ error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference --> $DIR/borrowck-access-permissions.rs:48:18 @@ -57,7 +57,7 @@ LL | let _y = &mut *foo_ref.f; help: consider changing this to be a mutable reference | LL | let foo_ref = &mut foo; - | ~~~~~~~~ + | +++ error: aborting due to 6 previous errors diff --git a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr index cbacc87a0e8..cf0c4127d82 100644 --- a/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr +++ b/tests/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.stderr @@ -6,8 +6,8 @@ LL | *s.pointer += 1; | help: consider changing this to be a mutable reference | -LL | fn a(s: &mut S<'_>) { - | ~~~~~~~~~~ +LL | fn a(s: &mut S) { + | +++ error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference --> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5 @@ -17,8 +17,8 @@ LL | *s.pointer += 1; | help: consider changing this to be a mutable reference | -LL | fn c(s: &mut &mut S<'_>) { - | ~~~~~~~~~~~~~~~ +LL | fn c(s: &mut &mut S) { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr index dd0817ff233..59ef61b19d5 100644 --- a/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr +++ b/tests/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr @@ -27,8 +27,8 @@ LL | let x: &mut isize = &mut **t0; | help: consider changing this to be a mutable reference | -LL | fn foo4(t0: &mut &mut isize) { - | ~~~~~~~~~~~~~~~ +LL | fn foo4(t0: &mut &mut isize) { + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs index 0229ca37a69..9163c8ed6fb 100644 --- a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs +++ b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs @@ -1,6 +1,7 @@ // Check that closure captures for slice patterns are inferred correctly #![allow(unused_variables)] +#![allow(drop_ref)] // run-pass diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs index dd6708582c1..a88b323e0bf 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs +++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs @@ -1,6 +1,7 @@ // run-pass #![allow(unused_mut)] #![allow(unused_variables)] +#![allow(drop_copy)] // pretty-expanded FIXME #23616 struct A { a: isize, b: Box<isize> } diff --git a/tests/ui/borrowck/borrowck-issue-14498.stderr b/tests/ui/borrowck/borrowck-issue-14498.stderr index 374c5ee3ed2..12d67d536d9 100644 --- a/tests/ui/borrowck/borrowck-issue-14498.stderr +++ b/tests/ui/borrowck/borrowck-issue-14498.stderr @@ -7,7 +7,7 @@ LL | ***p = 2; help: consider changing this to be a mutable reference | LL | let p = &mut y; - | ~~~~~~ + | +++ error[E0506]: cannot assign to `**y` because it is borrowed --> $DIR/borrowck-issue-14498.rs:25:5 diff --git a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr index d9590e446c7..fb3db4e1446 100644 --- a/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr +++ b/tests/ui/borrowck/borrowck-reborrow-from-mut.stderr @@ -111,7 +111,7 @@ LL | let _bar1 = &mut foo.bar1; help: consider changing this to be a mutable reference | LL | fn borrow_mut_from_imm(foo: &mut Foo) { - | ~~~~~~~~ + | +++ error: aborting due to 11 previous errors diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs index 1cf763f66fd..40c6bfeeb43 100644 --- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs +++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(drop_copy)] + struct A { a: isize, b: Box<isize> } fn field_copy_after_field_borrow() { 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/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr index b4bb128cbb4..2985a658fdd 100644 --- a/tests/ui/borrowck/issue-85765.stderr +++ b/tests/ui/borrowck/issue-85765.stderr @@ -18,7 +18,7 @@ LL | *r = 0; help: consider changing this to be a mutable reference | LL | let r = &mut mutvar; - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to `*x`, which is behind a `&` reference --> $DIR/issue-85765.rs:19:5 diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr index d7c602718f1..b39e57d70ec 100644 --- a/tests/ui/borrowck/mutability-errors.stderr +++ b/tests/ui/borrowck/mutability-errors.stderr @@ -7,7 +7,7 @@ LL | *x = (1,); help: consider changing this to be a mutable reference | LL | fn named_ref(x: &mut (i32,)) { - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to `x.0`, which is behind a `&` reference --> $DIR/mutability-errors.rs:10:5 @@ -18,7 +18,7 @@ LL | x.0 = 1; help: consider changing this to be a mutable reference | LL | fn named_ref(x: &mut (i32,)) { - | ~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference --> $DIR/mutability-errors.rs:11:5 @@ -29,7 +29,7 @@ LL | &mut *x; help: consider changing this to be a mutable reference | LL | fn named_ref(x: &mut (i32,)) { - | ~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `&` reference --> $DIR/mutability-errors.rs:12:5 @@ -40,7 +40,7 @@ LL | &mut x.0; help: consider changing this to be a mutable reference | LL | fn named_ref(x: &mut (i32,)) { - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to data in a `&` reference --> $DIR/mutability-errors.rs:16:5 @@ -74,8 +74,8 @@ LL | *x = (1,); | help: consider changing this to be a mutable pointer | -LL | unsafe fn named_ptr(x: *mut (i32,)) { - | ~~~~~~~~~~~ +LL | unsafe fn named_ptr(x: *mut const (i32,)) { + | +++ error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer --> $DIR/mutability-errors.rs:24:5 @@ -85,8 +85,8 @@ LL | (*x).0 = 1; | help: consider changing this to be a mutable pointer | -LL | unsafe fn named_ptr(x: *mut (i32,)) { - | ~~~~~~~~~~~ +LL | unsafe fn named_ptr(x: *mut const (i32,)) { + | +++ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer --> $DIR/mutability-errors.rs:25:5 @@ -96,8 +96,8 @@ LL | &mut *x; | help: consider changing this to be a mutable pointer | -LL | unsafe fn named_ptr(x: *mut (i32,)) { - | ~~~~~~~~~~~ +LL | unsafe fn named_ptr(x: *mut const (i32,)) { + | +++ error[E0596]: cannot borrow `x.0` as mutable, as it is behind a `*const` pointer --> $DIR/mutability-errors.rs:26:5 @@ -107,8 +107,8 @@ LL | &mut (*x).0; | help: consider changing this to be a mutable pointer | -LL | unsafe fn named_ptr(x: *mut (i32,)) { - | ~~~~~~~~~~~ +LL | unsafe fn named_ptr(x: *mut const (i32,)) { + | +++ error[E0594]: cannot assign to data in a `*const` pointer --> $DIR/mutability-errors.rs:30:5 diff --git a/tests/ui/check-cfg/order-independant.names_after.stderr b/tests/ui/check-cfg/order-independant.names_after.stderr new file mode 100644 index 00000000000..91b81428b38 --- /dev/null +++ b/tests/ui/check-cfg/order-independant.names_after.stderr @@ -0,0 +1,19 @@ +warning: unexpected `cfg` condition value + --> $DIR/order-independant.rs:8:7 + | +LL | #[cfg(a)] + | ^- help: specify a config value: `= "b"` + | + = note: expected values for `a` are: `b` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition value + --> $DIR/order-independant.rs:12:7 + | +LL | #[cfg(a = "unk")] + | ^^^^^^^^^ + | + = note: expected values for `a` are: `b` + +warning: 2 warnings emitted + diff --git a/tests/ui/check-cfg/order-independant.names_before.stderr b/tests/ui/check-cfg/order-independant.names_before.stderr new file mode 100644 index 00000000000..91b81428b38 --- /dev/null +++ b/tests/ui/check-cfg/order-independant.names_before.stderr @@ -0,0 +1,19 @@ +warning: unexpected `cfg` condition value + --> $DIR/order-independant.rs:8:7 + | +LL | #[cfg(a)] + | ^- help: specify a config value: `= "b"` + | + = note: expected values for `a` are: `b` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition value + --> $DIR/order-independant.rs:12:7 + | +LL | #[cfg(a = "unk")] + | ^^^^^^^^^ + | + = note: expected values for `a` are: `b` + +warning: 2 warnings emitted + diff --git a/tests/ui/check-cfg/order-independant.rs b/tests/ui/check-cfg/order-independant.rs new file mode 100644 index 00000000000..ce056b8dcd6 --- /dev/null +++ b/tests/ui/check-cfg/order-independant.rs @@ -0,0 +1,16 @@ +// check-pass +// revisions: names_before names_after +// compile-flags: -Z unstable-options +// compile-flags: --check-cfg=names(names_before,names_after) +// [names_before]compile-flags: --check-cfg=names(a) --check-cfg=values(a,"b") +// [names_after]compile-flags: --check-cfg=values(a,"b") --check-cfg=names(a) + +#[cfg(a)] +//~^ WARNING unexpected `cfg` condition value +fn my_cfg() {} + +#[cfg(a = "unk")] +//~^ WARNING unexpected `cfg` condition value +fn my_cfg() {} + +fn main() {} diff --git a/tests/ui/closure_context/issue-26046-fn-mut.stderr b/tests/ui/closure_context/issue-26046-fn-mut.stderr index f744b71c284..e468f6be791 100644 --- a/tests/ui/closure_context/issue-26046-fn-mut.stderr +++ b/tests/ui/closure_context/issue-26046-fn-mut.stderr @@ -9,7 +9,7 @@ LL | num += 1; LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here | - = note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()` + = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]>` to `Box<(dyn Fn() + 'static)>` error: aborting due to previous error diff --git a/tests/ui/closure_context/issue-26046-fn-once.stderr b/tests/ui/closure_context/issue-26046-fn-once.stderr index 34f94f9dca6..41f60327ce0 100644 --- a/tests/ui/closure_context/issue-26046-fn-once.stderr +++ b/tests/ui/closure_context/issue-26046-fn-once.stderr @@ -9,7 +9,7 @@ LL | vec LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here | - = note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec<u8>` + = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]>` to `Box<(dyn Fn() -> Vec<u8> + 'static)>` error: aborting due to previous error diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.rs b/tests/ui/closures/2229_closure_analysis/bad-pattern.rs new file mode 100644 index 00000000000..a7bf9b67d45 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.rs @@ -0,0 +1,23 @@ +// regression test for #108683 +// edition:2021 + +enum Refutable { + A, + B, +} + +fn example(v1: u32, v2: [u32; 4], v3: Refutable) { + const PAT: u32 = 0; + let v4 = &v2[..]; + || { + let 0 = v1; //~ ERROR refutable pattern in local binding + let (0 | 1) = v1; //~ ERROR refutable pattern in local binding + let 1.. = v1; //~ ERROR refutable pattern in local binding + let [0, 0, 0, 0] = v2; //~ ERROR refutable pattern in local binding + let [0] = v4; //~ ERROR refutable pattern in local binding + let Refutable::A = v3; //~ ERROR refutable pattern in local binding + let PAT = v1; //~ ERROR refutable pattern in local binding + }; +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr new file mode 100644 index 00000000000..ca8c2a16d32 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr @@ -0,0 +1,113 @@ +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:13:13 + | +LL | let 0 = v1; + | ^ pattern `1_u32..=u32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `u32` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let 0 = v1 { todo!() }; + | ++ +++++++++++ +help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits + | +LL | let _0 = v1; + | + + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:14:14 + | +LL | let (0 | 1) = v1; + | ^^^^^ pattern `2_u32..=u32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `u32` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let (0 | 1) = v1 { todo!() }; + | ++ +++++++++++ + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:15:13 + | +LL | let 1.. = v1; + | ^^^ pattern `0_u32` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `u32` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let 1.. = v1 { todo!() }; + | ++ +++++++++++ + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:16:13 + | +LL | let [0, 0, 0, 0] = v2; + | ^^^^^^^^^^^^ pattern `[1_u32..=u32::MAX, _, _, _]` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `[u32; 4]` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let [0, 0, 0, 0] = v2 { todo!() }; + | ++ +++++++++++ + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:17:13 + | +LL | let [0] = v4; + | ^^^ patterns `&[]` and `&[_, _, ..]` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `&[u32]` +help: you might want to use `if let` to ignore the variants that aren't matched + | +LL | if let [0] = v4 { todo!() }; + | ++ +++++++++++ + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:18:13 + | +LL | let Refutable::A = v3; + | ^^^^^^^^^^^^ pattern `Refutable::B` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +note: `Refutable` defined here + --> $DIR/bad-pattern.rs:4:6 + | +LL | enum Refutable { + | ^^^^^^^^^ +LL | A, +LL | B, + | - not covered + = note: the matched value is of type `Refutable` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Refutable::A = v3 { todo!() }; + | ++ +++++++++++ + +error[E0005]: refutable pattern in local binding + --> $DIR/bad-pattern.rs:19:13 + | +LL | let PAT = v1; + | ^^^ + | | + | pattern `1_u32..=u32::MAX` not covered + | missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable + | help: introduce a variable instead: `PAT_var` + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `u32` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0005`. diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr index 95f36fc042c..1904faa9598 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr @@ -10,7 +10,7 @@ LL | **ref_mref_x = y; help: consider changing this to be a mutable reference | LL | let ref_mref_x = &mut mref_x; - | ~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference --> $DIR/mut_ref.rs:26:13 diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs index ff5d284614b..bc7295a0826 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs @@ -1,6 +1,7 @@ // run-pass #![warn(rust_2021_incompatible_closure_captures)] +#![allow(drop_ref, drop_copy)] fn main() { if let a = "" { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr index 36a80e694e8..2609e2951ec 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr @@ -1,5 +1,5 @@ warning: irrefutable `if let` pattern - --> $DIR/issue-78720.rs:6:8 + --> $DIR/issue-78720.rs:7:8 | LL | if let a = "" { | ^^^^^^^^^^ diff --git a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs index 033fd6f1775..0f15f664e75 100644 --- a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs +++ b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs @@ -3,6 +3,7 @@ #![allow(unused)] #![allow(dead_code)] +#![allow(drop_ref)] struct Int(i32); struct B<'a>(&'a i32); diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs index 477fdd613f5..a097424a021 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs @@ -1,6 +1,8 @@ // edition:2021 // check-pass + #![feature(rustc_attrs)] +#![allow(drop_ref)] fn main() { let mut x = 1; diff --git a/tests/ui/issues/issue-868.rs b/tests/ui/closures/issue-868.rs index ce0a3c7ca52..ce0a3c7ca52 100644 --- a/tests/ui/issues/issue-868.rs +++ b/tests/ui/closures/issue-868.rs diff --git a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr index 980da536034..b976f70acf7 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr +++ b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x) | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `dyn std::error::Error` + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` error[E0277]: the trait bound `(): std::error::Error` is not satisfied --> $DIR/coerce-issue-49593-box-never-windows.rs:23:49 @@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)` + = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)` error: aborting due to 2 previous errors diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr index 322681b97bc..0d98fa93e5a 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr +++ b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x) | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `dyn std::error::Error` + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` error[E0277]: the trait bound `(): std::error::Error` is not satisfied --> $DIR/coerce-issue-49593-box-never.rs:23:49 @@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)` + = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)` error: aborting due to 2 previous errors diff --git a/tests/ui/coercion/coercion-slice.stderr b/tests/ui/coercion/coercion-slice.stderr index c7b856a57eb..17bbca7a0bd 100644 --- a/tests/ui/coercion/coercion-slice.stderr +++ b/tests/ui/coercion/coercion-slice.stderr @@ -2,11 +2,14 @@ error[E0308]: mismatched types --> $DIR/coercion-slice.rs:4:21 | LL | let _: &[i32] = [0]; - | ------ ^^^ - | | | - | | expected `&[i32]`, found `[{integer}; 1]` - | | help: consider borrowing here: `&[0]` + | ------ ^^^ expected `&[i32]`, found `[{integer}; 1]` + | | | expected due to this + | +help: consider borrowing here + | +LL | let _: &[i32] = &[0]; + | + error: aborting due to previous error diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs index a1b711a3024..87ae83dd966 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -11,6 +11,13 @@ struct S<T> { impl<T: ConstParamTy> ConstParamTy for S<T> {} +#[derive(PartialEq, Eq, ConstParamTy)] +struct D<T> { + field: u8, + gen: T, +} + + fn check<T: ConstParamTy + ?Sized>() {} fn main() { @@ -39,5 +46,8 @@ fn main() { check::<S<u8>>(); check::<S<[&[bool]; 8]>>(); + check::<D<u8>>(); + check::<D<[&[bool]; 8]>>(); + // FIXME: test tuples } diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs index 07fd243737e..74283a37afc 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -10,4 +10,8 @@ struct CantParam(NotParam); impl std::marker::ConstParamTy for CantParam {} //~^ error: the trait `ConstParamTy` cannot be implemented for this type +#[derive(std::marker::ConstParamTy, Eq, PartialEq)] +//~^ error: the trait `ConstParamTy` cannot be implemented for this type +struct CantParamDerive(NotParam); + fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr index c8e065848b1..52b65d6061a 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -7,6 +7,17 @@ LL | LL | impl std::marker::ConstParamTy for CantParam {} | ^^^^^^^^^ -error: aborting due to previous error +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/const_param_ty_impl_bad_field.rs:13:10 + | +LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | struct CantParamDerive(NotParam); + | -------- this field does not implement `ConstParamTy` + | + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index 17ef396164e..37986de481f 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -10,6 +10,10 @@ struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy for CantParam {} //~^ error: the type `CantParam` does not `#[derive(Eq)]` +#[derive(std::marker::ConstParamTy)] +//~^ error: the type `CantParamDerive` does not `#[derive(Eq)]` +struct CantParamDerive(ImplementsConstParamTy); + fn check<T: std::marker::ConstParamTy>() {} fn main() { diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index ca5abf5e254..52701d55914 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -7,6 +7,16 @@ LL | impl std::marker::ConstParamTy for CantParam {} note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL -error: aborting due to previous error +error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs new file mode 100644 index 00000000000..d70377a20c1 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs @@ -0,0 +1,33 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params, structural_match)] + +union Union { + a: u8, +} + +impl PartialEq for Union { + fn eq(&self, other: &Union) -> bool { + true + } +} +impl Eq for Union {} +impl std::marker::StructuralEq for Union {} + +impl std::marker::ConstParamTy for Union {} + +#[derive(std::marker::ConstParamTy)] +//~^ ERROR this trait cannot be derived for unions +union UnionDerive { + a: u8, +} + +impl PartialEq for UnionDerive { + fn eq(&self, other: &UnionDerive) -> bool { + true + } +} +impl Eq for UnionDerive {} +impl std::marker::StructuralEq for UnionDerive {} + + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr new file mode 100644 index 00000000000..29370304605 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr @@ -0,0 +1,8 @@ +error: this trait cannot be derived for unions + --> $DIR/const_param_ty_impl_union.rs:18:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs new file mode 100644 index 00000000000..ffc7f116a94 --- /dev/null +++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs @@ -0,0 +1,13 @@ +trait Trait { + const ASSOC: usize; +} + +fn bar<const N: usize>() {} + +fn foo<T: Trait>() { + bar::<<T as Trait>::ASSOC>(); + //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC` + //~| ERROR: unresolved item provided when a constant was expected +} + +fn main() {} diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr new file mode 100644 index 00000000000..ac009546135 --- /dev/null +++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr @@ -0,0 +1,21 @@ +error[E0575]: expected associated type, found associated constant `Trait::ASSOC` + --> $DIR/assoc_const_as_type_argument.rs:8:11 + | +LL | bar::<<T as Trait>::ASSOC>(); + | ^^^^^^^^^^^^^^^^^^^ not a associated type + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/assoc_const_as_type_argument.rs:8:11 + | +LL | bar::<<T as Trait>::ASSOC>(); + | ^^^^^^^^^^^^^^^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | bar::<{ <T as Trait>::ASSOC }>(); + | + + + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0575, E0747. +For more information about an error, try `rustc --explain E0575`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr b/tests/ui/const-generics/const-arg-in-const-arg.full.stderr deleted file mode 100644 index 463a37d7e3d..00000000000 --- a/tests/ui/const-generics/const-arg-in-const-arg.full.stderr +++ /dev/null @@ -1,163 +0,0 @@ -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:18:23 - | -LL | let _: [u8; faz::<'a>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:21:23 - | -LL | let _: [u8; faz::<'b>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:41:24 - | -LL | let _: Foo<{ faz::<'a>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:44:24 - | -LL | let _: Foo<{ faz::<'b>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:13:12 - | -LL | let _: [u8; foo::<T>()]; - | ^^^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:15:12 - | -LL | let _: [u8; bar::<N>()]; - | ^^^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:36:12 - | -LL | let _: Foo<{ foo::<T>() }>; - | ^^^^^^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:38:12 - | -LL | let _: Foo<{ bar::<N>() }>; - | ^^^^^^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:25:17 - | -LL | let _ = [0; foo::<T>()]; - | ^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); foo::<T>()]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:27:17 - | -LL | let _ = [0; bar::<N>()]; - | ^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); bar::<N>()]:` - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:30:23 - | -LL | let _ = [0; faz::<'a>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:33:23 - | -LL | let _ = [0; faz::<'b>(&())]; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:47:19 - | -LL | let _ = Foo::<{ foo::<T>() }>; - | ^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); { foo::<T>() }]:` - -error: unconstrained generic constant - --> $DIR/const-arg-in-const-arg.rs:49:19 - | -LL | let _ = Foo::<{ bar::<N>() }>; - | ^^^^^^^^^^^^^^ - | - = help: try adding a `where` bound using this expression: `where [(); { bar::<N>() }]:` - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:52:27 - | -LL | let _ = Foo::<{ faz::<'a>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:55:27 - | -LL | let _ = Foo::<{ faz::<'b>(&()) }>; - | ^^ - | -note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 - | -LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } - | ^^ - -error: aborting due to 16 previous errors - -For more information about this error, try `rustc --explain E0794`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index a7bd9c62b0e..f1f22e2342d 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:13:23 + --> $DIR/const-arg-in-const-arg.rs:15:23 | LL | let _: [u8; foo::<T>()]; | ^ cannot perform const operation using `T` @@ -8,7 +8,7 @@ LL | let _: [u8; foo::<T>()]; = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:15:23 + --> $DIR/const-arg-in-const-arg.rs:16:23 | LL | let _: [u8; bar::<N>()]; | ^ cannot perform const operation using `N` @@ -16,44 +16,44 @@ LL | let _: [u8; bar::<N>()]; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:18:23 | LL | let _: [u8; faz::<'a>(&())]; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:20:23 | LL | let _: [u8; baz::<'a>(&())]; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; faz::<'b>(&())]; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/const-arg-in-const-arg.rs:23:23 | LL | let _: [u8; baz::<'b>(&())]; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; bar::<N>()]; | ^ cannot perform const operation using `N` @@ -61,44 +61,44 @@ LL | let _ = [0; bar::<N>()]; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:30:23 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; faz::<'a>(&())]; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:32:23 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; baz::<'a>(&())]; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:33:23 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; faz::<'b>(&())]; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:35:23 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; baz::<'b>(&())]; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:36:24 + --> $DIR/const-arg-in-const-arg.rs:34:24 | LL | let _: Foo<{ foo::<T>() }>; | ^ cannot perform const operation using `T` @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::<T>() }>; = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:38:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ bar::<N>() }>; | ^ cannot perform const operation using `N` @@ -115,44 +115,44 @@ LL | let _: Foo<{ bar::<N>() }>; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:41:24 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:43:24 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:39:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:44:24 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:46:24 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:42:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:47:27 + --> $DIR/const-arg-in-const-arg.rs:43:27 | LL | let _ = Foo::<{ foo::<T>() }>; | ^ cannot perform const operation using `T` @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::<T>() }>; = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ bar::<N>() }>; | ^ cannot perform const operation using `N` @@ -169,44 +169,44 @@ LL | let _ = Foo::<{ bar::<N>() }>; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:52:27 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:54:27 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:48:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:55:27 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:57:27 +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:51:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; - | ^^ + | ^^ cannot perform const operation using `'b` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:15:23 + --> $DIR/const-arg-in-const-arg.rs:16:23 | LL | let _: [u8; bar::<N>()]; | ^ @@ -223,7 +223,7 @@ LL | let _: [u8; faz::<'a>(&())]; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ @@ -235,13 +235,13 @@ LL | let _: [u8; faz::<'b>(&())]; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:38:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ bar::<N>() }>; | ^ @@ -252,25 +252,25 @@ LL | let _: Foo<{ bar::<{ N }>() }>; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:41:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:44:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ @@ -284,7 +284,7 @@ LL | let _ = [0; foo::<T>()]; = note: this may fail depending on what value the parameter takes error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; bar::<N>()]; | ^ @@ -295,31 +295,31 @@ LL | let _ = [0; bar::<{ N }>()]; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ bar::<N>() }>; | ^ @@ -330,30 +330,30 @@ LL | let _ = Foo::<{ bar::<{ N }>() }>; | + + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:52:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:55:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ | note: the late bound lifetime parameter is introduced here - --> $DIR/const-arg-in-const-arg.rs:8:14 + --> $DIR/const-arg-in-const-arg.rs:10:14 | LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: aborting due to 36 previous errors -Some errors have detailed explanations: E0658, E0747, E0794. -For more information about an error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0747, E0794. +For more information about an error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index 44a4f560a24..9eaa54347f1 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -1,4 +1,6 @@ -// revisions: full min +// revisions: min +// we use a single revision because t his shoudl have a `full` revision +// but right now that ICEs and I(@BoxyUwU) could not get stderr normalization to work #![cfg_attr(full, feature(generic_const_exprs))] #![cfg_attr(full, allow(incomplete_features))] @@ -11,50 +13,42 @@ const fn baz<'a>(_: &'a ()) -> usize where &'a (): Sized { 13 } struct Foo<const N: usize>; fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::<T>()]; //[min]~ ERROR generic parameters may not - //[full]~^ ERROR unconstrained generic constant let _: [u8; bar::<N>()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[full]~^^ ERROR unconstrained generic constant - let _: [u8; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _: [u8; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime - let _: [u8; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _: [u8; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime + let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not + let _: [u8; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _: [u8; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not let _ = [0; foo::<T>()]; //[min]~ ERROR constant expression depends on a generic parameter - //[full]~^ ERROR unconstrained generic constant let _ = [0; bar::<N>()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[full]~^^ ERROR unconstrained generic constant - let _ = [0; faz::<'a>(&())]; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _ = [0; baz::<'a>(&())]; //[min]~ ERROR a non-static lifetime - let _ = [0; faz::<'b>(&())]; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _ = [0; baz::<'b>(&())]; //[min]~ ERROR a non-static lifetime + let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not + let _ = [0; faz::<'b>(&())]; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _ = [0; baz::<'b>(&())]; //[min]~ ERROR generic parameters may not let _: Foo<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not - //[full]~^ ERROR unconstrained generic constant let _: Foo<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[full]~^^ ERROR unconstrained generic constant - let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime - let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime + let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not + let _: Foo<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _: Foo<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ foo::<T>() }>; //[min]~ ERROR generic parameters may not - //[full]~^ ERROR unconstrained generic constant let _ = Foo::<{ bar::<N>() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[full]~^^ ERROR unconstrained generic constant - let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR a non-static lifetime - let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime - //~^ ERROR cannot specify lifetime arguments - let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR a non-static lifetime + let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not + let _ = Foo::<{ faz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not + //[min]~^ ERROR cannot specify lifetime arguments + let _ = Foo::<{ baz::<'b>(&()) }>; //[min]~ ERROR generic parameters may not } fn main() {} diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr index 82030731cc1..310ca75fdc9 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr @@ -1,12 +1,11 @@ -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/const-argument-non-static-lifetime.rs:14:17 | LL | let _: &'a (); - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.rs b/tests/ui/const-generics/const-argument-non-static-lifetime.rs index 0357e4ed59f..df2f3b7918c 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.rs +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.rs @@ -11,7 +11,7 @@ fn test<const N: usize>() {} fn wow<'a>() -> &'a () { test::<{ - let _: &'a (); //[min]~ ERROR a non-static lifetime + let _: &'a (); //[min]~ ERROR generic parameters may not be used in const operations 3 }>(); &() diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr index f639e276f46..539d840f0a8 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr @@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]); | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/const-param-type-depends-on-const-param.rs:15:40 | LL | pub struct SelfDependent<const N: [u8; N]>; | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index 24aa405211f..f829526ca1d 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]); | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/const-param-type-depends-on-const-param.rs:15:40 | LL | pub struct SelfDependent<const N: [u8; N]>; | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:11:47 diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 9c5c97befd8..c5160d1c384 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct B<T, const N: T>(PhantomData<[T; N]>); | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error: aborting due to previous error diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr index 32f7dea8263..938fb08b795 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent<T, const X: T>([(); X]); | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error[E0392]: parameter `T` is never used --> $DIR/const-param-type-depends-on-type-param.rs:11:22 diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr index 32f7dea8263..938fb08b795 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Dependent<T, const X: T>([(); X]); | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error[E0392]: parameter `T` is never used --> $DIR/const-param-type-depends-on-type-param.rs:11:22 diff --git a/tests/ui/const-generics/defaults/trait_objects_fail.stderr b/tests/ui/const-generics/defaults/trait_objects_fail.stderr index 0e8334d0338..481d77728b9 100644 --- a/tests/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/tests/ui/const-generics/defaults/trait_objects_fail.stderr @@ -5,7 +5,7 @@ LL | foo(&10_u32); | ^^^^^^^ the trait `Trait` is not implemented for `u32` | = help: the trait `Trait<2>` is implemented for `u32` - = note: required for the cast from `u32` to the object type `dyn Trait` + = note: required for the cast from `&u32` to `&dyn Trait` error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 @@ -14,7 +14,7 @@ LL | bar(&true); | ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | = help: the trait `Traitor<2, 3>` is implemented for `bool` - = note: required for the cast from `bool` to the object type `dyn Traitor<_>` + = note: required for the cast from `&bool` to `&dyn Traitor<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.rs b/tests/ui/const-generics/generic_const_exprs/issue-74713.rs index 0bcb997d96c..205d031d4a3 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-74713.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.rs @@ -1,7 +1,7 @@ fn bug<'a>() where [(); { //~ ERROR mismatched types - let _: &'a (); //~ ERROR a non-static lifetime is not allowed in a `const` + let _: &'a (); //~ ERROR generic parameters may not be used in const operations }]: {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr index e7673df0a02..f0e0a4b9711 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-74713.stderr @@ -1,11 +1,11 @@ -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/issue-74713.rs:4:17 | LL | let _: &'a (); - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0308]: mismatched types --> $DIR/issue-74713.rs:3:10 @@ -18,5 +18,4 @@ LL | | }]: error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs new file mode 100644 index 00000000000..96aeec77c13 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.rs @@ -0,0 +1,12 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn foo() -> [(); { + let a: &'a (); + //~^ ERROR: use of undeclared lifetime name `'a` + 10_usize +}] { + loop {} +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr new file mode 100644 index 00000000000..976f037062d --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/unresolved_lifetimes_error.stderr @@ -0,0 +1,11 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/unresolved_lifetimes_error.rs:5:13 + | +LL | fn foo() -> [(); { + | - help: consider introducing lifetime `'a` here: `<'a>` +LL | let a: &'a (); + | ^^ undeclared lifetime + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/const-generics/issue-46511.rs b/tests/ui/const-generics/issue-46511.rs index 71c50e2f3f7..78baba818ad 100644 --- a/tests/ui/const-generics/issue-46511.rs +++ b/tests/ui/const-generics/issue-46511.rs @@ -2,7 +2,7 @@ struct Foo<'a> //~ ERROR parameter `'a` is never used [E0392] { - _a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR a non-static lifetime is not allowed in a `const` + _a: [u8; std::mem::size_of::<&'a mut u8>()] //~ ERROR generic parameters may not be used in const operations } pub fn main() {} diff --git a/tests/ui/const-generics/issue-46511.stderr b/tests/ui/const-generics/issue-46511.stderr index b21afa56dcb..58c93a1fab4 100644 --- a/tests/ui/const-generics/issue-46511.stderr +++ b/tests/ui/const-generics/issue-46511.stderr @@ -1,11 +1,11 @@ -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/issue-46511.rs:5:35 | LL | _a: [u8; std::mem::size_of::<&'a mut u8>()] - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error[E0392]: parameter `'a` is never used --> $DIR/issue-46511.rs:3:12 @@ -17,5 +17,4 @@ LL | struct Foo<'a> error: aborting due to 2 previous errors -Some errors have detailed explanations: E0392, E0658. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs index cba2e22c460..6cfabb65efb 100644 --- a/tests/ui/const-generics/issues/issue-105821.rs +++ b/tests/ui/const-generics/issues/issue-105821.rs @@ -1,7 +1,7 @@ // check-pass #![allow(incomplete_features)] -#![feature(adt_const_params, const_ptr_read, generic_const_exprs)] +#![feature(adt_const_params, generic_const_exprs)] #![allow(dead_code)] const fn catone<const M: usize>(_a: &[u8; M]) -> [u8; M + 1] diff --git a/tests/ui/const-generics/issues/issue-56445-1.full.stderr b/tests/ui/const-generics/issues/issue-56445-1.full.stderr index 179643a7552..5fc0ec26047 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.full.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.full.stderr @@ -1,11 +1,11 @@ -error[E0771]: use of non-static lifetime `'a` in const generic +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-56445-1.rs:9:26 | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); - | ^^ + | ^^ the type must not depend on the parameter `'a` | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + = note: lifetime parameters may not be used in the type of const parameters error: aborting due to previous error -For more information about this error, try `rustc --explain E0771`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr index 9f880134162..71a7051f25b 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr @@ -1,10 +1,10 @@ -error[E0771]: use of non-static lifetime `'a` in const generic +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-56445-1.rs:9:26 | LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); - | ^^ + | ^^ the type must not depend on the parameter `'a` | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + = note: lifetime parameters may not be used in the type of const parameters error: `&str` is forbidden as the type of a const generic parameter --> $DIR/issue-56445-1.rs:9:25 @@ -17,4 +17,4 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0771`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-56445-1.rs b/tests/ui/const-generics/issues/issue-56445-1.rs index 0741c3796ad..d862bf24aef 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.rs +++ b/tests/ui/const-generics/issues/issue-56445-1.rs @@ -7,7 +7,7 @@ use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); -//~^ ERROR: use of non-static lifetime `'a` in const generic +//~^ ERROR: the type of const parameters must not depend on other generic parameters //[min]~| ERROR: `&str` is forbidden as the type of a const generic parameter impl Bug<'_, ""> {} diff --git a/tests/ui/const-generics/issues/issue-62878.full.stderr b/tests/ui/const-generics/issues/issue-62878.full.stderr index 3a2b291d7ba..c658b5a6e68 100644 --- a/tests/ui/const-generics/issues/issue-62878.full.stderr +++ b/tests/ui/const-generics/issues/issue-62878.full.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo<const N: usize, const A: [u8; N]>() {} | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 5a721720d78..9c0e5179cc4 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo<const N: usize, const A: [u8; N]>() {} | ^ the type must not depend on the parameter `N` + | + = note: const parameters may not be used in the type of const parameters error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/issue-62878.rs:5:33 diff --git a/tests/ui/const-generics/issues/issue-71169.full.stderr b/tests/ui/const-generics/issues/issue-71169.full.stderr index 1f5880f368e..ccdfbbd54cf 100644 --- a/tests/ui/const-generics/issues/issue-71169.full.stderr +++ b/tests/ui/const-generics/issues/issue-71169.full.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} | ^^^ the type must not depend on the parameter `LEN` + | + = note: const parameters may not be used in the type of const parameters error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index 998b16a79e6..ebfb24bec28 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {} | ^^^ the type must not depend on the parameter `LEN` + | + = note: const parameters may not be used in the type of const parameters error: `[u8; LEN]` is forbidden as the type of a const generic parameter --> $DIR/issue-71169.rs:5:38 diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index e17cf96aa3e..962eaf75b98 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { | ^^^^ the type must not depend on the parameter `Args` + | + = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` + | + = note: type parameters may not be used in the type of const parameters error[E0741]: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:14:61 diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index 3950317b370..e1e140071fc 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { | ^^^^ the type must not depend on the parameter `Args` + | + = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` + | + = note: type parameters may not be used in the type of const parameters error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:14:61 diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr index 656aa29e19b..e109459f2be 100644 --- a/tests/ui/const-generics/issues/issue-71611.full.stderr +++ b/tests/ui/const-generics/issues/issue-71611.full.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn func<A, const F: fn(inner: A)>(outer: A) { | ^ the type must not depend on the parameter `A` + | + = note: type parameters may not be used in the type of const parameters error[E0741]: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:5:21 diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index 01a85b745ce..b33d7cf9850 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | fn func<A, const F: fn(inner: A)>(outer: A) { | ^ the type must not depend on the parameter `A` + | + = note: type parameters may not be used in the type of const parameters error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:5:21 diff --git a/tests/ui/const-generics/issues/issue-77357.rs b/tests/ui/const-generics/issues/issue-77357.rs deleted file mode 100644 index 3cb8d3846ab..00000000000 --- a/tests/ui/const-generics/issues/issue-77357.rs +++ /dev/null @@ -1,11 +0,0 @@ -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -trait MyTrait<T> {} - -fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - //~^ ERROR overly complex generic constant - todo!() -} - -fn main() {} diff --git a/tests/ui/const-generics/issues/issue-77357.stderr b/tests/ui/const-generics/issues/issue-77357.stderr deleted file mode 100644 index 68b35a38b0f..00000000000 --- a/tests/ui/const-generics/issues/issue-77357.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: overly complex generic constant - --> $DIR/issue-77357.rs:6:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constants - | - = help: consider moving this anonymous constant into a `const` function - = note: this operation may be supported in the future - -error: aborting due to previous error - diff --git a/tests/ui/const-generics/issues/issue-83993.rs b/tests/ui/const-generics/issues/issue-83993.rs deleted file mode 100644 index f2f05d9526b..00000000000 --- a/tests/ui/const-generics/issues/issue-83993.rs +++ /dev/null @@ -1,14 +0,0 @@ -// check-pass - -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -fn bug<'a>() -where - for<'b> [(); { - let x: &'b (); - 0 - }]: -{} - -fn main() {} diff --git a/tests/ui/const-generics/issues/issue-88997.stderr b/tests/ui/const-generics/issues/issue-88997.stderr index 505ba0da232..b49d52dd0ba 100644 --- a/tests/ui/const-generics/issues/issue-88997.stderr +++ b/tests/ui/const-generics/issues/issue-88997.stderr @@ -3,12 +3,16 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T) | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-88997.rs:8:54 | LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T) | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-90364.stderr b/tests/ui/const-generics/issues/issue-90364.stderr index e85bd136ef6..23424d7b919 100644 --- a/tests/ui/const-generics/issues/issue-90364.stderr +++ b/tests/ui/const-generics/issues/issue-90364.stderr @@ -3,6 +3,8 @@ error[E0770]: the type of const parameters must not depend on other generic para | LL | pub struct Foo<T, const H: T>(T) | ^ the type must not depend on the parameter `T` + | + = note: type parameters may not be used in the type of const parameters error: aborting due to previous error diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.rs b/tests/ui/const-generics/late-bound-vars/in_closure.rs index 5294cc3b5f4..00fb535f048 100644 --- a/tests/ui/const-generics/late-bound-vars/in_closure.rs +++ b/tests/ui/const-generics/late-bound-vars/in_closure.rs @@ -1,4 +1,22 @@ -// run-pass +// failure-status: 101 +// known-bug: unknown +// error-pattern:internal compiler error +// normalize-stderr-test "internal compiler error.*" -> "" +// normalize-stderr-test "DefId\([^)]*\)" -> "..." +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "thread.*panicked.*\n" -> "" +// normalize-stderr-test "stack backtrace:\n" -> "" +// normalize-stderr-test "\s\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details.*\n" -> "" +// normalize-stderr-test "\n\n[ ]*\n" -> "" +// normalize-stderr-test "compiler/.*: projection" -> "projection" +// this should run-pass + #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.stderr b/tests/ui/const-generics/late-bound-vars/in_closure.stderr new file mode 100644 index 00000000000..557fbea2e05 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/in_closure.stderr @@ -0,0 +1,13 @@ +error: query stack during panic: +#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}` +#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}` +#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE +#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` +#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` +#5 [eval_to_valtree] evaluating type-level constant +#6 [typeck] type-checking `test` +#7 [used_trait_imports] finding used_trait_imports `test` +#8 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to previous error + diff --git a/tests/ui/const-generics/late-bound-vars/simple.rs b/tests/ui/const-generics/late-bound-vars/simple.rs index 6da5395ef83..5d19aaf0b95 100644 --- a/tests/ui/const-generics/late-bound-vars/simple.rs +++ b/tests/ui/const-generics/late-bound-vars/simple.rs @@ -1,4 +1,21 @@ -// run-pass +// failure-status: 101 +// known-bug: unknown +// error-pattern:internal compiler error +// normalize-stderr-test "internal compiler error.*" -> "" +// normalize-stderr-test "DefId\([^)]*\)" -> "..." +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "thread.*panicked.*\n" -> "" +// normalize-stderr-test "stack backtrace:\n" -> "" +// normalize-stderr-test "\s\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details.*\n" -> "" +// normalize-stderr-test "\n\n[ ]*\n" -> "" +// normalize-stderr-test "compiler/.*: projection" -> "projection" + #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/simple.stderr b/tests/ui/const-generics/late-bound-vars/simple.stderr new file mode 100644 index 00000000000..c0568f5a5cf --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/simple.stderr @@ -0,0 +1,13 @@ +error: query stack during panic: +#0 [mir_borrowck] borrow-checking `test::{constant#1}` +#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}` +#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE +#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` +#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` +#5 [eval_to_valtree] evaluating type-level constant +#6 [typeck] type-checking `test` +#7 [used_trait_imports] finding used_trait_imports `test` +#8 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to previous error + diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs index 6215b7d936c..86f2bc9c74b 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs +++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs @@ -5,7 +5,7 @@ fn test<const N: usize>() {} fn issue_75323_and_74447_1<'a>() -> &'a () { test::<{ let _: &'a (); 3 },>(); - //~^ ERROR a non-static lifetime is not allowed in a `const` + //~^ ERROR generic parameters may not be used in const operations &() } @@ -19,7 +19,7 @@ fn issue_75323_and_74447_3() { fn issue_73375<'a>() { [(); (|_: &'a u8| (), 0).1]; - //~^ ERROR a non-static lifetime is not allowed in a `const` + //~^ ERROR generic parameters may not be used in const operations } fn main() {} diff --git a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr index 5f641b07095..7726016eb83 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr +++ b/tests/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.stderr @@ -1,21 +1,20 @@ -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/forbid-non-static-lifetimes.rs:7:22 | LL | test::<{ let _: &'a (); 3 },>(); - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/forbid-non-static-lifetimes.rs:21:16 | LL | [(); (|_: &'a u8| (), 0).1]; - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs index 3018439afa7..de710b0e37d 100644 --- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs +++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.rs @@ -2,7 +2,7 @@ struct Foo< 'a, const N: usize = { let x: &'a (); - //~^ ERROR use of non-static lifetime `'a` in const generic + //~^ ERROR generic parameters may not be used in const operations 3 }, >(&'a ()); diff --git a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr index 9d9555d3f64..6b0d18f1989 100644 --- a/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr +++ b/tests/ui/const-generics/outer-lifetime-in-const-generic-default.stderr @@ -1,11 +1,11 @@ -error[E0771]: use of non-static lifetime `'a` in const generic +error: generic parameters may not be used in const operations --> $DIR/outer-lifetime-in-const-generic-default.rs:4:17 | LL | let x: &'a (); - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: aborting due to previous error -For more information about this error, try `rustc --explain E0771`. diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr b/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr new file mode 100644 index 00000000000..2f03b8e1f66 --- /dev/null +++ b/tests/ui/const-generics/variant-discrimiant-no-generics.full.stderr @@ -0,0 +1,34 @@ +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:7:15 + | +LL | Variant = N, + | ^ cannot perform const operation using `N` + | + = note: const parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:12:17 + | +LL | Variant = { N + 1 }, + | ^ cannot perform const operation using `N` + | + = note: const parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:18:37 + | +LL | Variant = { std::mem::size_of::<T>() as isize }, + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:25:17 + | +LL | let a: &'a (); + | ^^ cannot perform const operation using `'a` + | + = note: lifetime parameters may not be used in enum discriminant values + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr b/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr new file mode 100644 index 00000000000..2f03b8e1f66 --- /dev/null +++ b/tests/ui/const-generics/variant-discrimiant-no-generics.min.stderr @@ -0,0 +1,34 @@ +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:7:15 + | +LL | Variant = N, + | ^ cannot perform const operation using `N` + | + = note: const parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:12:17 + | +LL | Variant = { N + 1 }, + | ^ cannot perform const operation using `N` + | + = note: const parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:18:37 + | +LL | Variant = { std::mem::size_of::<T>() as isize }, + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in enum discriminant values + +error: generic parameters may not be used in enum discriminant values + --> $DIR/variant-discrimiant-no-generics.rs:25:17 + | +LL | let a: &'a (); + | ^^ cannot perform const operation using `'a` + | + = note: lifetime parameters may not be used in enum discriminant values + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/variant-discrimiant-no-generics.rs b/tests/ui/const-generics/variant-discrimiant-no-generics.rs new file mode 100644 index 00000000000..e286aa9a613 --- /dev/null +++ b/tests/ui/const-generics/variant-discrimiant-no-generics.rs @@ -0,0 +1,32 @@ +// revisions: full min + +#![cfg_attr(full, feature(generic_const_exprs))] +#![cfg_attr(full, allow(incomplete_features))] + +enum Foo<const N: isize> { + Variant = N, + //~^ ERROR: generic parameters may not be used in enum discriminant values +} + +enum Owo<const N: isize> { + Variant = { N + 1 }, + //~^ ERROR: generic parameters may not be used in enum discriminant values +} + +#[repr(isize)] +enum Bar<T> { + Variant = { std::mem::size_of::<T>() as isize }, + Other(T), //~^ ERROR: generic parameters may not be used in enum discriminant values +} + +#[repr(isize)] +enum UwU<'a> { + Variant = { + let a: &'a (); + //~^ ERROR: generic parameters may not be used in enum discriminant values + 10_isize + }, + Other(&'a ()), +} + +fn main() {} diff --git a/tests/ui/const-ptr/out_of_bounds_read.rs b/tests/ui/const-ptr/out_of_bounds_read.rs index 9dd669180da..a371aa93c5e 100644 --- a/tests/ui/const-ptr/out_of_bounds_read.rs +++ b/tests/ui/const-ptr/out_of_bounds_read.rs @@ -1,7 +1,5 @@ // error-pattern: evaluation of constant value failed -#![feature(const_ptr_read)] - fn main() { use std::ptr; diff --git a/tests/ui/const-ptr/out_of_bounds_read.stderr b/tests/ui/const-ptr/out_of_bounds_read.stderr index 89536f53f08..c5c0a1cdefc 100644 --- a/tests/ui/const-ptr/out_of_bounds_read.stderr +++ b/tests/ui/const-ptr/out_of_bounds_read.stderr @@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::read::<u32>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `_READ` - --> $DIR/out_of_bounds_read.rs:12:33 + --> $DIR/out_of_bounds_read.rs:10:33 | LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) }; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ note: inside `std::ptr::read::<u32>` note: inside `ptr::const_ptr::<impl *const u32>::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `_CONST_READ` - --> $DIR/out_of_bounds_read.rs:13:39 + --> $DIR/out_of_bounds_read.rs:11:39 | LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() }; | ^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ note: inside `std::ptr::read::<u32>` note: inside `ptr::mut_ptr::<impl *mut u32>::read` --> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL note: inside `_MUT_READ` - --> $DIR/out_of_bounds_read.rs:14:37 + --> $DIR/out_of_bounds_read.rs:12:37 | LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 369e4519407..a5d2ea01486 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -3,7 +3,6 @@ // normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" // normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] -#![feature(const_ptr_read)] use std::mem; diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index 080568b51ef..1d19dfff50b 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:16:1 + --> $DIR/ub-ref-ptr.rs:15:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:20:1 + --> $DIR/ub-ref-ptr.rs:19:1 | LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:24:1 + --> $DIR/ub-ref-ptr.rs:23:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:27:1 + --> $DIR/ub-ref-ptr.rs:26:1 | LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:34:1 + --> $DIR/ub-ref-ptr.rs:33:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:37:39 + --> $DIR/ub-ref-ptr.rs:36:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:37:38 + --> $DIR/ub-ref-ptr.rs:36:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:40:86 + --> $DIR/ub-ref-ptr.rs:39:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant used - --> $DIR/ub-ref-ptr.rs:40:85 + --> $DIR/ub-ref-ptr.rs:39:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:43:1 + --> $DIR/ub-ref-ptr.rs:42:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:46:1 + --> $DIR/ub-ref-ptr.rs:45:1 | LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) @@ -104,13 +104,13 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:49:41 + --> $DIR/ub-ref-ptr.rs:48:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:53:1 + --> $DIR/ub-ref-ptr.rs:52:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer @@ -121,13 +121,13 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; } error[E0080]: evaluation of constant value failed - --> $DIR/ub-ref-ptr.rs:55:38 + --> $DIR/ub-ref-ptr.rs:54:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:58:1 + --> $DIR/ub-ref-ptr.rs:57:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer @@ -138,7 +138,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-ref-ptr.rs:60:1 + --> $DIR/ub-ref-ptr.rs:59:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer @@ -158,7 +158,7 @@ note: inside `std::ptr::read::<u32>` note: inside `ptr::const_ptr::<impl *const u32>::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `UNALIGNED_READ` - --> $DIR/ub-ref-ptr.rs:67:5 + --> $DIR/ub-ref-ptr.rs:66:5 | LL | ptr.read(); | ^^^^^^^^^^ 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/const_forget.rs b/tests/ui/consts/const_forget.rs index ec7dde8c9ec..acdd6a54cf4 100644 --- a/tests/ui/consts/const_forget.rs +++ b/tests/ui/consts/const_forget.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(forget_copy)] + use std::mem::forget; const _: () = forget(0i32); diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs index e2f8149883b..6a3c93ce7a6 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -1,7 +1,6 @@ // revisions: no_flag with_flag // [no_flag] check-pass // [with_flag] compile-flags: -Zextra-const-ub-checks -#![feature(const_ptr_read)] use std::mem::transmute; diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index b2a5fd90149..3970baefcb3 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:9:20 + --> $DIR/detect-extra-ub.rs:8:20 | LL | let _x: bool = transmute(3u8); | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:15:21 + --> $DIR/detect-extra-ub.rs:14:21 | LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:21:30 + --> $DIR/detect-extra-ub.rs:20:30 | LL | let _x: (usize, usize) = transmute(x); | ^^^^^^^^^^^^ unable to turn pointer into raw bytes @@ -23,7 +23,7 @@ LL | let _x: (usize, usize) = transmute(x); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:26:20 + --> $DIR/detect-extra-ub.rs:25:20 | LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) diff --git a/tests/ui/consts/issue-104155.rs b/tests/ui/consts/issue-104155.rs index 1cc8f81b0d2..b3821f467b6 100644 --- a/tests/ui/consts/issue-104155.rs +++ b/tests/ui/consts/issue-104155.rs @@ -1,4 +1,7 @@ // check-pass + +#![allow(forget_copy)] + const _: () = core::mem::forget(Box::<u32>::default); const _: () = core::mem::forget(|| Box::<u32>::default()); 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/consts/issue-miri-1910.rs b/tests/ui/consts/issue-miri-1910.rs index 29e0ea95026..3798332dfd7 100644 --- a/tests/ui/consts/issue-miri-1910.rs +++ b/tests/ui/consts/issue-miri-1910.rs @@ -1,6 +1,5 @@ // error-pattern unable to turn pointer into raw bytes // normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC" -#![feature(const_ptr_read)] const C: () = unsafe { let foo = Some(&42 as *const i32); diff --git a/tests/ui/consts/issue-miri-1910.stderr b/tests/ui/consts/issue-miri-1910.stderr index a10eea9de11..fb758d406b5 100644 --- a/tests/ui/consts/issue-miri-1910.stderr +++ b/tests/ui/consts/issue-miri-1910.stderr @@ -10,7 +10,7 @@ note: inside `std::ptr::read::<u8>` note: inside `ptr::const_ptr::<impl *const u8>::read` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `C` - --> $DIR/issue-miri-1910.rs:8:5 + --> $DIR/issue-miri-1910.rs:7:5 | LL | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs index ca5905fab41..8d1d0b4fcdf 100644 --- a/tests/ui/crate-leading-sep.rs +++ b/tests/ui/crate-leading-sep.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(drop_copy)] + fn main() { use ::std::mem; mem::drop(2_usize); diff --git a/tests/ui/custom_test_frameworks/mismatch.stderr b/tests/ui/custom_test_frameworks/mismatch.stderr index 61061ae529d..31b18b2df98 100644 --- a/tests/ui/custom_test_frameworks/mismatch.stderr +++ b/tests/ui/custom_test_frameworks/mismatch.stderr @@ -6,7 +6,7 @@ LL | #[test] LL | fn wrong_kind(){} | ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn` | - = note: required for the cast from `TestDescAndFn` to the object type `dyn Testable` + = note: required for the cast from `&TestDescAndFn` to `&dyn Testable` = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/issues/issue-12511.rs b/tests/ui/cycle-trait/issue-12511.rs index ea83e3fd9dc..ea83e3fd9dc 100644 --- a/tests/ui/issues/issue-12511.rs +++ b/tests/ui/cycle-trait/issue-12511.rs diff --git a/tests/ui/issues/issue-12511.stderr b/tests/ui/cycle-trait/issue-12511.stderr index 558aad10946..558aad10946 100644 --- a/tests/ui/issues/issue-12511.stderr +++ b/tests/ui/cycle-trait/issue-12511.stderr diff --git a/tests/ui/issues/issue-15689-1.rs b/tests/ui/deriving/issue-15689-1.rs index d143926b281..d143926b281 100644 --- a/tests/ui/issues/issue-15689-1.rs +++ b/tests/ui/deriving/issue-15689-1.rs diff --git a/tests/ui/issues/issue-15689-2.rs b/tests/ui/deriving/issue-15689-2.rs index 83dcb1406f8..83dcb1406f8 100644 --- a/tests/ui/issues/issue-15689-2.rs +++ b/tests/ui/deriving/issue-15689-2.rs diff --git a/tests/ui/diagnostic-width/E0271.stderr b/tests/ui/diagnostic-width/E0271.stderr index ed7b6651d01..52f415037d3 100644 --- a/tests/ui/diagnostic-width/E0271.stderr +++ b/tests/ui/diagnostic-width/E0271.stderr @@ -15,8 +15,8 @@ note: expected this to be `Foo` | LL | type Error = E; | ^ - = note: required for the cast from `Result<Result<..., ...>, ...>` to the object type `dyn Future<Error = Foo>` - = note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt' + = note: required for the cast from `Box<Result<..., ...>>` to `Box<(dyn Future<Error = Foo> + 'static)>` + = note: the full name for the source type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt' error: aborting due to previous error diff --git a/tests/ui/did_you_mean/issue-38147-4.stderr b/tests/ui/did_you_mean/issue-38147-4.stderr index d3339989361..43647fa562b 100644 --- a/tests/ui/did_you_mean/issue-38147-4.stderr +++ b/tests/ui/did_you_mean/issue-38147-4.stderr @@ -6,8 +6,8 @@ LL | f.s.push('x'); | help: consider changing this to be a mutable reference | -LL | fn f(x: usize, f: &mut Foo<'_>) { - | ~~~~~~~~~~~~ +LL | fn f(x: usize, f: &mut Foo) { + | +++ error: aborting due to previous error diff --git a/tests/ui/did_you_mean/issue-39544.stderr b/tests/ui/did_you_mean/issue-39544.stderr index 8dc0512a945..8ccb4cbb0c1 100644 --- a/tests/ui/did_you_mean/issue-39544.stderr +++ b/tests/ui/did_you_mean/issue-39544.stderr @@ -40,7 +40,7 @@ LL | let _ = &mut other.x; help: consider changing this to be a mutable reference | LL | fn foo1(&self, other: &mut Z) { - | ~~~~~~ + | +++ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:25:17 @@ -62,7 +62,7 @@ LL | let _ = &mut other.x; help: consider changing this to be a mutable reference | LL | fn foo2<'a>(&'a self, other: &mut Z) { - | ~~~~~~ + | +++ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:30:17 @@ -73,7 +73,7 @@ LL | let _ = &mut self.x; help: consider changing this to be a mutable reference | LL | fn foo3<'a>(self: &'a mut Self, other: &Z) { - | ~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:31:17 @@ -84,7 +84,7 @@ LL | let _ = &mut other.x; help: consider changing this to be a mutable reference | LL | fn foo3<'a>(self: &'a Self, other: &mut Z) { - | ~~~~~~ + | +++ error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference --> $DIR/issue-39544.rs:35:17 @@ -95,7 +95,7 @@ LL | let _ = &mut other.x; help: consider changing this to be a mutable reference | LL | fn foo4(other: &mut Z) { - | ~~~~~~ + | +++ error[E0596]: cannot borrow `z.x` as mutable, as `z` is not declared as mutable --> $DIR/issue-39544.rs:41:13 @@ -117,7 +117,7 @@ LL | let _ = &mut w.x; help: consider changing this to be a mutable reference | LL | pub fn with_arg(z: Z, w: &mut Z) { - | ~~~~~~ + | +++ error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference --> $DIR/issue-39544.rs:48:5 diff --git a/tests/ui/did_you_mean/issue-40823.stderr b/tests/ui/did_you_mean/issue-40823.stderr index aadd698891e..ba94a570256 100644 --- a/tests/ui/did_you_mean/issue-40823.stderr +++ b/tests/ui/did_you_mean/issue-40823.stderr @@ -7,7 +7,7 @@ LL | buf.iter_mut(); help: consider changing this to be a mutable reference | LL | let mut buf = &mut [1, 2, 3, 4]; - | ~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/drop/dropck-eyepatch-manuallydrop.rs b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs new file mode 100644 index 00000000000..ff100cd941f --- /dev/null +++ b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs @@ -0,0 +1,22 @@ +// check-pass +//! This test checks that dropck knows that ManuallyDrop does not drop its field. +#![feature(dropck_eyepatch)] + +use std::mem::ManuallyDrop; + +struct S<T>(ManuallyDrop<T>); + +unsafe impl<#[may_dangle] T> Drop for S<T> { + fn drop(&mut self) {} +} + +struct NonTrivialDrop<'a>(&'a str); +impl<'a> Drop for NonTrivialDrop<'a> { + fn drop(&mut self) {} +} + +fn main() { + let s = String::from("string"); + let _t = S(ManuallyDrop::new(NonTrivialDrop(&s))); + drop(s); +} diff --git a/tests/ui/drop/issue-110682.rs b/tests/ui/drop/issue-110682.rs new file mode 100644 index 00000000000..35f9c7e8d9b --- /dev/null +++ b/tests/ui/drop/issue-110682.rs @@ -0,0 +1,92 @@ +// build-pass +// compile-flags: -Zmir-opt-level=3 + +use std::fmt::Debug; +use std::mem::ManuallyDrop; +use std::ptr; + +pub trait BitRegister {} + +macro_rules! register { + ($($t:ty),+ $(,)?) => { $( + impl BitRegister for $t { + } + )* }; +} + +register!(u8, u16, u32); + +pub trait BitStore: Sized + Debug { + /// The register type that the implementor describes. + type Mem: BitRegister + Into<Self>; +} + +macro_rules! store { + ($($t:ty),+ $(,)?) => { $( + impl BitStore for $t { + type Mem = Self; + } + )+ }; +} + +store!(u8, u16, u32,); + +#[repr(C)] +pub struct BitVec<T> +where + T: BitStore, +{ + /// Region pointer describing the live portion of the owned buffer. + pointer: ptr::NonNull<T>, + /// Allocated capacity, in elements `T`, of the owned buffer. + capacity: usize, +} + +impl<T> BitVec<T> +where + T: BitStore, +{ + pub fn new() -> Self { + let pointer = ptr::NonNull::<T>::new(ptr::null_mut()).unwrap(); + + BitVec { pointer, capacity: 10 } + } + + pub fn clear(&mut self) { + unsafe { + self.set_len(0); + } + } + + #[inline] + pub unsafe fn set_len(&mut self, new_len: usize) {} + + fn with_vec<F, R>(&mut self, func: F) -> R + where + F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R, + { + let cap = self.capacity; + let elts = 10; + let mut vec = ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr::null_mut(), elts, cap) }); + let out = func(&mut vec); + + out + } +} + +impl<T> Drop for BitVec<T> +where + T: BitStore, +{ + #[inline] + fn drop(&mut self) { + // The buffer elements do not have destructors. + self.clear(); + // Run the `Vec` destructor to deällocate the buffer. + self.with_vec(|vec| unsafe { ManuallyDrop::drop(vec) }); + } +} + +fn main() { + let bitvec = BitVec::<u32>::new(); +} diff --git a/tests/ui/issues/issue-979.rs b/tests/ui/drop/issue-979.rs index 57a99b325ad..57a99b325ad 100644 --- a/tests/ui/issues/issue-979.rs +++ b/tests/ui/drop/issue-979.rs diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs index 8fd46ecaf44..659d35db657 100644 --- a/tests/ui/drop/repeat-drop.rs +++ b/tests/ui/drop/repeat-drop.rs @@ -1,6 +1,8 @@ // run-pass // needs-unwind +#![allow(drop_ref, drop_copy)] + static mut CHECK: usize = 0; struct DropChecker(usize); diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr index ff77bd4cef8..2c75518c298 100644 --- a/tests/ui/dst/dst-bad-coerce1.stderr +++ b/tests/ui/dst/dst-bad-coerce1.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &Fat<dyn Bar> = f2; | ^^ the trait `Bar` is not implemented for `Foo` | - = note: required for the cast from `Foo` to the object type `dyn Bar` + = note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>` error[E0308]: mismatched types --> $DIR/dst-bad-coerce1.rs:28:27 @@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &(dyn Bar,) = f2; | ^^ the trait `Bar` is not implemented for `Foo` | - = note: required for the cast from `Foo` to the object type `dyn Bar` + = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)` error: aborting due to 4 previous errors diff --git a/tests/ui/dst/dst-object-from-unsized-type.stderr b/tests/ui/dst/dst-object-from-unsized-type.stderr index e24c96ebed6..d5e464aed4b 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.stderr +++ b/tests/ui/dst/dst-object-from-unsized-type.stderr @@ -6,7 +6,7 @@ LL | fn test1<T: ?Sized + Foo>(t: &T) { LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | - = note: required for the cast from `T` to the object type `dyn Foo` + = note: required for the cast from `&T` to `&dyn Foo` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn test1<T: ?Sized + Foo>(t: &T) { @@ -21,7 +21,7 @@ LL | fn test2<T: ?Sized + Foo>(t: &T) { LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | - = note: required for the cast from `T` to the object type `dyn Foo` + = note: required for the cast from `&T` to `&dyn Foo` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn test2<T: ?Sized + Foo>(t: &T) { @@ -35,7 +35,7 @@ LL | let _: &[&dyn Foo] = &["hi"]; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Foo` + = note: required for the cast from `&'static str` to `&dyn Foo` error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/dst-object-from-unsized-type.rs:23:23 @@ -44,7 +44,7 @@ LL | let _: &dyn Foo = x as &dyn Foo; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: required for the cast from `[u8]` to the object type `dyn Foo` + = note: required for the cast from `&[u8]` to `&dyn Foo` error: aborting due to 4 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/dyn-star/check-size-at-cast-polymorphic-bad.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr index 8726fae79a0..ba42f619a54 100644 --- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.stderr +++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.current.stderr @@ -1,5 +1,5 @@ error[E0277]: `&T` needs to have the same ABI as a pointer - --> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15 + --> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15 | LL | dyn_debug(t); | ^ `&T` needs to be a pointer-like type diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr new file mode 100644 index 00000000000..ba42f619a54 --- /dev/null +++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: `&T` needs to have the same ABI as a pointer + --> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15 + | +LL | dyn_debug(t); + | ^ `&T` needs to be a pointer-like type + | + = help: the trait `PointerLike` is not implemented for `&T` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerLike { + | +++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs index 913c2faacbd..9846f871424 100644 --- a/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs +++ b/tests/ui/dyn-star/check-size-at-cast-polymorphic-bad.rs @@ -1,3 +1,6 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + #![feature(dyn_star)] #![allow(incomplete_features)] diff --git a/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs new file mode 100644 index 00000000000..a2cc10a4b22 --- /dev/null +++ b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs @@ -0,0 +1,7 @@ +#[derive(Default)] +pub enum Foo { + A(u32), + #[default] + B, + C(u32), +} diff --git a/tests/ui/enum-discriminant/discr-foreign.rs b/tests/ui/enum-discriminant/discr-foreign.rs new file mode 100644 index 00000000000..e7123b34452 --- /dev/null +++ b/tests/ui/enum-discriminant/discr-foreign.rs @@ -0,0 +1,11 @@ +// aux-build:discr-foreign-dep.rs +// build-pass + +extern crate discr_foreign_dep; + +fn main() { + match Default::default() { + discr_foreign_dep::Foo::A(_) => {} + _ => {} + } +} 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/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs index ad9fcc25b41..62137c0c8d3 100644 --- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs +++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs @@ -7,7 +7,7 @@ use core::intrinsics::discriminant_value; enum MyWeirdOption<T> { None = 0, Some(T) = std::mem::size_of::<T>(), - //~^ ERROR generic parameters may not be used in const operations + //~^ ERROR generic parameters may not be used in enum discriminant values } fn main() { diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr index e4e10468d53..2cb159ee291 100644 --- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr +++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr @@ -1,11 +1,10 @@ -error: generic parameters may not be used in const operations +error: generic parameters may not be used in enum discriminant values --> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:35 | LL | Some(T) = std::mem::size_of::<T>(), | ^ cannot perform const operation using `T` | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: type parameters may not be used in enum discriminant values error: aborting due to previous error diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs index a0fb788a510..093c57534a4 100644 --- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs +++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs @@ -8,7 +8,7 @@ enum MyWeirdOption<T> { //~^ ERROR parameter `T` is never used None = 0, Some = std::mem::size_of::<T>(), - //~^ ERROR generic parameters may not be used in const operations + //~^ ERROR generic parameters may not be used in enum discriminant values } fn main() { diff --git a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr index 7ea8a39129e..fac3ce07aeb 100644 --- a/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr +++ b/tests/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr @@ -1,11 +1,10 @@ -error: generic parameters may not be used in const operations +error: generic parameters may not be used in enum discriminant values --> $DIR/issue-70453-generics-in-discr-ice.rs:10:32 | LL | Some = std::mem::size_of::<T>(), | ^ cannot perform const operation using `T` | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: type parameters may not be used in enum discriminant values error[E0392]: parameter `T` is never used --> $DIR/issue-70453-generics-in-discr-ice.rs:7:20 diff --git a/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr b/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr index 0a7a631606e..15cd6d30364 100644 --- a/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr +++ b/tests/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr @@ -1,11 +1,10 @@ -error: generic parameters may not be used in const operations +error: generic parameters may not be used in enum discriminant values --> $DIR/issue-70453-polymorphic-ctfe.rs:9:41 | LL | Some(T) = core::mem::size_of::<*mut T>(), | ^ cannot perform const operation using `T` | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: type parameters may not be used in enum discriminant values error: aborting due to previous error diff --git a/tests/ui/issues/issue-1821.rs b/tests/ui/enum/issue-1821.rs index 76ee9c3edb0..76ee9c3edb0 100644 --- a/tests/ui/issues/issue-1821.rs +++ b/tests/ui/enum/issue-1821.rs diff --git a/tests/ui/enum/issue-67945-1.stderr b/tests/ui/enum/issue-67945-1.stderr index 8f1b5b38e4c..878fa322f02 100644 --- a/tests/ui/enum/issue-67945-1.stderr +++ b/tests/ui/enum/issue-67945-1.stderr @@ -1,11 +1,10 @@ -error: generic parameters may not be used in const operations +error: generic parameters may not be used in enum discriminant values --> $DIR/issue-67945-1.rs:3:16 | LL | let x: S = 0; | ^ cannot perform const operation using `S` | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: type parameters may not be used in enum discriminant values error[E0392]: parameter `S` is never used --> $DIR/issue-67945-1.rs:1:10 diff --git a/tests/ui/enum/issue-67945-2.stderr b/tests/ui/enum/issue-67945-2.stderr index 63d3521afe4..f8ec12d470a 100644 --- a/tests/ui/enum/issue-67945-2.stderr +++ b/tests/ui/enum/issue-67945-2.stderr @@ -1,11 +1,10 @@ -error: generic parameters may not be used in const operations +error: generic parameters may not be used in enum discriminant values --> $DIR/issue-67945-2.rs:4:28 | LL | Var = type_ascribe!(0, S), | ^ cannot perform const operation using `S` | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: type parameters may not be used in enum discriminant values error[E0392]: parameter `S` is never used --> $DIR/issue-67945-2.rs:3:10 diff --git a/tests/ui/error-codes/E0389.stderr b/tests/ui/error-codes/E0389.stderr index 51c4c92addf..e4001856c38 100644 --- a/tests/ui/error-codes/E0389.stderr +++ b/tests/ui/error-codes/E0389.stderr @@ -7,7 +7,7 @@ LL | fancy_ref.num = 6; help: consider changing this to be a mutable reference | LL | let fancy_ref = &mut (&mut fancy); - | ~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/error-codes/E0771.rs b/tests/ui/error-codes/E0771.rs index 67e7d106a1f..c0a2e98a7df 100644 --- a/tests/ui/error-codes/E0771.rs +++ b/tests/ui/error-codes/E0771.rs @@ -1,7 +1,7 @@ #![feature(adt_const_params)] //~^ WARN the feature `adt_const_params` is incomplete -fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0771 +fn function_with_str<'a, const STRING: &'a str>() {} //~ ERROR E0770 fn main() { function_with_str::<"Hello, world!">() diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr index b759399a940..9450c61c27b 100644 --- a/tests/ui/error-codes/E0771.stderr +++ b/tests/ui/error-codes/E0771.stderr @@ -1,10 +1,10 @@ -error[E0771]: use of non-static lifetime `'a` in const generic +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/E0771.rs:4:41 | LL | fn function_with_str<'a, const STRING: &'a str>() {} - | ^^ + | ^^ the type must not depend on the parameter `'a` | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + = note: lifetime parameters may not be used in the type of const parameters warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/E0771.rs:1:12 @@ -17,4 +17,4 @@ LL | #![feature(adt_const_params)] error: aborting due to previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0771`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed index 47c4c9f67b6..0bc4feed329 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo { x: isize } diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs index c698de50c75..26ae6698d66 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo { x: isize } diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr index 7f5106eb57e..c7067117349 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -1,5 +1,5 @@ error[E0040]: explicit use of destructor method - --> $DIR/explicit-call-to-supertrait-dtor.rs:19:14 + --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14 | LL | self.drop(); | -----^^^^-- 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/feature-gates/feature-gate-builtin_syntax.rs b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs new file mode 100644 index 00000000000..832bb5a96bc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.rs @@ -0,0 +1,7 @@ +struct Foo { + v: u8, + w: u8, +} +fn main() { + builtin # offset_of(Foo, v); //~ ERROR `builtin #` syntax is unstable +} diff --git a/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr new file mode 100644 index 00000000000..3bc7848f66d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-builtin_syntax.stderr @@ -0,0 +1,12 @@ +error[E0658]: `builtin #` syntax is unstable + --> $DIR/feature-gate-builtin_syntax.rs:6:15 + | +LL | builtin # offset_of(Foo, v); + | ^^^^^^^^^ + | + = note: see issue #110680 <https://github.com/rust-lang/rust/issues/110680> for more information + = help: add `#![feature(builtin_syntax)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs new file mode 100644 index 00000000000..cb265aa7f25 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +#[cfg(overflow_checks)] //~ ERROR `cfg(overflow_checks)` is experimental +pub fn cast(v: i64)->u32{ + todo!() +} diff --git a/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr new file mode 100644 index 00000000000..79aba7945f6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr @@ -0,0 +1,12 @@ +error[E0658]: `cfg(overflow_checks)` is experimental and subject to change + --> $DIR/feature-gate-cfg_overflow_checks.rs:3:7 + | +LL | #[cfg(overflow_checks)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #111466 <https://github.com/rust-lang/rust/issues/111466> for more information + = help: add `#![feature(cfg_overflow_checks)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr index d81eade8e9b..303700c7ab4 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr @@ -31,14 +31,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn ptr(self: Ptr<Self>); | ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on -note: required for `Ptr<{integer}>` to implement `CoerceUnsized<Ptr<dyn Trait>>` - --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:20:40 - | -LL | impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {} - | --------- ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ - | | - | unsatisfied trait bound introduced here - = note: required by cast to type `Ptr<dyn Trait>` + = note: required for the cast from `Ptr<{integer}>` to `Ptr<dyn Trait>` error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs index 0680d234403..dce94c9eab2 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs @@ -13,5 +13,4 @@ fn non_unsafe_pin_new_unchecked<T>(pointer: &mut T) -> Pin<&mut T> { fn main() { let mut self_referential = PhantomPinned; let _: Pin<&mut PhantomPinned> = non_unsafe_pin_new_unchecked(&mut self_referential); - core::mem::forget(self_referential); // move and disable drop glue! } diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index cc316e55f5c..b0dddd3b1e8 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -15,7 +15,7 @@ LL | format!("{:X}", "3"); NonZeroI64 NonZeroI8 NonZeroIsize - and 21 others + and 20 others = note: required for `&str` to implement `UpperHex` note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL diff --git a/tests/ui/issues/issue-3099.rs b/tests/ui/fn/issue-3099.rs index ee75b359388..ee75b359388 100644 --- a/tests/ui/issues/issue-3099.rs +++ b/tests/ui/fn/issue-3099.rs diff --git a/tests/ui/issues/issue-3099.stderr b/tests/ui/fn/issue-3099.stderr index 32ee2e1d207..32ee2e1d207 100644 --- a/tests/ui/issues/issue-3099.stderr +++ b/tests/ui/fn/issue-3099.stderr diff --git a/tests/ui/generator/drop-env.rs b/tests/ui/generator/drop-env.rs index 66dfb8c2c09..cb46953dac3 100644 --- a/tests/ui/generator/drop-env.rs +++ b/tests/ui/generator/drop-env.rs @@ -4,6 +4,7 @@ //[nomiropt]compile-flags: -Z mir-opt-level=0 #![feature(generators, generator_trait)] +#![allow(drop_copy)] use std::ops::Generator; use std::pin::Pin; 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/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr index 06d2d23b9ef..f7b8e198cc4 100644 --- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr +++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr @@ -1,5 +1,5 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -15,7 +15,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `copy::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `©::unsync::Client` which is not `Send` @@ -33,14 +33,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -54,9 +54,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `copy::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `copy::unsend::Client` which is not `Send` @@ -74,14 +74,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -97,7 +97,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `&derived_drop::unsync::Client` which is not `Send` @@ -115,14 +115,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -136,9 +136,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `derived_drop::unsend::Client` which is not `Send` @@ -156,14 +156,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -179,7 +179,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `&significant_drop::unsync::Client` which is not `Send` @@ -197,14 +197,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -218,9 +218,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `significant_drop::unsend::Client` which is not `Send` @@ -238,7 +238,7 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send<T: Send>(_thing: T) {} | ^^^^ required by this bound in `assert_send` diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs index 03b00ac99ad..918d233bf4e 100644 --- a/tests/ui/generator/issue-57017.rs +++ b/tests/ui/generator/issue-57017.rs @@ -5,6 +5,7 @@ // [drop_tracking_mir] build-pass #![feature(generators, negative_impls)] +#![allow(drop_ref, drop_copy)] macro_rules! type_combinations { ( diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs index 17e23f5bcd2..adba800e25a 100644 --- a/tests/ui/generator/non-static-is-unpin.rs +++ b/tests/ui/generator/non-static-is-unpin.rs @@ -3,6 +3,7 @@ // run-pass #![feature(generators, generator_trait)] +#![allow(drop_copy)] use std::marker::{PhantomPinned, Unpin}; diff --git a/tests/ui/generator/resume-arg-size.rs b/tests/ui/generator/resume-arg-size.rs index b93dc54f7a9..19618f8d0aa 100644 --- a/tests/ui/generator/resume-arg-size.rs +++ b/tests/ui/generator/resume-arg-size.rs @@ -1,4 +1,5 @@ #![feature(generators)] +#![allow(drop_copy)] // run-pass 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/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr index 52c6e3eec60..370329b9f83 100644 --- a/tests/ui/generic-associated-types/issue-76535.base.stderr +++ b/tests/ui/generic-associated-types/issue-76535.base.stderr @@ -43,8 +43,7 @@ LL | pub trait SuperTrait { LL | type SubType<'a>: SubTrait where Self: 'a; | ^^^^^^^ ...because it contains the generic associated type `SubType` = help: consider moving `SubType` to another trait - = note: required for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` - = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>` + = note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType = SubStruct<'_>>>` error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr index f1de77bc3c0..ad704f5e9f0 100644 --- a/tests/ui/generic-associated-types/issue-79422.base.stderr +++ b/tests/ui/generic-associated-types/issue-79422.base.stderr @@ -43,8 +43,7 @@ LL | trait MapLike<K, V> { LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` = help: consider moving `VRefCont` to another trait - = note: required for `Box<BTreeMap<u8, u8>>` to implement `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` - = note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>` + = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>` error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr index 04184fce921..14492266cda 100644 --- a/tests/ui/generic-associated-types/issue-79422.extended.stderr +++ b/tests/ui/generic-associated-types/issue-79422.extended.stderr @@ -27,7 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a; | ^^^^^ = note: expected trait object `(dyn RefCont<'_, u8> + 'static)` found reference `&u8` - = note: required for the cast from `BTreeMap<u8, u8>` to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>` + = note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>` error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/issue-88595.rs b/tests/ui/generic-associated-types/issue-88595.rs index 5a40a612972..7de906e7ef3 100644 --- a/tests/ui/generic-associated-types/issue-88595.rs +++ b/tests/ui/generic-associated-types/issue-88595.rs @@ -19,4 +19,5 @@ impl<'a> A<'a> for C { type B<'b> = impl Clone; fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope + //~^ ERROR: mismatched types } diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr index 79d3479af8c..d6caed85459 100644 --- a/tests/ui/generic-associated-types/issue-88595.stderr +++ b/tests/ui/generic-associated-types/issue-88595.stderr @@ -1,16 +1,34 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-88595.rs:21:35 + --> $DIR/issue-88595.rs:21:5 | LL | fn a(&'a self) -> Self::B<'a> {} - | ^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice | -note: lifetime used multiple times - --> $DIR/issue-88595.rs:18:6 +note: for this opaque type + --> $DIR/issue-88595.rs:19:18 | -LL | impl<'a> A<'a> for C { - | ^^ LL | type B<'b> = impl Clone; - | ^^ + | ^^^^^^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-88595.rs:21:23 + | +LL | type B<'b> = impl Clone; + | ---------- the expected opaque type +LL | +LL | fn a(&'a self) -> Self::B<'a> {} + | - ^^^^^^^^^^^ expected opaque type, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected opaque type `<C as A<'a>>::B<'a>` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/issue-88595.rs:21:5 + | +LL | fn a(&'a self) -> Self::B<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs index cf65de2bc23..214267372bf 100644 --- a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs +++ b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs @@ -1,6 +1,7 @@ // check-pass #![feature(decl_macro)] +#![allow(drop_copy)] macro mac() { mod m { diff --git a/tests/ui/illegal-ufcs-drop.fixed b/tests/ui/illegal-ufcs-drop.fixed index d73b391be06..8783682dec4 100644 --- a/tests/ui/illegal-ufcs-drop.fixed +++ b/tests/ui/illegal-ufcs-drop.fixed @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo; impl Drop for Foo { diff --git a/tests/ui/illegal-ufcs-drop.rs b/tests/ui/illegal-ufcs-drop.rs index 11411f55494..29774306ec6 100644 --- a/tests/ui/illegal-ufcs-drop.rs +++ b/tests/ui/illegal-ufcs-drop.rs @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo; impl Drop for Foo { diff --git a/tests/ui/illegal-ufcs-drop.stderr b/tests/ui/illegal-ufcs-drop.stderr index 91f47d5e456..7a5c0612c07 100644 --- a/tests/ui/illegal-ufcs-drop.stderr +++ b/tests/ui/illegal-ufcs-drop.stderr @@ -1,5 +1,5 @@ error[E0040]: explicit use of destructor method - --> $DIR/illegal-ufcs-drop.rs:9:5 + --> $DIR/illegal-ufcs-drop.rs:12:5 | LL | Drop::drop(&mut Foo) | ^^^^^^^^^^ 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/in-assoc-type-unconstrained.rs b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs new file mode 100644 index 00000000000..c395b4195a0 --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs @@ -0,0 +1,27 @@ +#![feature(impl_trait_in_assoc_type)] + +mod compare_ty { + trait Trait { + type Ty: IntoIterator<Item = ()>; + } + impl Trait for () { + type Ty = Option<impl Sized>; + //~^ ERROR: unconstrained opaque type + //~| ERROR: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()` + } +} + +mod compare_method { + trait Trait { + type Ty; + fn method() -> Self::Ty; + } + impl Trait for () { + type Ty = impl Sized; + //~^ ERROR: unconstrained opaque type + fn method() -> () {} + //~^ ERROR: method `method` has an incompatible type for trait + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr new file mode 100644 index 00000000000..1097cd0f452 --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -0,0 +1,59 @@ +error[E0271]: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()` + --> $DIR/in-assoc-type-unconstrained.rs:8:19 + | +LL | type Ty = Option<impl Sized>; + | ^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type + | + = note: expected unit type `()` + found opaque type `<() as compare_ty::Trait>::Ty::{opaque#0}` +note: required by a bound in `compare_ty::Trait::Ty` + --> $DIR/in-assoc-type-unconstrained.rs:5:31 + | +LL | type Ty: IntoIterator<Item = ()>; + | ^^^^^^^^^ required by this bound in `Trait::Ty` + +error: unconstrained opaque type + --> $DIR/in-assoc-type-unconstrained.rs:8:26 + | +LL | type Ty = Option<impl Sized>; + | ^^^^^^^^^^ + | + = note: `Ty` must be used in combination with a concrete type within the same impl + +error[E0053]: method `method` has an incompatible type for trait + --> $DIR/in-assoc-type-unconstrained.rs:22:24 + | +LL | type Ty = impl Sized; + | ---------- the expected opaque type +LL | +LL | fn method() -> () {} + | ^^ + | | + | expected opaque type, found `()` + | help: change the output type to match the trait: `<() as compare_method::Trait>::Ty` + | +note: type in trait + --> $DIR/in-assoc-type-unconstrained.rs:17:24 + | +LL | fn method() -> Self::Ty; + | ^^^^^^^^ + = note: expected signature `fn() -> <() as compare_method::Trait>::Ty` + found signature `fn()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/in-assoc-type-unconstrained.rs:22:9 + | +LL | fn method() -> () {} + | ^^^^^^^^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/in-assoc-type-unconstrained.rs:20:19 + | +LL | type Ty = impl Sized; + | ^^^^^^^^^^ + | + = note: `Ty` must be used in combination with a concrete type within the same impl + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0053, E0271. +For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-assoc-type.rs b/tests/ui/impl-trait/in-assoc-type.rs new file mode 100644 index 00000000000..36c54bdd6de --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type.rs @@ -0,0 +1,21 @@ +#![feature(impl_trait_in_assoc_type)] + +trait Foo<T> { + type Bar; + fn foo(&self) -> <Self as Foo<()>>::Bar + where + Self: Foo<()>; +} + +impl Foo<()> for () { + type Bar = impl std::fmt::Debug; + fn foo(&self) -> Self::Bar {} +} + +impl Foo<i32> for () { + type Bar = u32; + fn foo(&self) -> <Self as Foo<()>>::Bar {} + //~^ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr new file mode 100644 index 00000000000..f0a272dc2d5 --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/in-assoc-type.rs:17:22 + | +LL | type Bar = impl std::fmt::Debug; + | -------------------- the expected opaque type +... +LL | fn foo(&self) -> <Self as Foo<()>>::Bar {} + | --- ^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected opaque type `<() as Foo<()>>::Bar` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/in-assoc-type.rs:17:5 + | +LL | fn foo(&self) -> <Self as Foo<()>>::Bar {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/object-safety.current.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr index b7f2b019a77..2c340a02319 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.current.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr @@ -42,8 +42,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait - = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>` - = note: required by cast to type `Box<dyn Foo>` + = note: required for the cast from `Box<u32>` to `Box<dyn Foo>` error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr index b7f2b019a77..2c340a02319 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.next.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr @@ -42,8 +42,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait - = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>` - = note: required by cast to type `Box<dyn Foo>` + = note: required for the cast from `Box<u32>` to `Box<dyn Foo>` error: aborting due to 3 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/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index f7aff419544..fe62a8f3288 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -43,6 +43,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | = note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _` found signature `fn(&b::Bar, &(b::Bar, i32)) -> _` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9 + | +LL | fn eq(&self, _other: &(Bar, i32)) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 6f5aacacfc1..c58aab42269 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -98,19 +98,23 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:40:17 | LL | let s = S { u }; - | ^ - | | - | expected `&u32`, found integer - | help: consider borrowing here: `u: &u` + | ^ expected `&u32`, found integer + | +help: consider borrowing here + | +LL | let s = S { u: &u }; + | ++++ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:42:20 | LL | let s = S { u: u }; - | ^ - | | - | expected `&u32`, found integer - | help: consider borrowing here: `&u` + | ^ expected `&u32`, found integer + | +help: consider borrowing here + | +LL | let s = S { u: &u }; + | + error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:45:17 diff --git a/tests/ui/issues/issue-71584.rs b/tests/ui/inference/issue-71584.rs index 7bf3ed60ec1..7bf3ed60ec1 100644 --- a/tests/ui/issues/issue-71584.rs +++ b/tests/ui/inference/issue-71584.rs diff --git a/tests/ui/issues/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr index 6ddb7657301..6ddb7657301 100644 --- a/tests/ui/issues/issue-71584.stderr +++ b/tests/ui/inference/issue-71584.stderr 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-11374.stderr b/tests/ui/issues/issue-11374.stderr index 6e1fb1540bb..879dc5b76c5 100644 --- a/tests/ui/issues/issue-11374.stderr +++ b/tests/ui/issues/issue-11374.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-11374.rs:26:15 | LL | c.read_to(v); - | ------- ^ - | | | - | | expected `&mut [u8]`, found `Vec<_>` - | | help: consider mutably borrowing here: `&mut v` + | ------- ^ expected `&mut [u8]`, found `Vec<_>` + | | | arguments to this method are incorrect | = note: expected mutable reference `&mut [u8]` @@ -15,6 +13,10 @@ note: method defined here | LL | pub fn read_to(&mut self, vec: &mut [u8]) { | ^^^^^^^ -------------- +help: consider mutably borrowing here + | +LL | c.read_to(&mut v); + | ++++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-14366.stderr b/tests/ui/issues/issue-14366.stderr index 10a73b245ac..df61aabf00a 100644 --- a/tests/ui/issues/issue-14366.stderr +++ b/tests/ui/issues/issue-14366.stderr @@ -5,8 +5,8 @@ LL | let _x = "test" as &dyn (::std::any::Any); | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Any` -help: consider borrowing the value, since `&str` can be coerced into `dyn Any` + = note: required for the cast from `&'static str` to `&(dyn Any + 'static)` +help: consider borrowing the value, since `&&'static str` can be coerced into `&(dyn Any + 'static)` | LL | let _x = &"test" as &dyn (::std::any::Any); | + diff --git a/tests/ui/issues/issue-17033.stderr b/tests/ui/issues/issue-17033.stderr index f26bee5ff45..3419c079859 100644 --- a/tests/ui/issues/issue-17033.stderr +++ b/tests/ui/issues/issue-17033.stderr @@ -2,11 +2,14 @@ error[E0308]: mismatched types --> $DIR/issue-17033.rs:2:10 | LL | (*p)(()) - | ---- ^^ - | | | - | | expected `&mut ()`, found `()` - | | help: consider mutably borrowing here: `&mut ()` + | ---- ^^ expected `&mut ()`, found `()` + | | | arguments to this function are incorrect + | +help: consider mutably borrowing here + | +LL | (*p)(&mut ()) + | ++++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-18819.stderr b/tests/ui/issues/issue-18819.stderr index 1fc974b609c..40098f9622f 100644 --- a/tests/ui/issues/issue-18819.stderr +++ b/tests/ui/issues/issue-18819.stderr @@ -19,7 +19,7 @@ LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) { help: consider borrowing here | LL | print_x(&X); - | ~~ + | + help: provide the argument | LL | print_x(/* &dyn Foo<Item = bool> */, /* &str */); diff --git a/tests/ui/issues/issue-22034.stderr b/tests/ui/issues/issue-22034.stderr index b32de5b24b9..9833e559cbc 100644 --- a/tests/ui/issues/issue-22034.stderr +++ b/tests/ui/issues/issue-22034.stderr @@ -6,7 +6,7 @@ LL | &mut *(ptr as *mut dyn Fn()) | = help: the trait `Fn<()>` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` - = note: required for the cast from `()` to the object type `dyn Fn()` + = note: required for the cast from `*mut ()` to `*mut dyn Fn()` error: aborting due to previous error diff --git a/tests/ui/issues/issue-22872.stderr b/tests/ui/issues/issue-22872.stderr index 9510197197a..63222d25c01 100644 --- a/tests/ui/issues/issue-22872.stderr +++ b/tests/ui/issues/issue-22872.stderr @@ -13,7 +13,7 @@ LL | impl<'b, P> Wrap<'b> for Wrapper<P> LL | where P: Process<'b>, LL | <P as Process<'b>>::Item: Iterator { | -------- unsatisfied trait bound introduced here - = note: required for the cast from `Wrapper<P>` to the object type `dyn for<'b> Wrap<'b>` + = note: required for the cast from `Box<Wrapper<P>>` to `Box<dyn for<'b> Wrap<'b>>` help: consider further restricting the associated type | LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator { diff --git a/tests/ui/issues/issue-2748-a.rs b/tests/ui/issues/issue-2748-a.rs deleted file mode 100644 index cbb9bcc28ac..00000000000 --- a/tests/ui/issues/issue-2748-a.rs +++ /dev/null @@ -1,17 +0,0 @@ -// build-pass -#![allow(dead_code)] -#![allow(non_snake_case)] - -// pretty-expanded FIXME #23616 - -struct CMap<'a> { - buf: &'a [u8], -} - -fn CMap(buf: &[u8]) -> CMap { - CMap { - buf: buf - } -} - -pub fn main() { } 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/issues/issue-46302.stderr b/tests/ui/issues/issue-46302.stderr index a6f97c3c9af..6e126038cc9 100644 --- a/tests/ui/issues/issue-46302.stderr +++ b/tests/ui/issues/issue-46302.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/issue-46302.rs:3:27 | LL | let u: &str = if true { s[..2] } else { s }; - | ^^^^^^ - | | - | expected `&str`, found `str` - | help: consider borrowing here: `&s[..2]` + | ^^^^^^ expected `&str`, found `str` + | +help: consider borrowing here + | +LL | let u: &str = if true { &s[..2] } else { s }; + | + error: aborting due to previous error diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr index e874ded8ec5..211dd512895 100644 --- a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr +++ b/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42 | LL | light_flows_our_war_of_mocking_words(behold as usize); - | ------------------------------------ ^^^^^^^^^^^^^^^ - | | | - | | expected `&usize`, found `usize` - | | help: consider borrowing here: `&(behold as usize)` + | ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize` + | | | arguments to this function are incorrect | note: function defined here @@ -13,15 +11,17 @@ note: function defined here | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- +help: consider borrowing here + | +LL | light_flows_our_war_of_mocking_words(&(behold as usize)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42 | LL | light_flows_our_war_of_mocking_words(with_tears + 4); - | ------------------------------------ ^^^^^^^^^^^^^^ - | | | - | | expected `&usize`, found `usize` - | | help: consider borrowing here: `&(with_tears + 4)` + | ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize` + | | | arguments to this function are incorrect | note: function defined here @@ -29,6 +29,10 @@ note: function defined here | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- +help: consider borrowing here + | +LL | light_flows_our_war_of_mocking_words(&(with_tears + 4)); + | ++ + error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-51515.rs b/tests/ui/issues/issue-51515.rs index 84e09afac0a..33a9bf85e23 100644 --- a/tests/ui/issues/issue-51515.rs +++ b/tests/ui/issues/issue-51515.rs @@ -1,7 +1,6 @@ fn main() { let foo = &16; //~^ HELP consider changing this to be a mutable reference - //~| SUGGESTION &mut 16 *foo = 32; //~^ ERROR cannot assign to `*foo`, which is behind a `&` reference let bar = foo; diff --git a/tests/ui/issues/issue-51515.stderr b/tests/ui/issues/issue-51515.stderr index 94e5c9f1b83..88b8d210908 100644 --- a/tests/ui/issues/issue-51515.stderr +++ b/tests/ui/issues/issue-51515.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference - --> $DIR/issue-51515.rs:5:5 + --> $DIR/issue-51515.rs:4:5 | LL | *foo = 32; | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written @@ -7,10 +7,10 @@ LL | *foo = 32; help: consider changing this to be a mutable reference | LL | let foo = &mut 16; - | ~~~~~~~ + | +++ error[E0594]: cannot assign to `*bar`, which is behind a `&` reference - --> $DIR/issue-51515.rs:9:5 + --> $DIR/issue-51515.rs:8:5 | LL | *bar = 64; | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr index eff3e6e7849..aa922e2682d 100644 --- a/tests/ui/issues/issue-61106.stderr +++ b/tests/ui/issues/issue-61106.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-61106.rs:3:9 | LL | foo(x.clone()); - | --- ^^^^^^^^^ - | | | - | | expected `&str`, found `String` - | | help: consider borrowing here: `&x` + | --- ^^^^^^^^^ expected `&str`, found `String` + | | | arguments to this function are incorrect | note: function defined here @@ -13,6 +11,10 @@ note: function defined here | LL | fn foo(_: &str) {} | ^^^ ------- +help: consider borrowing here + | +LL | foo(&x.clone()); + | + error: aborting due to previous error diff --git a/tests/ui/issues/issue-61623.stderr b/tests/ui/issues/issue-61623.stderr index 5fcc338557c..bedea3890a3 100644 --- a/tests/ui/issues/issue-61623.stderr +++ b/tests/ui/issues/issue-61623.stderr @@ -7,7 +7,7 @@ LL | f2(|| x.0, f1(x.1)) help: consider changing this to be a mutable reference | LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) { - | ~~~~~~~~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index efb25bf83e1..53c1940491f 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -11,7 +11,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>` + = note: required for the cast from `&S<T>` to `&dyn Gettable<T>` help: consider restricting type parameter `T` | LL | fn f<T: std::marker::Send>(val: T) { @@ -30,7 +30,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>` + = note: required for the cast from `&S<T>` to `&dyn Gettable<T>` help: consider restricting type parameter `T` | LL | fn f<T: std::marker::Copy>(val: T) { @@ -49,7 +49,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>` + = note: required for the cast from `&S<T>` to `&dyn Gettable<T>` help: consider restricting type parameter `T` | LL | fn g<T: std::marker::Send>(val: T) { @@ -68,7 +68,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>` + = note: required for the cast from `&S<T>` to `&dyn Gettable<T>` help: consider restricting type parameter `T` | LL | fn g<T: std::marker::Copy>(val: T) { @@ -88,7 +88,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<String>` to the object type `dyn Gettable<String>` + = note: required for the cast from `Box<S<String>>` to `Box<dyn Gettable<String>>` error[E0277]: the trait bound `Foo: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:43:37 @@ -104,7 +104,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S<Foo>` to the object type `dyn Gettable<Foo>` + = note: required for the cast from `Box<S<Foo>>` to `Box<dyn Gettable<Foo>>` help: consider annotating `Foo` with `#[derive(Copy)]` | LL + #[derive(Copy)] diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 8d45748a6c4..29495176556 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -46,8 +46,7 @@ LL | trait Foo : Copy { | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&Box<{integer}>` to `&dyn Foo` error: aborting due to 3 previous errors diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 2fbb5a98a8d..3e164ebf514 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -32,8 +32,7 @@ LL | trait Foo : Copy { | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&Box<i32>` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&Box<i32>` to `&dyn Foo` error: aborting due to 2 previous errors 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/lifetimes/issue-64173-unused-lifetimes.rs b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs index 8080dd7dc34..3879784d0b0 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs @@ -13,7 +13,7 @@ const fn foo<T>() -> usize { } struct Bar<'a> { //~ ERROR: parameter `'a` is never used - beta: [(); foo::<&'a ()>()], //~ ERROR: a non-static lifetime is not allowed in a `const` + beta: [(); foo::<&'a ()>()], //~ ERROR: generic parameters may not be used in const operations } fn main() {} diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr index a487cbea537..02ca10b2eb6 100644 --- a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr +++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr @@ -1,11 +1,11 @@ -error[E0658]: a non-static lifetime is not allowed in a `const` +error: generic parameters may not be used in const operations --> $DIR/issue-64173-unused-lifetimes.rs:16:23 | LL | beta: [(); foo::<&'a ()>()], - | ^^ + | ^^ cannot perform const operation using `'a` | - = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information - = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable + = note: lifetime parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic `Self` types are currently not permitted in anonymous constants --> $DIR/issue-64173-unused-lifetimes.rs:4:28 @@ -31,5 +31,4 @@ LL | struct Bar<'a> { error: aborting due to 4 previous errors -Some errors have detailed explanations: E0392, E0658. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index 0ae68ad04f7..2f5ba98445b 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -27,7 +27,7 @@ fn d<const C: S>() {} trait Foo<'a> {} struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>; -//~^ ERROR use of non-static lifetime `'a` in const generic +//~^ ERROR the type of const parameters must not depend on other generic parameters //~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 20163d289b1..4994e4dc444 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -9,13 +9,13 @@ help: consider introducing a named lifetime parameter LL | fn d<'a, const C: S<'a>>() {} | +++ ++++ -error[E0771]: use of non-static lifetime `'a` in const generic +error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/unusual-rib-combinations.rs:29:22 | LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>; - | ^^ + | ^^ the type must not depend on the parameter `'a` | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + = note: lifetime parameters may not be used in the type of const parameters error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/unusual-rib-combinations.rs:7:16 @@ -74,5 +74,5 @@ LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0106, E0214, E0308, E0771. +Some errors have detailed explanations: E0106, E0214, E0308, E0770. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/lint/drop_copy.rs b/tests/ui/lint/drop_copy.rs new file mode 100644 index 00000000000..0adcd34505f --- /dev/null +++ b/tests/ui/lint/drop_copy.rs @@ -0,0 +1,79 @@ +// check-pass + +#![warn(drop_copy)] + +use std::mem::drop; +use std::vec::Vec; + +#[derive(Copy, Clone)] +struct SomeStruct; + +struct AnotherStruct { + x: u8, + y: u8, + z: Vec<u8>, +} + +impl Clone for AnotherStruct { + fn clone(&self) -> AnotherStruct { + AnotherStruct { + x: self.x, + y: self.y, + z: self.z.clone(), + } + } +} + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let s3 = &s1; + let mut s4 = s1; + let ref s5 = s1; + + drop(s1); //~ WARN calls to `std::mem::drop` + drop(s2); //~ WARN calls to `std::mem::drop` + drop(s3); //~ WARN calls to `std::mem::drop` + drop(s4); //~ WARN calls to `std::mem::drop` + drop(s5); //~ WARN calls to `std::mem::drop` + + let a1 = AnotherStruct { + x: 255, + y: 0, + z: vec![1, 2, 3], + }; + let a2 = &a1; + let mut a3 = a1.clone(); + let ref a4 = a1; + let a5 = a1.clone(); + + drop(a2); //~ WARN calls to `std::mem::drop` + drop(a3); + drop(a4); //~ WARN calls to `std::mem::drop` + drop(a5); +} + +#[allow(unused)] +#[allow(clippy::unit_cmp)] +fn issue9482(x: u8) { + fn println_and<T>(t: T) -> T { + println!("foo"); + t + } + + match x { + // Don't lint (copy type), we only care about side-effects + 0 => drop(println_and(12)), + // Don't lint (no copy type), we only care about side-effects + 1 => drop(println_and(String::new())), + 2 => { + // Lint, even if we only care about the side-effect, it's already in a block + drop(println_and(13)); //~ WARN calls to `std::mem::drop` + }, + // Lint, idiomatic use is only in body of `Arm` + 3 if drop(println_and(14)) == () => (), //~ WARN calls to `std::mem::drop` + // Lint, not a fn/method call + 4 => drop(2),//~ WARN calls to `std::mem::drop` + _ => (), + } +} diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr new file mode 100644 index 00000000000..db8e89ad295 --- /dev/null +++ b/tests/ui/lint/drop_copy.stderr @@ -0,0 +1,108 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:34:5 + | +LL | drop(s1); + | ^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result +note: the lint level is defined here + --> $DIR/drop_copy.rs:3:9 + | +LL | #![warn(drop_copy)] + | ^^^^^^^^^ + +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:35:5 + | +LL | drop(s2); + | ^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_copy.rs:36:5 + | +LL | drop(s3); + | ^^^^^--^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(drop_ref)]` on by default + +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:37:5 + | +LL | drop(s4); + | ^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_copy.rs:38:5 + | +LL | drop(s5); + | ^^^^^--^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_copy.rs:50:5 + | +LL | drop(a2); + | ^^^^^--^ + | | + | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_copy.rs:52:5 + | +LL | drop(a4); + | ^^^^^--^ + | | + | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:71:13 + | +LL | drop(println_and(13)); + | ^^^^^---------------^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:74:14 + | +LL | 3 if drop(println_and(14)) == () => (), + | ^^^^^---------------^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/drop_copy.rs:76:14 + | +LL | 4 => drop(2), + | ^^^^^-^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: 10 warnings emitted + diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/tests/ui/lint/drop_ref.rs index 10044e65f11..db4f7569f6f 100644 --- a/src/tools/clippy/tests/ui/drop_ref.rs +++ b/tests/ui/lint/drop_ref.rs @@ -1,42 +1,39 @@ -#![warn(clippy::drop_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::map_err_ignore)] -#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)] +// check-pass -use std::mem::drop; +#![warn(drop_ref)] struct SomeStruct; fn main() { - drop(&SomeStruct); + drop(&SomeStruct); //~ WARN calls to `std::mem::drop` let mut owned1 = SomeStruct; - drop(&owned1); - drop(&&owned1); - drop(&mut owned1); - drop(owned1); //OK + drop(&owned1); //~ WARN calls to `std::mem::drop` + drop(&&owned1); //~ WARN calls to `std::mem::drop` + drop(&mut owned1); //~ WARN calls to `std::mem::drop` + drop(owned1); let reference1 = &SomeStruct; - drop(reference1); + drop(reference1); //~ WARN calls to `std::mem::drop` let reference2 = &mut SomeStruct; - drop(reference2); + drop(reference2); //~ WARN calls to `std::mem::drop` let ref reference3 = SomeStruct; - drop(reference3); + drop(reference3); //~ WARN calls to `std::mem::drop` } #[allow(dead_code)] fn test_generic_fn_drop<T>(val: T) { - drop(&val); - drop(val); //OK + drop(&val); //~ WARN calls to `std::mem::drop` + drop(val); } #[allow(dead_code)] fn test_similarly_named_function() { fn drop<T>(_val: T) {} drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::drop(&SomeStruct); + std::mem::drop(&SomeStruct); //~ WARN calls to `std::mem::drop` } #[derive(Copy, Clone)] @@ -77,21 +74,26 @@ fn test_owl_result_2() -> Result<u8, ()> { #[allow(clippy::unit_cmp)] fn issue10122(x: u8) { // This is a function which returns a reference and has a side-effect, which means - // that calling drop() on the function is considered an idiomatic way of achieving the side-effect - // in a match arm. + // that calling drop() on the function is considered an idiomatic way of achieving + // the side-effect in a match arm. fn println_and<T>(t: &T) -> &T { println!("foo"); t } match x { - 0 => drop(println_and(&12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(&String::new())), // Don't lint (no copy type), we only care about side-effects + // Don't lint (copy type), we only care about side-effects + 0 => drop(println_and(&12)), + // Don't lint (no copy type), we only care about side-effects + 1 => drop(println_and(&String::new())), 2 => { - drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block + // Lint, even if we only care about the side-effect, it's already in a block + drop(println_and(&13)); //~ WARN calls to `std::mem::drop` }, - 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(&2), // Lint, not a fn/method call + // Lint, idiomatic use is only in body of `Arm` + 3 if drop(println_and(&14)) == () => (), //~ WARN calls to `std::mem::drop` + // Lint, not a fn/method call + 4 => drop(&2), //~ WARN calls to `std::mem::drop` _ => (), } } diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr new file mode 100644 index 00000000000..04c988fe99d --- /dev/null +++ b/tests/ui/lint/drop_ref.stderr @@ -0,0 +1,127 @@ +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:8:5 + | +LL | drop(&SomeStruct); + | ^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result +note: the lint level is defined here + --> $DIR/drop_ref.rs:3:9 + | +LL | #![warn(drop_ref)] + | ^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:11:5 + | +LL | drop(&owned1); + | ^^^^^-------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:12:5 + | +LL | drop(&&owned1); + | ^^^^^--------^ + | | + | argument has type `&&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:13:5 + | +LL | drop(&mut owned1); + | ^^^^^-----------^ + | | + | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:17:5 + | +LL | drop(reference1); + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:20:5 + | +LL | drop(reference2); + | ^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:23:5 + | +LL | drop(reference3); + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:28:5 + | +LL | drop(&val); + | ^^^^^----^ + | | + | argument has type `&T` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:36:5 + | +LL | std::mem::drop(&SomeStruct); + | ^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:91:13 + | +LL | drop(println_and(&13)); + | ^^^^^----------------^ + | | + | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:94:14 + | +LL | 3 if drop(println_and(&14)) == () => (), + | ^^^^^----------------^ + | | + | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing + --> $DIR/drop_ref.rs:96:14 + | +LL | 4 => drop(&2), + | ^^^^^--^ + | | + | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: 12 warnings emitted + diff --git a/tests/ui/lint/forget_copy.rs b/tests/ui/lint/forget_copy.rs new file mode 100644 index 00000000000..a6b17b76971 --- /dev/null +++ b/tests/ui/lint/forget_copy.rs @@ -0,0 +1,56 @@ +// check-pass + +#![warn(forget_copy)] + +use std::mem::forget; +use std::vec::Vec; + +#[derive(Copy, Clone)] +struct SomeStruct; + +struct AnotherStruct { + x: u8, + y: u8, + z: Vec<u8>, +} + +impl Clone for AnotherStruct { + fn clone(&self) -> AnotherStruct { + AnotherStruct { + x: self.x, + y: self.y, + z: self.z.clone(), + } + } +} + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let s3 = &s1; + let mut s4 = s1; + let ref s5 = s1; + + forget(s1); //~ WARN calls to `std::mem::forget` + forget(s2); //~ WARN calls to `std::mem::forget` + forget(s3); //~ WARN calls to `std::mem::forget` + forget(s4); //~ WARN calls to `std::mem::forget` + forget(s5); //~ WARN calls to `std::mem::forget` + + let a1 = AnotherStruct { + x: 255, + y: 0, + z: vec![1, 2, 3], + }; + let a2 = &a1; + let mut a3 = a1.clone(); + let ref a4 = a1; + let a5 = a1.clone(); + + forget(a2); //~ WARN calls to `std::mem::forget` + let a3 = &a1; + forget(a3); //~ WARN calls to `std::mem::forget` + forget(a4); //~ WARN calls to `std::mem::forget` + let a5 = a1.clone(); + forget(a5); +} diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr new file mode 100644 index 00000000000..37bc8a8854e --- /dev/null +++ b/tests/ui/lint/forget_copy.stderr @@ -0,0 +1,88 @@ +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forget_copy.rs:34:5 + | +LL | forget(s1); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result +note: the lint level is defined here + --> $DIR/forget_copy.rs:3:9 + | +LL | #![warn(forget_copy)] + | ^^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forget_copy.rs:35:5 + | +LL | forget(s2); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_copy.rs:36:5 + | +LL | forget(s3); + | ^^^^^^^--^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(forget_ref)]` on by default + +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing + --> $DIR/forget_copy.rs:37:5 + | +LL | forget(s4); + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_copy.rs:38:5 + | +LL | forget(s5); + | ^^^^^^^--^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_copy.rs:50:5 + | +LL | forget(a2); + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_copy.rs:52:5 + | +LL | forget(a3); + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_copy.rs:53:5 + | +LL | forget(a4); + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: 8 warnings emitted + diff --git a/tests/ui/lint/forget_ref.rs b/tests/ui/lint/forget_ref.rs new file mode 100644 index 00000000000..13f6d4be3d1 --- /dev/null +++ b/tests/ui/lint/forget_ref.rs @@ -0,0 +1,39 @@ +// check-pass + +#![warn(forget_ref)] + +use std::mem::forget; + +struct SomeStruct; + +fn main() { + forget(&SomeStruct); //~ WARN calls to `std::mem::forget` + + let mut owned = SomeStruct; + forget(&owned); //~ WARN calls to `std::mem::forget` + forget(&&owned); //~ WARN calls to `std::mem::forget` + forget(&mut owned); //~ WARN calls to `std::mem::forget` + forget(owned); + + let reference1 = &SomeStruct; + forget(&*reference1); //~ WARN calls to `std::mem::forget` + + let reference2 = &mut SomeStruct; + forget(reference2); //~ WARN calls to `std::mem::forget` + + let ref reference3 = SomeStruct; + forget(reference3); //~ WARN calls to `std::mem::forget` +} + +#[allow(dead_code)] +fn test_generic_fn_forget<T>(val: T) { + forget(&val); //~ WARN calls to `std::mem::forget` + forget(val); +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn forget<T>(_val: T) {} + forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::forget(&SomeStruct); //~ WARN calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr new file mode 100644 index 00000000000..63fc7791980 --- /dev/null +++ b/tests/ui/lint/forget_ref.stderr @@ -0,0 +1,97 @@ +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:10:5 + | +LL | forget(&SomeStruct); + | ^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result +note: the lint level is defined here + --> $DIR/forget_ref.rs:3:9 + | +LL | #![warn(forget_ref)] + | ^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:13:5 + | +LL | forget(&owned); + | ^^^^^^^------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:14:5 + | +LL | forget(&&owned); + | ^^^^^^^-------^ + | | + | argument has type `&&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:15:5 + | +LL | forget(&mut owned); + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:19:5 + | +LL | forget(&*reference1); + | ^^^^^^^------------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:22:5 + | +LL | forget(reference2); + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:25:5 + | +LL | forget(reference3); + | ^^^^^^^----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:30:5 + | +LL | forget(&val); + | ^^^^^^^----^ + | | + | argument has type `&T` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing + --> $DIR/forget_ref.rs:38:5 + | +LL | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result + +warning: 9 warnings emitted + 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/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs index 9c7be15fcc8..8ef6ab1b6ff 100644 --- a/tests/ui/liveness/liveness-unused.rs +++ b/tests/ui/liveness/liveness-unused.rs @@ -1,7 +1,7 @@ #![warn(unused)] #![deny(unused_variables)] #![deny(unused_assignments)] -#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)] +#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, drop_copy)] use std::ops::AddAssign; 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/issues/issue-2804-2.rs b/tests/ui/macros/issue-2804-2.rs index d02725505ac..d02725505ac 100644 --- a/tests/ui/issues/issue-2804-2.rs +++ b/tests/ui/macros/issue-2804-2.rs 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/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs index 8fef9b0ed87..c50dfdf0116 100644 --- a/tests/ui/macros/parse-complex-macro-invoc-op.rs +++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs @@ -4,6 +4,7 @@ #![allow(unused_assignments)] #![allow(unused_variables)] #![allow(stable_features)] +#![allow(drop_copy)] // Test parsing binary operators after macro invocations. 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/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr index 9241a8be58f..dcc21acc5c0 100644 --- a/tests/ui/methods/method-self-arg-1.stderr +++ b/tests/ui/methods/method-self-arg-1.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:11:14 | LL | Foo::bar(x); - | -------- ^ - | | | - | | expected `&Foo`, found `Foo` - | | help: consider borrowing here: `&x` + | -------- ^ expected `&Foo`, found `Foo` + | | | arguments to this function are incorrect | note: method defined here @@ -13,6 +11,10 @@ note: method defined here | LL | fn bar(&self) {} | ^^^ ----- +help: consider borrowing here + | +LL | Foo::bar(&x); + | + error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:13:14 diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 2a36a352c73..6b9ac3c5852 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -220,11 +220,7 @@ LL | let _ = fat_v as *const dyn Foo; | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: required for the cast from `[u8]` to the object type `dyn Foo` -help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo` - | -LL | let _ = &fat_v as *const dyn Foo; - | + + = note: required for the cast from `*const [u8]` to `*const dyn Foo` error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/cast-rfc0401.rs:62:13 @@ -233,11 +229,7 @@ LL | let _ = a as *const dyn Foo; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Foo` -help: consider borrowing the value, since `&str` can be coerced into `dyn Foo` - | -LL | let _ = &a as *const dyn Foo; - | + + = note: required for the cast from `*const str` to `*const dyn Foo` error[E0606]: casting `&{float}` as `f32` is invalid --> $DIR/cast-rfc0401.rs:71:30 diff --git a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr index 13942682d28..7be94ef4ad6 100644 --- a/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr +++ b/tests/ui/mismatched_types/dont-point-return-on-E0308.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/dont-point-return-on-E0308.rs:11:11 | LL | f(()); - | - ^^ - | | | - | | expected `&()`, found `()` - | | help: consider borrowing here: `&()` + | - ^^ expected `&()`, found `()` + | | | arguments to this function are incorrect | note: function defined here @@ -13,6 +11,10 @@ note: function defined here | LL | async fn f(_: &()) {} | ^ ------ +help: consider borrowing here + | +LL | f(&()); + | + error: aborting due to previous error diff --git a/tests/ui/mut/mut-cross-borrowing.stderr b/tests/ui/mut/mut-cross-borrowing.stderr index 8401827e51f..8a3076db9b2 100644 --- a/tests/ui/mut/mut-cross-borrowing.stderr +++ b/tests/ui/mut/mut-cross-borrowing.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/mut-cross-borrowing.rs:7:7 | LL | f(x) - | - ^ - | | | - | | expected `&mut isize`, found `Box<{integer}>` - | | help: consider mutably borrowing here: `&mut x` + | - ^ expected `&mut isize`, found `Box<{integer}>` + | | | arguments to this function are incorrect | = note: expected mutable reference `&mut isize` @@ -15,6 +13,10 @@ note: function defined here | LL | fn f(_: &mut isize) {} | ^ ------------- +help: consider mutably borrowing here + | +LL | f(&mut x) + | ++++ error: aborting due to previous error diff --git a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr index a0f790dba15..5b6f0235123 100644 --- a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr +++ b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr @@ -10,7 +10,7 @@ LL | | }) as Box<dyn FnMut()>); | = note: expected unit type `()` found type `!` - = note: required for the cast from `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to the object type `dyn FnMut()` + = note: required for the cast from `Box<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]>` to `Box<dyn FnMut()>` error: aborting due to previous error diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs index 7bb7c87097c..e95a992d780 100644 --- a/tests/ui/never_type/never-assign-dead-code.rs +++ b/tests/ui/never_type/never-assign-dead-code.rs @@ -3,6 +3,7 @@ // check-pass #![feature(never_type)] +#![allow(drop_copy)] #![warn(unused)] fn main() { diff --git a/tests/ui/never_type/never-assign-dead-code.stderr b/tests/ui/never_type/never-assign-dead-code.stderr index 521b82023c9..5660bde5c27 100644 --- a/tests/ui/never_type/never-assign-dead-code.stderr +++ b/tests/ui/never_type/never-assign-dead-code.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/never-assign-dead-code.rs:10:5 + --> $DIR/never-assign-dead-code.rs:11:5 | LL | let x: ! = panic!("aah"); | ------------- any code following this expression is unreachable @@ -7,14 +7,14 @@ LL | drop(x); | ^^^^^^^^ unreachable statement | note: the lint level is defined here - --> $DIR/never-assign-dead-code.rs:6:9 + --> $DIR/never-assign-dead-code.rs:7:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` warning: unreachable call - --> $DIR/never-assign-dead-code.rs:10:5 + --> $DIR/never-assign-dead-code.rs:11:5 | LL | drop(x); | ^^^^ - any code following this expression is unreachable @@ -22,7 +22,7 @@ LL | drop(x); | unreachable call warning: unused variable: `x` - --> $DIR/never-assign-dead-code.rs:9:9 + --> $DIR/never-assign-dead-code.rs:10:9 | LL | let x: ! = panic!("aah"); | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/issues/issue-30438-a.rs b/tests/ui/nll/issue-30438-a.rs index 0d4eb796ad9..0d4eb796ad9 100644 --- a/tests/ui/issues/issue-30438-a.rs +++ b/tests/ui/nll/issue-30438-a.rs diff --git a/tests/ui/issues/issue-30438-a.stderr b/tests/ui/nll/issue-30438-a.stderr index 53845af82fb..53845af82fb 100644 --- a/tests/ui/issues/issue-30438-a.stderr +++ b/tests/ui/nll/issue-30438-a.stderr diff --git a/tests/ui/issues/issue-30438-b.rs b/tests/ui/nll/issue-30438-b.rs index 79510cdb663..79510cdb663 100644 --- a/tests/ui/issues/issue-30438-b.rs +++ b/tests/ui/nll/issue-30438-b.rs diff --git a/tests/ui/issues/issue-30438-b.stderr b/tests/ui/nll/issue-30438-b.stderr index fd6bd25b1da..fd6bd25b1da 100644 --- a/tests/ui/issues/issue-30438-b.stderr +++ b/tests/ui/nll/issue-30438-b.stderr diff --git a/tests/ui/issues/issue-30438-c.rs b/tests/ui/nll/issue-30438-c.rs index 813c1d3e2cc..813c1d3e2cc 100644 --- a/tests/ui/issues/issue-30438-c.rs +++ b/tests/ui/nll/issue-30438-c.rs diff --git a/tests/ui/issues/issue-30438-c.stderr b/tests/ui/nll/issue-30438-c.stderr index 7c001088097..7c001088097 100644 --- a/tests/ui/issues/issue-30438-c.stderr +++ b/tests/ui/nll/issue-30438-c.stderr diff --git a/tests/ui/nll/issue-47388.stderr b/tests/ui/nll/issue-47388.stderr index c780451dfa9..09b9d638afb 100644 --- a/tests/ui/nll/issue-47388.stderr +++ b/tests/ui/nll/issue-47388.stderr @@ -7,7 +7,7 @@ LL | fancy_ref.num = 6; help: consider changing this to be a mutable reference | LL | let fancy_ref = &mut (&mut fancy); - | ~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/nll/issue-51244.stderr b/tests/ui/nll/issue-51244.stderr index 03d8acc8188..8ccb5809e39 100644 --- a/tests/ui/nll/issue-51244.stderr +++ b/tests/ui/nll/issue-51244.stderr @@ -7,7 +7,7 @@ LL | *my_ref = 0; help: consider changing this to be a mutable reference | LL | let ref mut my_ref @ _ = 0; - | ~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-54302-cases.rs b/tests/ui/nll/issue-54302-cases.rs index faa116269ee..faa116269ee 100644 --- a/tests/ui/issues/issue-54302-cases.rs +++ b/tests/ui/nll/issue-54302-cases.rs diff --git a/tests/ui/issues/issue-54302-cases.stderr b/tests/ui/nll/issue-54302-cases.stderr index 6e8b69c4bee..6e8b69c4bee 100644 --- a/tests/ui/issues/issue-54302-cases.stderr +++ b/tests/ui/nll/issue-54302-cases.stderr diff --git a/tests/ui/issues/issue-54302.rs b/tests/ui/nll/issue-54302.rs index 1bfaebc3895..1bfaebc3895 100644 --- a/tests/ui/issues/issue-54302.rs +++ b/tests/ui/nll/issue-54302.rs diff --git a/tests/ui/issues/issue-54302.stderr b/tests/ui/nll/issue-54302.stderr index 26c46571f9c..26c46571f9c 100644 --- a/tests/ui/issues/issue-54302.stderr +++ b/tests/ui/nll/issue-54302.stderr diff --git a/tests/ui/nll/issue-57989.stderr b/tests/ui/nll/issue-57989.stderr index d5effd6f346..6062b31d688 100644 --- a/tests/ui/nll/issue-57989.stderr +++ b/tests/ui/nll/issue-57989.stderr @@ -7,7 +7,7 @@ LL | *x = 0; help: consider changing this to be a mutable reference | LL | fn f(x: &mut i32) { - | ~~~~~~~~ + | +++ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-57989.rs:5:5 diff --git a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs index 7cc0acf45f2..73ceaeeb875 100644 --- a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs +++ b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -5,6 +5,8 @@ // check-pass // compile-flags:-Zno-leak-check +#![allow(drop_copy)] + fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 { panic!() } diff --git a/tests/ui/nll/ty-outlives/projection-body.rs b/tests/ui/nll/ty-outlives/projection-body.rs index b03a539ebdb..bff9058a507 100644 --- a/tests/ui/nll/ty-outlives/projection-body.rs +++ b/tests/ui/nll/ty-outlives/projection-body.rs @@ -3,6 +3,8 @@ // // check-pass +#![allow(drop_ref)] + trait MyTrait<'a> { type Output; } diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs new file mode 100644 index 00000000000..318be2a6401 --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -C overflow_checks=true + +#![feature(cfg_overflow_checks)] + +fn main() { + assert!(cfg!(overflow_checks)); + assert!(compiles_differently()); +} + +#[cfg(overflow_checks)] +fn compiles_differently()->bool { + true +} + +#[cfg(not(overflow_checks))] +fn compiles_differently()->bool { + false +} diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs new file mode 100644 index 00000000000..0367d980a64 --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -C overflow_checks=false + +#![feature(cfg_overflow_checks)] + +fn main() { + assert!(!cfg!(overflow_checks)); + assert!(!compiles_differently()); +} + +#[cfg(overflow_checks)] +fn compiles_differently()->bool { + true +} + +#[cfg(not(overflow_checks))] +fn compiles_differently()->bool { + false +} diff --git a/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr index 8420637b3de..183245b2322 100644 --- a/tests/ui/object-safety/issue-19538.stderr +++ b/tests/ui/object-safety/issue-19538.stderr @@ -29,8 +29,7 @@ LL | fn foo<T>(&self, val: T); LL | trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait - = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>` - = note: required by cast to type `&mut dyn Bar` + = note: required for the cast from `&mut Thing` to `&mut dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index f44de07d5da..db3e0885a85 100644 --- a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | const X: usize; | ^ ...because it contains this associated `const` = help: consider moving `X` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index 9a2d472d5e7..b200b64a1f0 100644 --- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | fn bar<T>(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:26:5 @@ -29,8 +28,7 @@ LL | trait Bar { LL | fn bar<T>(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 40a298bd1a7..414614d8d0b 100644 --- a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:30:5 @@ -29,8 +28,7 @@ LL | trait Baz { LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type = help: consider moving `baz` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>` - = note: required by cast to type `&dyn Baz` + = note: required for the cast from `&T` to `&dyn Baz` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index da87b58c9e2..befcef952a8 100644 --- a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} | ^^^ ...because associated function `foo` has no `self` parameter - = note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>` - = note: required by cast to type `Box<dyn Foo>` + = note: required for the cast from `Box<Bar>` to `Box<dyn Foo>` help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self) {} diff --git a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 6c29c8d5f7c..90e5c59dd02 100644 --- a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Bar | --- this trait cannot be made into an object... LL | where Self : Sized | ^^^^^ ...because it requires `Self: Sized` - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 70a44ed6101..a6c22b8747e 100644 --- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Bar : Sized { | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs index 163b07454ec..92a205f14d9 100644 --- a/tests/ui/offset-of/offset-of-arg-count.rs +++ b/tests/ui/offset-of/offset-of-arg-count.rs @@ -3,7 +3,20 @@ use std::mem::offset_of; fn main() { - offset_of!(NotEnoughArguments); //~ ERROR expected one of - offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments - offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments + offset_of!(NotEnoughArguments); //~ ERROR unexpected end of macro invocation + offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR unexpected end of macro invocation + offset_of!(Container, field, too many arguments); //~ ERROR no rules expected the token `too` + offset_of!(S, f); // compiles fine + offset_of!(S, f,); // also compiles fine + offset_of!(S, f.); //~ ERROR unexpected end of macro invocation + offset_of!(S, f.,); //~ ERROR expected identifier + offset_of!(S, f..); //~ ERROR no rules expected the token + offset_of!(S, f..,); //~ ERROR no rules expected the token + offset_of!(Lt<'static>, bar); // issue #111657 + +} + +struct S { f: u8, } +struct Lt<'a> { + bar: &'a (), } diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr index ebecc982c51..4275a89545f 100644 --- a/tests/ui/offset-of/offset-of-arg-count.stderr +++ b/tests/ui/offset-of/offset-of-arg-count.stderr @@ -1,20 +1,59 @@ -error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>` - --> $DIR/offset-of-arg-count.rs:6:16 +error: unexpected end of macro invocation + --> $DIR/offset-of-arg-count.rs:6:34 | LL | offset_of!(NotEnoughArguments); - | ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<` + | ^ missing tokens in macro arguments + | +note: while trying to match `,` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -error: expected 2 arguments - --> $DIR/offset-of-arg-count.rs:7:5 +error: unexpected end of macro invocation + --> $DIR/offset-of-arg-count.rs:7:45 | LL | offset_of!(NotEnoughArgumentsWithAComma, ); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ missing tokens in macro arguments + | +note: while trying to match meta-variable `$fields:tt` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -error: expected 2 arguments - --> $DIR/offset-of-arg-count.rs:8:5 +error: no rules expected the token `too` + --> $DIR/offset-of-arg-count.rs:8:34 | LL | offset_of!(Container, field, too many arguments); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ no rules expected this token in macro call + | + = note: while trying to match sequence end + +error: unexpected end of macro invocation + --> $DIR/offset-of-arg-count.rs:11:21 + | +LL | offset_of!(S, f.); + | ^ missing tokens in macro arguments + | +note: while trying to match meta-variable `$fields:tt` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: expected identifier, found `,` + --> $DIR/offset-of-arg-count.rs:12:21 + | +LL | offset_of!(S, f.,); + | ^ expected identifier + +error: no rules expected the token `..` + --> $DIR/offset-of-arg-count.rs:13:20 + | +LL | offset_of!(S, f..); + | ^^ no rules expected this token in macro call + | + = note: while trying to match sequence start + +error: no rules expected the token `..` + --> $DIR/offset-of-arg-count.rs:14:20 + | +LL | offset_of!(S, f..,); + | ^^ no rules expected this token in macro call + | + = note: while trying to match sequence start -error: aborting due to 3 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/offset-of/offset-of-builtin.rs b/tests/ui/offset-of/offset-of-builtin.rs new file mode 100644 index 00000000000..1be9899887b --- /dev/null +++ b/tests/ui/offset-of/offset-of-builtin.rs @@ -0,0 +1,44 @@ +#![feature(builtin_syntax)] + +// For the exposed macro we already test these errors in the other files, +// but this test helps to make sure the builtin construct also errors. +// This has the same examples as offset-of-arg-count.rs + +fn main() { + builtin # offset_of(NotEnoughArguments); //~ ERROR expected one of +} +fn t1() { + // Already errored upon at the macro level. Yielding an error would require + // extra effort. + builtin # offset_of(NotEnoughArgumentsWithAComma, ); +} +fn t2() { + builtin # offset_of(Container, field, too many arguments); //~ ERROR expected identifier, found + //~| ERROR found `,` + //~| ERROR found `many` + //~| ERROR found `arguments` +} +fn t3() { + builtin # offset_of(S, f); // compiles fine +} +fn t4() { + // Already errored upon at the macro level. Yielding an error would require + // extra effort. + builtin # offset_of(S, f); +} +fn t5() { + builtin # offset_of(S, f.); //~ ERROR expected identifier +} +fn t6() { + builtin # offset_of(S, f.,); //~ ERROR expected identifier +} +fn t7() { + builtin # offset_of(S, f..); //~ ERROR expected one of +} +fn t8() { + // Already errored upon at the macro level. Yielding an error would require + // extra effort. + builtin # offset_of(S, f..,); +} + +struct S { f: u8, } diff --git a/tests/ui/offset-of/offset-of-builtin.stderr b/tests/ui/offset-of/offset-of-builtin.stderr new file mode 100644 index 00000000000..1a1f33cc613 --- /dev/null +++ b/tests/ui/offset-of/offset-of-builtin.stderr @@ -0,0 +1,65 @@ +error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `)` + --> $DIR/offset-of-builtin.rs:8:43 + | +LL | builtin # offset_of(NotEnoughArguments); + | ^ expected one of `!`, `(`, `+`, `,`, `::`, or `<` + +error: expected identifier, found `,` + --> $DIR/offset-of-builtin.rs:16:41 + | +LL | builtin # offset_of(Container, field, too many arguments); + | ^ + | | + | expected identifier + | help: remove this comma + +error: expected one of `)` or `.`, found `,` + --> $DIR/offset-of-builtin.rs:16:41 + | +LL | builtin # offset_of(Container, field, too many arguments); + | ^ + | | + | expected one of `)` or `.` + | help: missing `.` + +error: expected one of `)` or `.`, found `many` + --> $DIR/offset-of-builtin.rs:16:47 + | +LL | builtin # offset_of(Container, field, too many arguments); + | -^^^^ expected one of `)` or `.` + | | + | help: missing `.` + +error: expected one of `)` or `.`, found `arguments` + --> $DIR/offset-of-builtin.rs:16:52 + | +LL | builtin # offset_of(Container, field, too many arguments); + | -^^^^^^^^^ expected one of `)` or `.` + | | + | help: missing `.` + +error: expected identifier, found `)` + --> $DIR/offset-of-builtin.rs:30:30 + | +LL | builtin # offset_of(S, f.); + | ^ expected identifier + +error: expected identifier, found `,` + --> $DIR/offset-of-builtin.rs:33:30 + | +LL | builtin # offset_of(S, f.,); + | ^ expected identifier + +error: expected one of `)` or `.`, found `..` + --> $DIR/offset-of-builtin.rs:36:29 + | +LL | builtin # offset_of(S, f..); + | ^^ expected one of `)` or `.` + | +help: if you meant to bind the contents of the rest of the array pattern into `f`, use `@` + | +LL | builtin # offset_of(S, f @ ..); + | + + +error: aborting due to 8 previous errors + diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 8e88015b07a..e6e0f499236 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -5,6 +5,7 @@ LL | offset_of!(Alpha, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time --> $DIR/offset-of-dst-field.rs:31:5 @@ -13,6 +14,7 @@ LL | offset_of!(Beta, z); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time --> $DIR/offset-of-dst-field.rs:32:5 @@ -21,6 +23,7 @@ LL | offset_of!(Gamma, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `Extern` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr index 25811a061d7..c39882519a5 100644 --- a/tests/ui/offset-of/offset-of-unstable.stderr +++ b/tests/ui/offset-of/offset-of-unstable.stderr @@ -33,6 +33,7 @@ LL | | ); | |_____^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/offset-of-unstable.rs:18:5 @@ -41,6 +42,7 @@ LL | offset_of!(StableWithUnstableField, unstable); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/offset-of-unstable.rs:20:5 @@ -49,6 +51,7 @@ LL | offset_of!(StableWithUnstableFieldType, stable.unstable); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/offset-of-unstable.rs:21:5 @@ -61,6 +64,7 @@ LL | | ); | |_____^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of unstable library feature 'unstable_test_feature' --> $DIR/offset-of-unstable.rs:26:5 @@ -73,6 +77,7 @@ LL | | ); | |_____^ | = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors diff --git a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs index e56f9ffe23c..c138d99d303 100644 --- a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs +++ b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs @@ -3,6 +3,8 @@ // check-pass #![allow(irrefutable_let_patterns)] +#![allow(drop_copy)] +#![allow(drop_ref)] fn main() { // A regression test for a mistake we made at one point: diff --git a/tests/ui/parser/builtin-syntax.rs b/tests/ui/parser/builtin-syntax.rs new file mode 100644 index 00000000000..897dab8ec50 --- /dev/null +++ b/tests/ui/parser/builtin-syntax.rs @@ -0,0 +1,9 @@ +#![feature(builtin_syntax)] + +fn main() { + builtin # foobar(); //~ ERROR unknown `builtin #` construct +} + +fn not_identifier() { + builtin # {}(); //~ ERROR expected identifier after +} diff --git a/tests/ui/parser/builtin-syntax.stderr b/tests/ui/parser/builtin-syntax.stderr new file mode 100644 index 00000000000..ee3764a6221 --- /dev/null +++ b/tests/ui/parser/builtin-syntax.stderr @@ -0,0 +1,14 @@ +error: unknown `builtin #` construct `foobar` + --> $DIR/builtin-syntax.rs:4:5 + | +LL | builtin # foobar(); + | ^^^^^^^^^^^^^^^^ + +error: expected identifier after `builtin #` + --> $DIR/builtin-syntax.rs:8:15 + | +LL | builtin # {}(); + | ^ + +error: aborting due to 2 previous errors + 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/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index fbdefd9d36c..965204bf240 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -2,6 +2,9 @@ // Test `@` patterns combined with `box` patterns. +#![allow(drop_ref)] +#![allow(drop_copy)] + #![feature(box_patterns)] #[derive(Copy, Clone)] diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index 0108861cfce..3eb5d2cbf54 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -2,6 +2,8 @@ // Test `Copy` bindings in the rhs of `@` patterns. +#![allow(drop_copy)] + #[derive(Copy, Clone)] struct C; diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs index 5445696fdff..0550238549e 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(drop_ref)] + fn main() {} struct U; diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index c7c7c074f7c..a033cc0655e 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -112,7 +112,7 @@ LL | *_x0 = U; help: consider changing this to be a mutable reference | LL | let (ref mut _x0, _x1, ref _x2, ..) = tup; - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference --> $DIR/borrowck-move-ref-pattern.rs:27:5 @@ -123,7 +123,7 @@ LL | *_x2 = U; help: consider changing this to be a mutable reference | LL | let (ref _x0, _x1, ref mut _x2, ..) = tup; - | ~~~~~~~~~~~ + | +++ error[E0382]: use of moved value: `tup.1` --> $DIR/borrowck-move-ref-pattern.rs:28:10 diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs index 583f70f41aa..788975d960a 100644 --- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs +++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(drop_ref)] + fn main() { struct U; fn accept_fn_once(_: impl FnOnce()) {} 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/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs index 1598b069691..c73268dc46a 100644 --- a/tests/ui/print_type_sizes/async.rs +++ b/tests/ui/print_type_sizes/async.rs @@ -3,6 +3,8 @@ // build-pass // ignore-pass +#![allow(drop_copy)] + async fn wait() {} pub async fn test(arg: [u8; 8192]) { diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index 1c6887412be..873def9031a 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -1,4 +1,4 @@ -print-type-size type: `[async fn body@$DIR/async.rs:8:36: 11:2]`: 16386 bytes, alignment: 1 bytes +print-type-size type: `[async fn body@$DIR/async.rs:10:36: 13:2]`: 16386 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes @@ -16,14 +16,14 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 8192 bytes -print-type-size type: `[async fn body@$DIR/async.rs:6:17: 6:19]`: 1 bytes, alignment: 1 bytes +print-type-size type: `[async fn body@$DIR/async.rs:8:17: 8:19]`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes -print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes diff --git a/tests/ui/print_type_sizes/generator_discr_placement.rs b/tests/ui/print_type_sizes/generator_discr_placement.rs index 1a85fe95bb6..a77a03f0a8a 100644 --- a/tests/ui/print_type_sizes/generator_discr_placement.rs +++ b/tests/ui/print_type_sizes/generator_discr_placement.rs @@ -6,6 +6,7 @@ // Avoid emitting panic handlers, like the rest of these tests... #![feature(generators)] +#![allow(drop_copy)] pub fn foo() { let a = || { diff --git a/tests/ui/print_type_sizes/generator_discr_placement.stdout b/tests/ui/print_type_sizes/generator_discr_placement.stdout index f2a11c7a33b..fe0022cf5f4 100644 --- a/tests/ui/print_type_sizes/generator_discr_placement.stdout +++ b/tests/ui/print_type_sizes/generator_discr_placement.stdout @@ -1,4 +1,4 @@ -print-type-size type: `[generator@$DIR/generator_discr_placement.rs:11:13: 11:15]`: 8 bytes, alignment: 4 bytes +print-type-size type: `[generator@$DIR/generator_discr_placement.rs:12:13: 12:15]`: 8 bytes, alignment: 4 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Suspend0`: 7 bytes diff --git a/tests/ui/range/issue-54505-no-literals.fixed b/tests/ui/range/issue-54505-no-literals.fixed index 4d8f67182b9..71c36c741cc 100644 --- a/tests/ui/range/issue-54505-no-literals.fixed +++ b/tests/ui/range/issue-54505-no-literals.fixed @@ -16,60 +16,60 @@ fn main() { take_range(&std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(&::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(&std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(&::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(&std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFull {} + //~| SUGGESTION & take_range(&::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFull {} + //~| SUGGESTION & take_range(&std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(&::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(&std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(&::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(&std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & take_range(&::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & } diff --git a/tests/ui/range/issue-54505-no-literals.rs b/tests/ui/range/issue-54505-no-literals.rs index dc21dcbc2db..db125d1a22b 100644 --- a/tests/ui/range/issue-54505-no-literals.rs +++ b/tests/ui/range/issue-54505-no-literals.rs @@ -16,60 +16,60 @@ fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } + //~| SUGGESTION & take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } + //~| SUGGESTION & take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeFull {} + //~| SUGGESTION & take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeFull {} + //~| SUGGESTION & take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) + //~| SUGGESTION & take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeTo { end: 5 } + //~| SUGGESTION & take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } + //~| SUGGESTION & } diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr index d112983848d..5894bb6ba55 100644 --- a/tests/ui/range/issue-54505-no-literals.stderr +++ b/tests/ui/range/issue-54505-no-literals.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:16:16 | LL | take_range(std::ops::Range { start: 0, end: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -15,15 +13,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::Range { start: 0, end: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:21:16 | LL | take_range(::std::ops::Range { start: 0, end: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,15 +33,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::Range { start: 0, end: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:26:16 | LL | take_range(std::ops::RangeFrom { start: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -51,15 +53,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeFrom { start: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:31:16 | LL | take_range(::std::ops::RangeFrom { start: 1 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -69,15 +73,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeFrom { start: 1 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:36:16 | LL | take_range(std::ops::RangeFull {}); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -87,15 +93,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeFull {}); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:41:16 | LL | take_range(::std::ops::RangeFull {}); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&::std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -105,15 +113,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeFull {}); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:46:16 | LL | take_range(std::ops::RangeInclusive::new(0, 1)); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -123,15 +133,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeInclusive::new(0, 1)); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:51:16 | LL | take_range(::std::ops::RangeInclusive::new(0, 1)); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -141,15 +153,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeInclusive::new(0, 1)); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:56:16 | LL | take_range(std::ops::RangeTo { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -159,15 +173,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeTo { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:61:16 | LL | take_range(::std::ops::RangeTo { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -177,15 +193,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeTo { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:66:16 | LL | take_range(std::ops::RangeToInclusive { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -195,15 +213,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&std::ops::RangeToInclusive { end: 5 }); + | + error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:71:16 | LL | take_range(::std::ops::RangeToInclusive { end: 5 }); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -213,6 +233,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&::std::ops::RangeToInclusive { end: 5 }); + | + error: aborting due to 12 previous errors diff --git a/tests/ui/range/issue-54505-no-std.rs b/tests/ui/range/issue-54505-no-std.rs index 9f378b4836e..db455fada3b 100644 --- a/tests/ui/range/issue-54505-no-std.rs +++ b/tests/ui/range/issue-54505-no-std.rs @@ -29,30 +29,30 @@ fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index a6a9f89da74..13563d1940c 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -14,10 +14,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:29:16 | LL | take_range(0..1); - | ---------- ^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -27,15 +25,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:34:16 | LL | take_range(1..); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&(1..)` + | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -45,15 +45,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(1..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:39:16 | LL | take_range(..); - | ---------- ^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&(..)` + | ---------- ^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -63,15 +65,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:44:16 | LL | take_range(0..=1); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -81,15 +85,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..=1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:49:16 | LL | take_range(..5); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&(..5)` + | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -99,15 +105,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..5)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:54:16 | LL | take_range(..=42); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -117,6 +125,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..=42)); + | ++ + error: aborting due to 8 previous errors diff --git a/tests/ui/range/issue-54505.fixed b/tests/ui/range/issue-54505.fixed index f8298c0b5ce..9d113ba1d35 100644 --- a/tests/ui/range/issue-54505.fixed +++ b/tests/ui/range/issue-54505.fixed @@ -14,30 +14,30 @@ fn main() { take_range(&(0..1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(&(1..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(&(..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(&(0..=1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(&(..5)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(&(..=42)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505.rs b/tests/ui/range/issue-54505.rs index 03673252dd3..c9929988fe5 100644 --- a/tests/ui/range/issue-54505.rs +++ b/tests/ui/range/issue-54505.rs @@ -14,30 +14,30 @@ fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..1) + //~| SUGGESTION &( take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(1..) + //~| SUGGESTION &( take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..) + //~| SUGGESTION &( take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(0..=1) + //~| SUGGESTION &( take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..5) + //~| SUGGESTION &( take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here - //~| SUGGESTION &(..=42) + //~| SUGGESTION &( } diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr index eda047b507a..0e959fc05e2 100644 --- a/tests/ui/range/issue-54505.stderr +++ b/tests/ui/range/issue-54505.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-54505.rs:14:16 | LL | take_range(0..1); - | ---------- ^^^^ - | | | - | | expected `&_`, found `Range<{integer}>` - | | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ expected `&_`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -15,15 +13,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:19:16 | LL | take_range(1..); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeFrom<{integer}>` - | | help: consider borrowing here: `&(1..)` + | ---------- ^^^ expected `&_`, found `RangeFrom<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,15 +33,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(1..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:24:16 | LL | take_range(..); - | ---------- ^^ - | | | - | | expected `&_`, found `RangeFull` - | | help: consider borrowing here: `&(..)` + | ---------- ^^ expected `&_`, found `RangeFull` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -51,15 +53,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:29:16 | LL | take_range(0..=1); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeInclusive<{integer}>` - | | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ expected `&_`, found `RangeInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -69,15 +73,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(0..=1)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:34:16 | LL | take_range(..5); - | ---------- ^^^ - | | | - | | expected `&_`, found `RangeTo<{integer}>` - | | help: consider borrowing here: `&(..5)` + | ---------- ^^^ expected `&_`, found `RangeTo<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -87,15 +93,17 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..5)); + | ++ + error[E0308]: mismatched types --> $DIR/issue-54505.rs:39:16 | LL | take_range(..=42); - | ---------- ^^^^^ - | | | - | | expected `&_`, found `RangeToInclusive<{integer}>` - | | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ expected `&_`, found `RangeToInclusive<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -105,6 +113,10 @@ note: function defined here | LL | fn take_range(_r: &impl RangeBounds<i8>) {} | ^^^^^^^^^^ ------------------------- +help: consider borrowing here + | +LL | take_range(&(..=42)); + | ++ + error: aborting due to 6 previous errors diff --git a/tests/ui/range/issue-73553-misinterp-range-literal.stderr b/tests/ui/range/issue-73553-misinterp-range-literal.stderr index 77595b3678e..52efa241d0b 100644 --- a/tests/ui/range/issue-73553-misinterp-range-literal.stderr +++ b/tests/ui/range/issue-73553-misinterp-range-literal.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:12:10 | LL | demo(tell(1)..tell(10)); - | ---- ^^^^^^^^^^^^^^^^^ - | | | - | | expected `&Range<usize>`, found `Range<usize>` - | | help: consider borrowing here: `&(tell(1)..tell(10))` + | ---- ^^^^^^^^^^^^^^^^^ expected `&Range<usize>`, found `Range<usize>` + | | | arguments to this function are incorrect | = note: expected reference `&std::ops::Range<usize>` @@ -15,15 +13,17 @@ note: function defined here | LL | fn demo(r: &Range) { | ^^^^ --------- +help: consider borrowing here + | +LL | demo(&(tell(1)..tell(10))); + | ++ + error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:14:10 | LL | demo(1..10); - | ---- ^^^^^ - | | | - | | expected `&Range<usize>`, found `Range<{integer}>` - | | help: consider borrowing here: `&(1..10)` + | ---- ^^^^^ expected `&Range<usize>`, found `Range<{integer}>` + | | | arguments to this function are incorrect | = note: expected reference `&std::ops::Range<usize>` @@ -33,6 +33,10 @@ note: function defined here | LL | fn demo(r: &Range) { | ^^^^ --------- +help: consider borrowing here + | +LL | demo(&(1..10)); + | ++ + error: aborting due to 2 previous errors diff --git a/tests/ui/reachable/auxiliary/foreign-priv-aux.rs b/tests/ui/reachable/auxiliary/foreign-priv-aux.rs new file mode 100644 index 00000000000..10dc0861461 --- /dev/null +++ b/tests/ui/reachable/auxiliary/foreign-priv-aux.rs @@ -0,0 +1,21 @@ +trait PrivTrait { + fn priv_fn(&self); +} + +pub struct ImplPrivTrait; + +impl PrivTrait for ImplPrivTrait { + fn priv_fn(&self) {} +} + +pub struct Wrapper<T>(T); + +pub trait PubTrait { + fn pub_fn(&self); +} + +impl<T: PrivTrait> PubTrait for Wrapper<T> { + fn pub_fn(&self) { + self.0.priv_fn() + } +} diff --git a/tests/ui/reachable/foreign-priv.rs b/tests/ui/reachable/foreign-priv.rs new file mode 100644 index 00000000000..bf336b6be7a --- /dev/null +++ b/tests/ui/reachable/foreign-priv.rs @@ -0,0 +1,12 @@ +// aux-build:foreign-priv-aux.rs +// build-pass + +#![crate_type = "lib"] + +extern crate foreign_priv_aux; + +use foreign_priv_aux::{ImplPrivTrait, PubTrait, Wrapper}; + +pub fn foo(x: Wrapper<ImplPrivTrait>) { + x.pub_fn(); +} diff --git a/tests/ui/issues/issue-948.rs b/tests/ui/reachable/issue-948.rs index b9bbeb3951e..b9bbeb3951e 100644 --- a/tests/ui/issues/issue-948.rs +++ b/tests/ui/reachable/issue-948.rs diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs index a65c17e0efc..5ae5ebb450e 100644 --- a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs +++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs @@ -55,11 +55,11 @@ where } pub fn x<T: Copy>(a: Array<T>) { - // drop just avoids a must_use warning - drop((0..1).filter(|_| true)); + // _ just avoids a must_use warning + let _ = (0..1).filter(|_| true); let y = a.index_axis(); a.axis_iter().for_each(|_| { - drop(y); + let _ = y; }); } diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs index d463f311c34..af2bb09805a 100644 --- a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs +++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs @@ -3,6 +3,8 @@ // check-pass +#![allow(drop_copy)] + use std::marker::PhantomData; fn apply<T, F: FnOnce(T)>(_: T, _: F) {} diff --git a/tests/ui/resolve/explicit-self-lowercase-param.rs b/tests/ui/resolve/explicit-self-lowercase-param.rs new file mode 100644 index 00000000000..7171bd8a42d --- /dev/null +++ b/tests/ui/resolve/explicit-self-lowercase-param.rs @@ -0,0 +1,8 @@ +struct Foo; + +impl Foo { + fn do_nothing(self: Box<self>) {} //~ ERROR attempt to use a non-constant value in a constant + //~^ HELP try using `Self` +} + +fn main() {} diff --git a/tests/ui/resolve/explicit-self-lowercase-param.stderr b/tests/ui/resolve/explicit-self-lowercase-param.stderr new file mode 100644 index 00000000000..cd64dbb3854 --- /dev/null +++ b/tests/ui/resolve/explicit-self-lowercase-param.stderr @@ -0,0 +1,8 @@ +error: attempt to use a non-constant value in a constant + --> $DIR/explicit-self-lowercase-param.rs:4:29 + | +LL | fn do_nothing(self: Box<self>) {} + | ^^^^ help: try using `Self` + +error: aborting due to previous error + 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-111312.rs b/tests/ui/resolve/issue-111312.rs new file mode 100644 index 00000000000..acea37b358b --- /dev/null +++ b/tests/ui/resolve/issue-111312.rs @@ -0,0 +1,11 @@ +// edition: 2021 + +trait Has { + fn has() {} +} + +trait HasNot {} + +fn main() { + HasNot::has(); //~ ERROR +} diff --git a/tests/ui/resolve/issue-111312.stderr b/tests/ui/resolve/issue-111312.stderr new file mode 100644 index 00000000000..4c864029c98 --- /dev/null +++ b/tests/ui/resolve/issue-111312.stderr @@ -0,0 +1,15 @@ +error[E0599]: no function or associated item named `has` found for trait `HasNot` + --> $DIR/issue-111312.rs:10:13 + | +LL | HasNot::has(); + | ^^^ function or associated item not found in `HasNot` + | +note: `Has` defines an item `has` + --> $DIR/issue-111312.rs:3:1 + | +LL | trait Has { + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-3099-a.rs b/tests/ui/resolve/issue-3099-a.rs index 9c3d8cf5a55..9c3d8cf5a55 100644 --- a/tests/ui/issues/issue-3099-a.rs +++ b/tests/ui/resolve/issue-3099-a.rs diff --git a/tests/ui/issues/issue-3099-a.stderr b/tests/ui/resolve/issue-3099-a.stderr index e3733cebba5..e3733cebba5 100644 --- a/tests/ui/issues/issue-3099-a.stderr +++ b/tests/ui/resolve/issue-3099-a.stderr diff --git a/tests/ui/issues/issue-3099-b.rs b/tests/ui/resolve/issue-3099-b.rs index 71952c3b060..71952c3b060 100644 --- a/tests/ui/issues/issue-3099-b.rs +++ b/tests/ui/resolve/issue-3099-b.rs diff --git a/tests/ui/issues/issue-3099-b.stderr b/tests/ui/resolve/issue-3099-b.stderr index c0cfefeb940..c0cfefeb940 100644 --- a/tests/ui/issues/issue-3099-b.stderr +++ b/tests/ui/resolve/issue-3099-b.stderr 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/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs index be775b37f7b..8f45b989f13 100644 --- a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs +++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs @@ -3,6 +3,8 @@ // check-pass +#![allow(drop_ref)] + // aux-build:monovariants.rs extern crate monovariants; diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs index 04d924a9aed..4c1562790d5 100644 --- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs +++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs @@ -4,6 +4,8 @@ // Tests ensuring that `dbg!(expr)` has the expected run-time behavior. // as well as some compile time properties we expect. +#![allow(drop_copy)] + #[derive(Copy, Clone, Debug)] struct Unit; diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr index 49d72158e92..a20a6062c13 100644 --- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr +++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr @@ -1,28 +1,28 @@ -[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit -[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit -[$DIR/dbg-macro-expected-behavior.rs:27] Point { x: 42, y: 24 } = Point { +[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit +[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit +[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:28] b = Point { +[$DIR/dbg-macro-expected-behavior.rs:30] b = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:36] -[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:38] +[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(& a) = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42 +[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42 before -[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331 -[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = ( +[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331 +[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = ( "Yeah", ) -[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1 -[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2 -[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1 -[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2 -[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah" +[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1 +[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1 +[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah" diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs index 3ac90992486..f31123f16f1 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs @@ -12,7 +12,9 @@ trait Specialize {} trait Foo {} #[const_trait] -trait Bar {} +trait Bar { + fn bar(); +} // bgr360: I was only able to exercise the code path that raises the // "missing ~const qualifier" error by making this base impl non-const, even @@ -21,26 +23,36 @@ trait Bar {} impl<T> Bar for T where T: ~const Foo, -{} +{ + default fn bar() {} +} impl<T> Bar for T where T: Foo, //~ ERROR missing `~const` qualifier T: Specialize, -{} +{ + fn bar() {} +} #[const_trait] -trait Baz {} +trait Baz { + fn baz(); +} impl<T> const Baz for T where T: ~const Foo, -{} +{ + default fn baz() {} +} impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz` where T: Foo, T: Specialize, -{} +{ + fn baz() {} +} fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr index 4aea1979421..057cf4aea8a 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,11 +1,11 @@ error: missing `~const` qualifier for specialization - --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:32:8 | LL | T: Foo, | ^^^ error[E0119]: conflicting implementations of trait `Baz` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:50:1 | LL | impl<T> const Baz for T | ----------------------- first implementation here diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs index 9c2c2cf1610..92d8be6bb16 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs @@ -11,27 +11,39 @@ trait Specialize {} #[const_trait] -trait Foo {} +trait Foo { + fn foo(); +} -impl<T> const Foo for T {} +impl<T> const Foo for T { + default fn foo() {} +} impl<T> const Foo for T where T: ~const Specialize, -{} +{ + fn foo() {} +} #[const_trait] -trait Bar {} +trait Bar { + fn bar() {} +} impl<T> const Bar for T where T: ~const Foo, -{} +{ + default fn bar() {} +} impl<T> const Bar for T where T: ~const Foo, T: ~const Specialize, -{} +{ + fn bar() {} +} fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs index 1e6b1c6513b..51bfaf73b57 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -15,31 +15,43 @@ trait Specialize {} trait Foo {} #[const_trait] -trait Bar {} +trait Bar { + fn bar(); +} impl<T> Bar for T where T: Foo, -{} +{ + default fn bar() {} +} impl<T> const Bar for T where T: ~const Foo, T: Specialize, -{} +{ + fn bar() {} +} #[const_trait] -trait Baz {} +trait Baz { + fn baz(); +} impl<T> const Baz for T where T: Foo, -{} +{ + default fn baz() {} +} impl<T> const Baz for T where T: ~const Foo, T: Specialize, -{} +{ + fn baz() {} +} fn main() {} diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed index 15e0ccc5256..4ed4d610025 100644 --- a/tests/ui/rust-2018/remove-extern-crate.fixed +++ b/tests/ui/rust-2018/remove-extern-crate.fixed @@ -5,6 +5,7 @@ // compile-flags:--extern remove_extern_crate #![warn(rust_2018_idioms)] +#![allow(drop_copy)] //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs index aec0bc7c374..5dafdb2b7b7 100644 --- a/tests/ui/rust-2018/remove-extern-crate.rs +++ b/tests/ui/rust-2018/remove-extern-crate.rs @@ -5,6 +5,7 @@ // compile-flags:--extern remove_extern_crate #![warn(rust_2018_idioms)] +#![allow(drop_copy)] extern crate core; //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.stderr b/tests/ui/rust-2018/remove-extern-crate.stderr index d07358e471b..f752cac8ed6 100644 --- a/tests/ui/rust-2018/remove-extern-crate.stderr +++ b/tests/ui/rust-2018/remove-extern-crate.stderr @@ -1,5 +1,5 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:9:1 + --> $DIR/remove-extern-crate.rs:10:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it @@ -12,7 +12,7 @@ LL | #![warn(rust_2018_idioms)] = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:33:5 + --> $DIR/remove-extern-crate.rs:34:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | use core; | ~~~ warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:43:5 + --> $DIR/remove-extern-crate.rs:44:5 | LL | pub extern crate core; | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 0ec0d4be5f2..13591f5b635 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -31,8 +31,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc<Self>) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>` - = note: required by cast to type `Rc<dyn Foo>` + = note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>` error: aborting due to 2 previous errors diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index b494b448e2e..593f705353a 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -14,8 +14,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc<Self>) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>` - = note: required by cast to type `Rc<dyn Foo>` + = note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>` error: aborting due to previous error diff --git a/tests/ui/self/self-ctor-inner-const.rs b/tests/ui/self/self-ctor-inner-const.rs deleted file mode 100644 index b015397a5bc..00000000000 --- a/tests/ui/self/self-ctor-inner-const.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Verify that we ban usage of `Self` as constructor from inner items. - -struct S0<T>(T); - -impl<T> S0<T> { - fn foo() { - const C: S0<u8> = Self(0); - //~^ ERROR can't use generic parameters from outer function - fn bar() -> Self { - //~^ ERROR can't use generic parameters from outer function - Self(0) - //~^ ERROR can't use generic parameters from outer function - } - } -} - -fn main() {} diff --git a/tests/ui/self/self-ctor-inner-const.stderr b/tests/ui/self/self-ctor-inner-const.stderr deleted file mode 100644 index 7287c64c659..00000000000 --- a/tests/ui/self/self-ctor-inner-const.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:7:27 - | -LL | const C: S0<u8> = Self(0); - | ^^^^ - | | - | use of generic parameter from outer function - | can't use `Self` here - -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:9:21 - | -LL | impl<T> S0<T> { - | ---- `Self` type implicitly declared here, by this `impl` -... -LL | fn bar() -> Self { - | ^^^^ - | | - | use of generic parameter from outer function - | use a type here instead - -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:11:13 - | -LL | Self(0) - | ^^^^ - | | - | use of generic parameter from outer function - | can't use `Self` here - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/self/self-ctor-nongeneric.rs b/tests/ui/self/self-ctor-nongeneric.rs new file mode 100644 index 00000000000..0ae7f8da4b4 --- /dev/null +++ b/tests/ui/self/self-ctor-nongeneric.rs @@ -0,0 +1,15 @@ +// `Self` as a constructor is currently allowed when the outer item is not generic. +// check-pass + +struct S0(usize); + +impl S0 { + fn foo() { + const C: S0 = Self(0); + fn bar() -> S0 { + Self(0) + } + } +} + +fn main() {} diff --git a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr index 570328fc211..80c5f9da40c 100644 --- a/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr +++ b/tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr @@ -18,7 +18,7 @@ LL | &mut x.y help: consider changing this to be a mutable reference | LL | fn deref_extend_mut_field1(x: &mut Own<Point>) -> &mut isize { - | ~~~~~~~~~~~~~~~ + | +++ error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:78:19 @@ -50,7 +50,7 @@ LL | x.y = 3; help: consider changing this to be a mutable reference | LL | fn assign_field2<'a>(x: &'a mut Own<Point>) { - | ~~~~~~~~~~~~~~~~~~ + | +++ error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5 @@ -82,7 +82,7 @@ LL | x.y_mut() help: consider changing this to be a mutable reference | LL | fn deref_extend_mut_method1(x: &mut Own<Point>) -> &mut isize { - | ~~~~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:129:6 @@ -104,7 +104,7 @@ LL | *x.y_mut() = 3; help: consider changing this to be a mutable reference | LL | fn assign_method2<'a>(x: &'a mut Own<Point>) { - | ~~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to 10 previous errors diff --git a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr index 3fed7b3f4dc..dbd52dc2d38 100644 --- a/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr +++ b/tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr @@ -18,7 +18,7 @@ LL | &mut **x help: consider changing this to be a mutable reference | LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize { - | ~~~~~~~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6 @@ -40,7 +40,7 @@ LL | **x = 3; help: consider changing this to be a mutable reference | LL | fn assign2<'a>(x: &'a mut Own<isize>) { - | ~~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 9711dad8078..99c8fa1f932 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -19,7 +19,7 @@ LL | (*f)(); help: consider changing this to be a mutable reference | LL | fn test2<F>(f: &mut F) where F: FnMut() { - | ~~~~~~ + | +++ error[E0596]: cannot borrow `f.f` as mutable, as it is behind a `&` reference --> $DIR/borrowck-call-is-borrow-issue-12224.rs:34:5 @@ -29,8 +29,8 @@ LL | f.f.call_mut(()) | help: consider changing this to be a mutable reference | -LL | fn test4(f: &mut Test<'_>) { - | ~~~~~~~~~~~~~ +LL | fn test4(f: &mut Test) { + | +++ error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13 diff --git a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr index 2a842f5a2a9..328197ae9f4 100644 --- a/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr +++ b/tests/ui/span/borrowck-call-method-from-mut-aliasable.stderr @@ -7,7 +7,7 @@ LL | x.h(); help: consider changing this to be a mutable reference | LL | fn b(x: &mut Foo) { - | ~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/span/borrowck-fn-in-const-b.stderr b/tests/ui/span/borrowck-fn-in-const-b.stderr index 1df19deb12f..17fdcc622f7 100644 --- a/tests/ui/span/borrowck-fn-in-const-b.stderr +++ b/tests/ui/span/borrowck-fn-in-const-b.stderr @@ -7,7 +7,7 @@ LL | x.push(format!("this is broken")); help: consider changing this to be a mutable reference | LL | fn broken(x: &mut Vec<String>) { - | ~~~~~~~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/tests/ui/span/borrowck-object-mutability.stderr b/tests/ui/span/borrowck-object-mutability.stderr index b6517e0b309..805a8034c18 100644 --- a/tests/ui/span/borrowck-object-mutability.stderr +++ b/tests/ui/span/borrowck-object-mutability.stderr @@ -7,7 +7,7 @@ LL | x.borrowed_mut(); help: consider changing this to be a mutable reference | LL | fn borrowed_receiver(x: &mut dyn Foo) { - | ~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable --> $DIR/borrowck-object-mutability.rs:18:5 diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr index bb30f000ea7..ff840b781f0 100644 --- a/tests/ui/span/coerce-suggestions.stderr +++ b/tests/ui/span/coerce-suggestions.stderr @@ -10,11 +10,14 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:9:19 | LL | let x: &str = String::new(); - | ---- ^^^^^^^^^^^^^ - | | | - | | expected `&str`, found `String` - | | help: consider borrowing here: `&String::new()` + | ---- ^^^^^^^^^^^^^ expected `&str`, found `String` + | | | expected due to this + | +help: consider borrowing here + | +LL | let x: &str = &String::new(); + | + error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:12:10 diff --git a/tests/ui/span/issue-39018.stderr b/tests/ui/span/issue-39018.stderr index bae93639271..c8c4a513988 100644 --- a/tests/ui/span/issue-39018.stderr +++ b/tests/ui/span/issue-39018.stderr @@ -78,10 +78,12 @@ error[E0308]: mismatched types --> $DIR/issue-39018.rs:29:17 | LL | let _ = a + b; - | ^ - | | - | expected `&str`, found `String` - | help: consider borrowing here: `&b` + | ^ expected `&str`, found `String` + | +help: consider borrowing here + | +LL | let _ = a + &b; + | + error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:30:15 diff --git a/tests/ui/span/mut-arg-hint.stderr b/tests/ui/span/mut-arg-hint.stderr index 96ce4d5bc6c..06011eac674 100644 --- a/tests/ui/span/mut-arg-hint.stderr +++ b/tests/ui/span/mut-arg-hint.stderr @@ -7,7 +7,7 @@ LL | a.push_str("bar"); help: consider changing this to be a mutable reference | LL | fn foo(mut a: &mut String) { - | ~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/mut-arg-hint.rs:8:5 @@ -18,7 +18,7 @@ LL | a.push_str("foo"); help: consider changing this to be a mutable reference | LL | pub fn foo<'a>(mut a: &'a mut String) { - | ~~~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference --> $DIR/mut-arg-hint.rs:15:9 @@ -29,7 +29,7 @@ LL | a.push_str("foo"); help: consider changing this to be a mutable reference | LL | pub fn foo(mut a: &mut String) { - | ~~~~~~~~~~~ + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/specialization/min_specialization/specialize-associated-type.rs b/tests/ui/specialization/min_specialization/specialize-associated-type.rs new file mode 100644 index 00000000000..c4960b0c28e --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize-associated-type.rs @@ -0,0 +1,37 @@ +// Another regression test for #109815. + +// check-pass + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +trait X {} +trait Z { + type Assoc: X; +} +struct A<T>(T); + +impl X for () {} + +impl<T: X> Z for A<T> { + type Assoc = (); +} + +trait MyFrom<T> { + fn from(other: T) -> Self; +} + +impl<T> MyFrom<()> for T { + default fn from(other: ()) -> T { + panic!(); + } +} + +impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T { + fn from(other: ()) -> T { + panic!(); + } +} + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.rs b/tests/ui/specialization/min_specialization/specialize_nothing.rs new file mode 100644 index 00000000000..ef92254d465 --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_nothing.rs @@ -0,0 +1,14 @@ +#![feature(min_specialization)] + +trait Special { + fn be_special(); +} + +impl<T> Special for T { + fn be_special() {} +} + +impl Special for usize {} +//~^ ERROR specialization impl does not specialize any associated items + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/specialize_nothing.stderr b/tests/ui/specialization/min_specialization/specialize_nothing.stderr new file mode 100644 index 00000000000..65f73781cae --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_nothing.stderr @@ -0,0 +1,14 @@ +error: specialization impl does not specialize any associated items + --> $DIR/specialize_nothing.rs:11:1 + | +LL | impl Special for usize {} + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl is a specialization of this impl + --> $DIR/specialize_nothing.rs:7:1 + | +LL | impl<T> Special for T { + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.rs b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs new file mode 100644 index 00000000000..24e92a0abc3 --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.rs @@ -0,0 +1,33 @@ +// A regression test for #109815. + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +trait X {} +trait Y: X {} +trait Z { + type Assoc: Y; +} +struct A<T>(T); + +impl<T: X> Z for A<T> {} +//~^ ERROR not all trait items implemented + +trait MyFrom<T> { + fn from(other: T) -> Self; +} + +impl<T> MyFrom<T> for T { + default fn from(other: T) -> T { + other + } +} + +impl<T: X> MyFrom<<A<T> as Z>::Assoc> for T { + fn from(other: <A<T> as Z>::Assoc) -> T { + other + } +} + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr new file mode 100644 index 00000000000..cc12302bd8c --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_on_type_error.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Assoc` + --> $DIR/specialize_on_type_error.rs:14:1 + | +LL | type Assoc: Y; + | ------------- `Assoc` from trait +... +LL | impl<T: X> Z for A<T> {} + | ^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs new file mode 100644 index 00000000000..d90b81f717a --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.rs @@ -0,0 +1,50 @@ +// Regression test for #79457. + +#![feature(min_specialization)] + +use std::any::Any; + +pub trait Tr { + fn method(self) -> Box<dyn Any + 'static>; + fn other(self); +} + +impl<T: Any + 'static> Tr for T { + default fn method(self) -> Box<dyn Any + 'static> { + Box::new(self) + } + + default fn other(self) {} +} + +impl<'a> Tr for &'a i32 { + //~^ ERROR does not fulfill the required lifetime + fn other(self) {} +} + +fn promote_to_static<'a>(i: &'a i32) -> &'static i32 { + *i.method().downcast().unwrap() +} + +struct Wrapper<'a>(&'a i32); + +impl<'a> Tr for Wrapper<'a> { + //~^ ERROR does not fulfill the required lifetime + fn other(self) {} +} + +fn promote_to_static_2<'a>(w: Wrapper<'a>) -> Wrapper<'static> { + *w.method().downcast().unwrap() +} + +fn main() { + let i = Box::new(100_i32); + let static_i: &'static i32 = promote_to_static(&*i); + drop(i); + println!("{}", *static_i); + + let j = Box::new(200_i32); + let static_w: Wrapper<'static> = promote_to_static_2(Wrapper(&*j)); + drop(j); + println!("{}", *static_w.0); +} diff --git a/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr new file mode 100644 index 00000000000..2af75876d5b --- /dev/null +++ b/tests/ui/specialization/min_specialization/specialize_with_generalize_lifetimes.stderr @@ -0,0 +1,27 @@ +error[E0477]: the type `&'a i32` does not fulfill the required lifetime + --> $DIR/specialize_with_generalize_lifetimes.rs:20:1 + | +LL | impl<'a> Tr for &'a i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must satisfy the static lifetime as required by this binding + --> $DIR/specialize_with_generalize_lifetimes.rs:12:15 + | +LL | impl<T: Any + 'static> Tr for T { + | ^^^^^^^ + +error[E0477]: the type `Wrapper<'a>` does not fulfill the required lifetime + --> $DIR/specialize_with_generalize_lifetimes.rs:31:1 + | +LL | impl<'a> Tr for Wrapper<'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: type must satisfy the static lifetime as required by this binding + --> $DIR/specialize_with_generalize_lifetimes.rs:12:15 + | +LL | impl<T: Any + 'static> Tr for T { + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0477`. diff --git a/tests/ui/statics/issue-91050-1.rs b/tests/ui/statics/issue-91050-1.rs index 403a41462ef..f59bcf0b803 100644 --- a/tests/ui/statics/issue-91050-1.rs +++ b/tests/ui/statics/issue-91050-1.rs @@ -12,6 +12,8 @@ // // In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" +#![allow(drop_copy)] + pub mod before { #[no_mangle] pub static GLOBAL1: [u8; 1] = [1]; diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr index c23400a1d14..515cb9e12f8 100644 --- a/tests/ui/str/str-array-assignment.stderr +++ b/tests/ui/str/str-array-assignment.stderr @@ -10,10 +10,12 @@ error[E0308]: mismatched types --> $DIR/str-array-assignment.rs:5:27 | LL | let u: &str = if true { s[..2] } else { s }; - | ^^^^^^ - | | - | expected `&str`, found `str` - | help: consider borrowing here: `&s[..2]` + | ^^^^^^ expected `&str`, found `str` + | +help: consider borrowing here + | +LL | let u: &str = if true { &s[..2] } else { s }; + | + error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/str-array-assignment.rs:7:7 @@ -33,11 +35,14 @@ error[E0308]: mismatched types --> $DIR/str-array-assignment.rs:9:17 | LL | let w: &str = s[..2]; - | ---- ^^^^^^ - | | | - | | expected `&str`, found `str` - | | help: consider borrowing here: `&s[..2]` + | ---- ^^^^^^ expected `&str`, found `str` + | | | expected due to this + | +help: consider borrowing here + | +LL | let w: &str = &s[..2]; + | + error: aborting due to 4 previous errors diff --git a/tests/ui/structs-enums/issue-103869.fixed b/tests/ui/structs-enums/issue-103869.fixed new file mode 100644 index 00000000000..49fe32c7109 --- /dev/null +++ b/tests/ui/structs-enums/issue-103869.fixed @@ -0,0 +1,13 @@ +// run-rustfix + +struct VecOrMap { + //~^ HELP: perhaps you meant to use `struct` here + vec: Vec<usize>, + //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:` + //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` +} + +fn main() { + let o = VecOrMap { vec: vec![1, 2, 3] }; + println!("{:?}", o.vec); +} diff --git a/tests/ui/parser/issue-103869.rs b/tests/ui/structs-enums/issue-103869.rs index 9213437458a..729079e0501 100644 --- a/tests/ui/parser/issue-103869.rs +++ b/tests/ui/structs-enums/issue-103869.rs @@ -1,8 +1,13 @@ -enum VecOrMap{ +// run-rustfix + +enum VecOrMap { + //~^ HELP: perhaps you meant to use `struct` here vec: Vec<usize>, //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:` //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` - map: HashMap<String,usize> } -fn main() {} +fn main() { + let o = VecOrMap { vec: vec![1, 2, 3] }; + println!("{:?}", o.vec); +} diff --git a/tests/ui/parser/issue-103869.stderr b/tests/ui/structs-enums/issue-103869.stderr index 9eb20e2005a..4665ebf89a3 100644 --- a/tests/ui/parser/issue-103869.stderr +++ b/tests/ui/structs-enums/issue-103869.stderr @@ -1,12 +1,17 @@ error: expected one of `(`, `,`, `=`, `{`, or `}`, found `:` - --> $DIR/issue-103869.rs:2:8 + --> $DIR/issue-103869.rs:5:8 | -LL | enum VecOrMap{ +LL | enum VecOrMap { | -------- while parsing this enum +LL | LL | vec: Vec<usize>, | ^ expected one of `(`, `,`, `=`, `{`, or `}` | = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` +help: perhaps you meant to use `struct` here + | +LL | struct VecOrMap { + | ~~~~~~ error: aborting due to previous error diff --git a/tests/ui/suggestions/as-ref.stderr b/tests/ui/suggestions/as-ref.stderr index 0ee343ebf9f..2147d2d92e3 100644 --- a/tests/ui/suggestions/as-ref.stderr +++ b/tests/ui/suggestions/as-ref.stderr @@ -2,61 +2,73 @@ error[E0308]: mismatched types --> $DIR/as-ref.rs:7:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:8:39 | LL | opt.and_then(|arg| Some(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().and_then(|arg| Some(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:10:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:11:37 | LL | opt.and_then(|arg| Ok(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | opt.as_ref().and_then(|arg| Ok(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:13:29 @@ -101,61 +113,73 @@ error[E0308]: mismatched types --> $DIR/as-ref.rs:22:42 | LL | multiple_ref_opt.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_opt.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:23:52 | LL | multiple_ref_opt.and_then(|arg| Some(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_opt.as_ref().and_then(|arg| Some(takes_ref(arg))); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:25:45 | LL | multiple_ref_result.map(|arg| takes_ref(arg)); - | --- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().map` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_result.as_ref().map(|arg| takes_ref(arg)); + | +++++++++ error[E0308]: mismatched types --> $DIR/as-ref.rs:26:53 | LL | multiple_ref_result.and_then(|arg| Ok(takes_ref(arg))); - | -------- --------- ^^^ expected `&Foo`, found `Foo` - | | | - | | arguments to this function are incorrect - | help: consider using `as_ref` instead: `as_ref().and_then` + | --------- ^^^ expected `&Foo`, found `Foo` + | | + | arguments to this function are incorrect | note: function defined here --> $DIR/as-ref.rs:3:4 | LL | fn takes_ref(_: &Foo) {} | ^^^^^^^^^ ------- +help: consider using `as_ref` instead + | +LL | multiple_ref_result.as_ref().and_then(|arg| Ok(takes_ref(arg))); + | +++++++++ error: aborting due to 11 previous errors diff --git a/tests/ui/suggestions/derive-macro-missing-bounds.stderr b/tests/ui/suggestions/derive-macro-missing-bounds.stderr index c3f305c1770..bffcb1af487 100644 --- a/tests/ui/suggestions/derive-macro-missing-bounds.stderr +++ b/tests/ui/suggestions/derive-macro-missing-bounds.stderr @@ -36,7 +36,7 @@ LL | impl<T: Debug + Trait> Debug for Inner<T> { | unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&c::Inner<T>` to implement `Debug` - = note: required for the cast from `&c::Inner<T>` to the object type `dyn Debug` + = note: required for the cast from `&&c::Inner<T>` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -58,7 +58,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug, T: Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&d::Inner<T>` to implement `Debug` - = note: required for the cast from `&d::Inner<T>` to the object type `dyn Debug` + = note: required for the cast from `&&d::Inner<T>` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -80,7 +80,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug + Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&e::Inner<T>` to implement `Debug` - = note: required for the cast from `&e::Inner<T>` to the object type `dyn Debug` + = note: required for the cast from `&&e::Inner<T>` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -102,7 +102,7 @@ LL | impl<T: Debug> Debug for Inner<T> where T: Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&f::Inner<T>` to implement `Debug` - = note: required for the cast from `&f::Inner<T>` to the object type `dyn Debug` + = note: required for the cast from `&&f::Inner<T>` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | diff --git a/tests/ui/suggestions/issue-68049-2.stderr b/tests/ui/suggestions/issue-68049-2.stderr index de35aa5b186..6f3c78443f8 100644 --- a/tests/ui/suggestions/issue-68049-2.stderr +++ b/tests/ui/suggestions/issue-68049-2.stderr @@ -4,10 +4,10 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference LL | *input = self.0; | ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written | -help: consider changing that to be a mutable reference +help: consider changing this to be a mutable reference | -LL | fn example(&self, input: &mut i32); // should suggest here - | ~~~~~~~~ +LL | fn example(&self, input: &mut i32) { // should not suggest here + | +++ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference --> $DIR/issue-68049-2.rs:17:5 @@ -15,7 +15,7 @@ error[E0594]: cannot assign to `self.0`, which is behind a `&` reference LL | self.0 += *input; | ^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written | -help: consider changing that to be a mutable reference +help: consider changing this to be a mutable reference | LL | fn example(&mut self, input: &i32); // should suggest here | ~~~~~~~~~ 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/suggestions/suggest-borrow-to-dyn-object.rs b/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs deleted file mode 100644 index 120fc538307..00000000000 --- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::ffi::{OsStr, OsString}; -use std::path::Path; - -fn check(p: &dyn AsRef<Path>) { - let m = std::fs::metadata(&p); - println!("{:?}", &m); -} - -fn main() { - let s: OsString = ".".into(); - let s: &OsStr = &s; - check(s); - //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time - //~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]` - //~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>` -} diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr deleted file mode 100644 index 365c1016eb3..00000000000 --- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/suggest-borrow-to-dyn-object.rs:12:11 - | -LL | check(s); - | ^ doesn't have a size known at compile-time - | - = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]` -note: required because it appears within the type `OsStr` - --> $SRC_DIR/std/src/ffi/os_str.rs:LL:COL - = note: required for the cast from `OsStr` to the object type `dyn AsRef<Path>` -help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>` - | -LL | check(&s); - | + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/suggest-ref-macro.rs b/tests/ui/suggestions/suggest-ref-macro.rs index 6f780f32a14..730f5fa1b5e 100644 --- a/tests/ui/suggestions/suggest-ref-macro.rs +++ b/tests/ui/suggestions/suggest-ref-macro.rs @@ -14,7 +14,7 @@ macro_rules! bla { () => { x(123); //~^ ERROR mismatched types - //~| SUGGESTION &mut 123 + //~| SUGGESTION &mut }; ($v:expr) => { x($v) @@ -25,5 +25,5 @@ fn main() { bla!(); bla!(456); //~^ ERROR mismatched types - //~| SUGGESTION &mut 456 + //~| SUGGESTION &mut } diff --git a/tests/ui/suggestions/suggest-ref-macro.stderr b/tests/ui/suggestions/suggest-ref-macro.stderr index 17de49fbd84..08bc9e86a50 100644 --- a/tests/ui/suggestions/suggest-ref-macro.stderr +++ b/tests/ui/suggestions/suggest-ref-macro.stderr @@ -18,10 +18,8 @@ error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:15:11 | LL | x(123); - | - ^^^ - | | | - | | expected `&mut i32`, found integer - | | help: consider mutably borrowing here: `&mut 123` + | - ^^^ expected `&mut i32`, found integer + | | | arguments to this function are incorrect ... LL | bla!(); @@ -33,6 +31,10 @@ note: function defined here LL | fn x(_: &mut i32) {} | ^ ----------- = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider mutably borrowing here + | +LL | x(&mut 123); + | ++++ error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:26:10 @@ -41,16 +43,17 @@ LL | x($v) | - arguments to this function are incorrect ... LL | bla!(456); - | ^^^ - | | - | expected `&mut i32`, found integer - | help: consider mutably borrowing here: `&mut 456` + | ^^^ expected `&mut i32`, found integer | note: function defined here --> $DIR/suggest-ref-macro.rs:11:4 | LL | fn x(_: &mut i32) {} | ^ ----------- +help: consider mutably borrowing here + | +LL | bla!(&mut 456); + | ++++ error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/suggest-ref-mut.rs b/tests/ui/suggestions/suggest-ref-mut.rs index d04113ffccc..b40439b8e37 100644 --- a/tests/ui/suggestions/suggest-ref-mut.rs +++ b/tests/ui/suggestions/suggest-ref-mut.rs @@ -12,12 +12,10 @@ impl X { fn main() { let ref foo = 16; //~^ HELP - //~| SUGGESTION ref mut foo *foo = 32; //~^ ERROR if let Some(ref bar) = Some(16) { //~^ HELP - //~| SUGGESTION ref mut bar *bar = 32; //~^ ERROR } @@ -25,6 +23,5 @@ fn main() { ref quo => { *quo = 32; }, //~^ ERROR //~| HELP - //~| SUGGESTION ref mut quo } } diff --git a/tests/ui/suggestions/suggest-ref-mut.stderr b/tests/ui/suggestions/suggest-ref-mut.stderr index 7973759bf5e..cc00022ab8e 100644 --- a/tests/ui/suggestions/suggest-ref-mut.stderr +++ b/tests/ui/suggestions/suggest-ref-mut.stderr @@ -10,7 +10,7 @@ LL | fn zap(&mut self) { | ~~~~~~~~~ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:16:5 + --> $DIR/suggest-ref-mut.rs:15:5 | LL | *foo = 32; | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written @@ -18,10 +18,10 @@ LL | *foo = 32; help: consider changing this to be a mutable reference | LL | let ref mut foo = 16; - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to `*bar`, which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:21:9 + --> $DIR/suggest-ref-mut.rs:19:9 | LL | *bar = 32; | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written @@ -29,10 +29,10 @@ LL | *bar = 32; help: consider changing this to be a mutable reference | LL | if let Some(ref mut bar) = Some(16) { - | ~~~~~~~~~~~ + | +++ error[E0594]: cannot assign to `*quo`, which is behind a `&` reference - --> $DIR/suggest-ref-mut.rs:25:22 + --> $DIR/suggest-ref-mut.rs:23:22 | LL | ref quo => { *quo = 32; }, | ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written @@ -40,7 +40,7 @@ LL | ref quo => { *quo = 32; }, help: consider changing this to be a mutable reference | LL | ref mut quo => { *quo = 32; }, - | ~~~~~~~~~~~ + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.fixed b/tests/ui/suggestions/type-ascription-instead-of-let.fixed new file mode 100644 index 00000000000..e3d03b6f22a --- /dev/null +++ b/tests/ui/suggestions/type-ascription-instead-of-let.fixed @@ -0,0 +1,11 @@ +// run-rustfix + +fn fun(x: i32) -> i32 { x } + +fn main() { + let _closure_annotated = |value: i32| -> i32 { + let temp: i32 = fun(5i32); + //~^ ERROR expected identifier, found `:` + temp + value + 1 + }; +} diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.rs b/tests/ui/suggestions/type-ascription-instead-of-let.rs index 5ad60243298..6e1c86f9671 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-let.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-let.rs @@ -1,7 +1,9 @@ +// run-rustfix + fn fun(x: i32) -> i32 { x } fn main() { - let closure_annotated = |value: i32| -> i32 { + let _closure_annotated = |value: i32| -> i32 { temp: i32 = fun(5i32); //~^ ERROR expected identifier, found `:` temp + value + 1 diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.stderr b/tests/ui/suggestions/type-ascription-instead-of-let.stderr index fb697b0ccfd..065b1f4d353 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-let.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-let.stderr @@ -1,8 +1,13 @@ error: expected identifier, found `:` - --> $DIR/type-ascription-instead-of-let.rs:5:13 + --> $DIR/type-ascription-instead-of-let.rs:7:13 | LL | temp: i32 = fun(5i32); | ^ expected identifier + | +help: you might have meant to introduce a new binding + | +LL | let temp: i32 = fun(5i32); + | +++ error: aborting due to previous error diff --git a/tests/ui/issues/issue-12997-1.rs b/tests/ui/test-attrs/issue-12997-1.rs index 9f808dac362..9f808dac362 100644 --- a/tests/ui/issues/issue-12997-1.rs +++ b/tests/ui/test-attrs/issue-12997-1.rs diff --git a/tests/ui/issues/issue-12997-1.stderr b/tests/ui/test-attrs/issue-12997-1.stderr index 00c605174fb..00c605174fb 100644 --- a/tests/ui/issues/issue-12997-1.stderr +++ b/tests/ui/test-attrs/issue-12997-1.stderr diff --git a/tests/ui/issues/issue-12997-2.rs b/tests/ui/test-attrs/issue-12997-2.rs index 9df965315ab..9df965315ab 100644 --- a/tests/ui/issues/issue-12997-2.rs +++ b/tests/ui/test-attrs/issue-12997-2.rs diff --git a/tests/ui/issues/issue-12997-2.stderr b/tests/ui/test-attrs/issue-12997-2.stderr index 2a3d0e3457b..2a3d0e3457b 100644 --- a/tests/ui/issues/issue-12997-2.stderr +++ b/tests/ui/test-attrs/issue-12997-2.stderr diff --git a/tests/ui/issues/issue-34932.rs b/tests/ui/test-attrs/issue-34932.rs index ab568fd01ef..ab568fd01ef 100644 --- a/tests/ui/issues/issue-34932.rs +++ b/tests/ui/test-attrs/issue-34932.rs 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/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index 93d6770eb47..e7e8a796796 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -5,7 +5,7 @@ LL | let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct` | = help: the trait `Trait<&'static str>` is implemented for `Struct` - = note: required for the cast from `Struct` to the object type `dyn Trait<isize>` + = note: required for the cast from `Box<Struct>` to `Box<dyn Trait<isize>>` error: aborting due to previous error diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs index f031dd9ca48..558303c2e40 100644 --- a/tests/ui/traits/copy-guessing.rs +++ b/tests/ui/traits/copy-guessing.rs @@ -1,5 +1,8 @@ // run-pass + #![allow(dead_code)] +#![allow(drop_copy)] + // "guessing" in trait selection can affect `copy_or_move`. Check that this // is correctly handled. I am not sure what is the "correct" behaviour, // but we should at least not ICE. diff --git a/tests/ui/traits/impl-evaluation-order.rs b/tests/ui/traits/impl-evaluation-order.rs index 57809d89aa6..256ce992eef 100644 --- a/tests/ui/traits/impl-evaluation-order.rs +++ b/tests/ui/traits/impl-evaluation-order.rs @@ -6,6 +6,8 @@ // check-pass +#![allow(drop_copy)] + trait A { type B; } diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index 7064a39d21e..b174669545a 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,5 +1,4 @@ #[derive(Clone)] //~ trait objects must include the `dyn` keyword - //~| trait objects must include the `dyn` keyword struct Foo; trait Foo {} //~ the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index f9b7b814663..1037603ceb7 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:4:1 + --> $DIR/issue-106072.rs:3:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -16,15 +16,7 @@ LL | #[derive(Clone)] | = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/issue-106072.rs:1:10 - | -LL | #[derive(Clone)] - | ^^^^^ - | - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0428, E0782. For more information about an error, try `rustc --explain E0428`. diff --git a/tests/ui/traits/issue-20692.stderr b/tests/ui/traits/issue-20692.stderr index 2028994cdaa..30e3c9da1a0 100644 --- a/tests/ui/traits/issue-20692.stderr +++ b/tests/ui/traits/issue-20692.stderr @@ -27,8 +27,7 @@ LL | trait Array: Sized + Copy {} | | | | | ...because it requires `Self: Sized` | this trait cannot be made into an object... - = note: required for `&T` to implement `CoerceUnsized<&dyn Array>` - = note: required by cast to type `&dyn Array` + = note: required for the cast from `&T` to `&dyn Array` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr index 50d6fb05465..d5327602430 100644 --- a/tests/ui/traits/issue-38604.stderr +++ b/tests/ui/traits/issue-38604.stderr @@ -25,8 +25,7 @@ LL | trait Foo where u32: Q<Self> { | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... - = note: required for `Box<()>` to implement `CoerceUnsized<Box<dyn Foo>>` - = note: required by cast to type `Box<dyn Foo>` + = note: required for the cast from `Box<()>` to `Box<dyn Foo>` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr index 9ac5c4725ab..1c0e8bcf185 100644 --- a/tests/ui/traits/issue-7013.stderr +++ b/tests/ui/traits/issue-7013.stderr @@ -12,7 +12,7 @@ note: required because it appears within the type `B` | LL | struct B { | ^ - = note: required for the cast from `B` to the object type `dyn Foo + Send` + = note: required for the cast from `Box<B>` to `Box<dyn Foo + Send>` error: aborting due to previous error diff --git a/tests/ui/traits/map-types.stderr b/tests/ui/traits/map-types.stderr index f685c50b07d..4315056f206 100644 --- a/tests/ui/traits/map-types.stderr +++ b/tests/ui/traits/map-types.stderr @@ -5,7 +5,7 @@ LL | let y: Box<dyn Map<usize, isize>> = Box::new(x); | ^^^^^^^^^^^ the trait `Map<usize, isize>` is not implemented for `Box<dyn Map<isize, isize>>` | = help: the trait `Map<K, V>` is implemented for `HashMap<K, V>` - = note: required for the cast from `Box<dyn Map<isize, isize>>` to the object type `dyn Map<usize, isize>` + = note: required for the cast from `Box<Box<dyn Map<isize, isize>>>` to `Box<dyn Map<usize, isize>>` error: aborting due to previous error diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/new-solver/alias-bound-unsound.rs new file mode 100644 index 00000000000..00294c708f1 --- /dev/null +++ b/tests/ui/traits/new-solver/alias-bound-unsound.rs @@ -0,0 +1,27 @@ +// compile-flags: -Ztrait-solver=next + +// Makes sure that alias bounds are not unsound! + +#![feature(trivial_bounds)] + +trait Foo { + type Item: Copy + where + <Self as Foo>::Item: Copy; + + fn copy_me(x: &Self::Item) -> Self::Item { + *x + } +} + +impl Foo for () { + type Item = String where String: Copy; +} + +fn main() { + let x = String::from("hello, world"); + drop(<() as Foo>::copy_me(&x)); + //~^ ERROR `<() as Foo>::Item: Copy` is not satisfied + //~| ERROR `<() as Foo>::Item` is not well-formed + println!("{x}"); +} diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/new-solver/alias-bound-unsound.stderr new file mode 100644 index 00000000000..9a43d2a6639 --- /dev/null +++ b/tests/ui/traits/new-solver/alias-bound-unsound.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `<() as Foo>::Item: Copy` is not satisfied + --> $DIR/alias-bound-unsound.rs:23:10 + | +LL | drop(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `<() as Foo>::Item` + | +note: required by a bound in `Foo::Item` + --> $DIR/alias-bound-unsound.rs:10:30 + | +LL | type Item: Copy + | ---- required by a bound in this associated type +LL | where +LL | <Self as Foo>::Item: Copy; + | ^^^^ required by this bound in `Foo::Item` + +error: the type `<() as Foo>::Item` is not well-formed + --> $DIR/alias-bound-unsound.rs:23:10 + | +LL | drop(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr index 6a926534e07..4aefdd6bb07 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr @@ -1,5 +1,5 @@ error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely - --> $DIR/auto-with-drop_tracking_mir.rs:24:13 + --> $DIR/auto-with-drop_tracking_mir.rs:25:13 | LL | is_send(foo()); | ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely @@ -8,7 +8,7 @@ LL | is_send(foo()); | = help: the trait `Send` is not implemented for `impl Future<Output = ()>` note: required by a bound in `is_send` - --> $DIR/auto-with-drop_tracking_mir.rs:23:24 + --> $DIR/auto-with-drop_tracking_mir.rs:24:24 | LL | fn is_send(_: impl Send) {} | ^^^^ required by this bound in `is_send` diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs index a5db7c4636b..f115e143318 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs @@ -14,6 +14,7 @@ async fn foo() { #[cfg(fail)] let x = &NotSync; bar().await; + #[allow(drop_ref)] drop(x); } diff --git a/tests/ui/traits/new-solver/nested-alias-bound.rs b/tests/ui/traits/new-solver/nested-alias-bound.rs new file mode 100644 index 00000000000..c365902dbe5 --- /dev/null +++ b/tests/ui/traits/new-solver/nested-alias-bound.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait A { + type A: B; +} + +trait B { + type B: C; +} + +trait C {} + +fn needs_c<T: C>() {} + +fn test<T: A>() { + needs_c::<<T::A as B>::B>(); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs index 18ee0545700..c6c11a1a1de 100644 --- a/tests/ui/traits/new-solver/temporary-ambiguity.rs +++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs @@ -18,5 +18,5 @@ fn main() { let w = Wrapper(x); needs_foo(w); x = 1; - drop(x); + let _ = x; } diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr index 47fa29b6648..d56519223f4 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr @@ -20,8 +20,7 @@ LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables | | | this trait cannot be made into an object... - = note: required for `&()` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/supertrait-object-safety.rs:19:12 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/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr index dc18adeafc7..a51b6975938 100644 --- a/tests/ui/traits/object/safety.stderr +++ b/tests/ui/traits/object/safety.stderr @@ -11,8 +11,7 @@ LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); | ^^^ ...because associated function `foo` has no `self` parameter - = note: required for `&St` to implement `CoerceUnsized<&dyn Tr>` - = note: required by cast to type `&dyn Tr` + = note: required for the cast from `&St` to `&dyn Tr` help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self); diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr index 6c0e8b8af4b..74a0fc42708 100644 --- a/tests/ui/traits/test-2.stderr +++ b/tests/ui/traits/test-2.stderr @@ -76,8 +76,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } | this trait cannot be made into an object... = help: consider moving `dup` to another trait = help: consider moving `blah` to another trait - = note: required for `Box<{integer}>` to implement `CoerceUnsized<Box<dyn bar>>` - = note: required by cast to type `Box<dyn bar>` + = note: required for the cast from `Box<{integer}>` to `Box<dyn bar>` error: aborting due to 5 previous errors diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr index fe269d8e99b..82b4e9bd72a 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` | - = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>` + = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr index ef007d5cb90..856303ef4dd 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied LL | let _ = x as &dyn Bar<u32>; // Error | ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>` | - = note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>` + = note: required for the cast from `&&dyn Foo<i32>` to `&dyn Bar<u32>` error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>` --> $DIR/type-checking-test-2.rs:25:13 @@ -34,7 +34,7 @@ error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied LL | let a = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>` | - = note: required for the cast from `&dyn Foo<u32>` to the object type `dyn Bar<_>` + = note: required for the cast from `&&dyn Foo<u32>` to `&dyn Bar<_>` error: aborting due to 4 previous errors diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr index 39b60c31197..c054ddb893d 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr @@ -7,7 +7,7 @@ LL | *t help: consider changing this to be a mutable reference | LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { - | ~~~~~~~~~~~~~~~~~~~ + | +++ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6 @@ -18,7 +18,7 @@ LL | {*t} help: consider changing this to be a mutable reference | LL | fn copy_reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { - | ~~~~~~~~~~~~~~~~~~~ + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs index 3416503b851..6ed7667115a 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs @@ -1,6 +1,8 @@ // check-pass // Check tautalogically false `Copy` bounds + #![feature(trivial_bounds)] +#![allow(drop_ref, drop_copy)] fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds is_copy(&t); diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr index 1e26623899b..deeb352a2a8 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr @@ -1,5 +1,5 @@ warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51 + --> $DIR/trivial-bounds-inconsistent-copy.rs:7:51 | LL | fn copy_string(t: String) -> String where String: Copy { | ^^^^ @@ -7,19 +7,19 @@ LL | fn copy_string(t: String) -> String where String: Copy { = note: `#[warn(trivial_bounds)]` on by default warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56 + --> $DIR/trivial-bounds-inconsistent-copy.rs:14:56 | LL | fn copy_out_string(t: &String) -> String where String: Copy { | ^^^^ warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55 + --> $DIR/trivial-bounds-inconsistent-copy.rs:18:55 | LL | fn copy_string_with_param<T>(x: String) where String: Copy { | ^^^^ warning: trait bound for<'b> &'b mut i32: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76 + --> $DIR/trivial-bounds-inconsistent-copy.rs:24:76 | LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy { | ^^^^ diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 551815d021a..58eaa9c2c42 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -5,15 +5,16 @@ trait Trait { type Opaque1; type Opaque2; - fn constrain(self); + fn constrain(self) -> (Self::Opaque1, Self::Opaque2); } impl<'a> Trait for &'a () { type Opaque1 = impl Sized; type Opaque2 = impl Sized + 'a; - fn constrain(self) { - let _: Self::Opaque1 = (); - let _: Self::Opaque2 = self; + fn constrain(self) -> (Self::Opaque1, Self::Opaque2) { + let a: Self::Opaque1 = (); + let b: Self::Opaque2 = self; + (a, b) } } diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs new file mode 100644 index 00000000000..93c52126d69 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs @@ -0,0 +1,16 @@ +#![feature(impl_trait_in_assoc_type)] + +trait Foo { + type Foo; + fn bar(); +} + +impl Foo for () { + type Foo = impl std::fmt::Debug; + fn bar() { + let x: Self::Foo = (); + //~^ ERROR: mismatched types + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr new file mode 100644 index 00000000000..2beed73cb85 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- the expected opaque type +LL | fn bar() { +LL | let x: Self::Foo = (); + | --------- ^^ expected opaque type, found `()` + | | + | expected due to this + | + = note: expected opaque type `<() as Foo>::Foo` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5 + | +LL | fn bar() { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr index fa16d321890..af758d8099f 100644 --- a/tests/ui/type-alias-impl-trait/issue-98604.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr @@ -4,7 +4,7 @@ error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<O LL | Box::new(test) as AsyncFnPtr; | ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>` + = note: required for the cast from `Box<fn() -> impl Future<Output = ()> {test}>` to `Box<(dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> + 'static)>` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr index 506d40cb776..9b651008371 100644 --- a/tests/ui/type-alias-impl-trait/issue-98608.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr @@ -9,7 +9,7 @@ LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi); | = note: expected struct `Box<u8>` found opaque type `impl Sized` - = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box<u8>` + = note: required for the cast from `Box<fn() -> impl Sized {hi}>` to `Box<dyn Fn() -> Box<u8>>` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr new file mode 100644 index 00000000000..9e96323ab54 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr @@ -0,0 +1,25 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-in-associated-type.rs:36:23 + | +LL | type Opaque = impl Sized + 'a; + | ^^^^^^^^^^^^^^^ ...so that the type `&'a T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for () { + | ++++ + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-in-associated-type.rs:36:23 + | +LL | type Opaque = impl Sized + 'a; + | ^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for () { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs new file mode 100644 index 00000000000..31fbef9f78f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs @@ -0,0 +1,45 @@ +// WF check for impl Trait in associated type position. +// +// revisions: pass fail +// [pass] check-pass +// [fail] check-fail + +#![feature(impl_trait_in_assoc_type)] + +// The hidden type here (`&'a T`) requires proving `T: 'a`. +// We know it holds because of implied bounds from the impl header. +#[cfg(pass)] +mod pass { + trait Trait<Req> { + type Opaque1; + fn constrain_opaque1(req: Req) -> Self::Opaque1; + } + + impl<'a, T> Trait<&'a T> for () { + type Opaque1 = impl IntoIterator<Item = impl Sized + 'a>; + fn constrain_opaque1(req: &'a T) -> Self::Opaque1 { + [req] + } + } +} + +// The hidden type here (`&'a T`) requires proving `T: 'a`, +// but that is not known to hold in the impl. +#[cfg(fail)] +mod fail { + trait Trait<'a, T> { + type Opaque; + fn constrain_opaque(req: &'a T) -> Self::Opaque; + } + + impl<'a, T> Trait<'a, T> for () { + type Opaque = impl Sized + 'a; + //[fail]~^ ERROR the parameter type `T` may not live long enough + //[fail]~| ERROR the parameter type `T` may not live long enough + fn constrain_opaque(req: &'a T) -> Self::Opaque { + req + } + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr new file mode 100644 index 00000000000..753a46e882e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr @@ -0,0 +1,19 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-nested.rs:55:27 + | +LL | type InnerOpaque<T> = impl Sized; + | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/wf-nested.rs:12:20 + | +LL | struct IsStatic<T: 'static>(T); + | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | type InnerOpaque<T: 'static> = impl Sized; + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr new file mode 100644 index 00000000000..9ab6685a7f7 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr @@ -0,0 +1,14 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-nested.rs:46:17 + | +LL | let _ = outer.get(); + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test<T: 'static>() { + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs new file mode 100644 index 00000000000..de388329489 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.rs @@ -0,0 +1,60 @@ +// Well-formedness of nested opaque types, i.e. `impl Sized` in +// `type Outer = impl Trait<Assoc = impl Sized>`. +// See the comments below. +// +// revisions: pass pass_sound fail +// [pass] check-pass +// [pass_sound] check-fail +// [fail] check-fail + +#![feature(type_alias_impl_trait)] + +struct IsStatic<T: 'static>(T); + +trait Trait<In> { + type Out; + + fn get(&self) -> Result<Self::Out, ()> { + Err(()) + } +} + +impl<T> Trait<&'static T> for () { + type Out = IsStatic<T>; +} + +// The hidden type for `impl Sized` is `IsStatic<T>`, which requires `T: 'static`. +// We know it is well-formed because it can *only* be referenced as a projection: +// <OuterOpaque<T> as Trait<&'static T>>::Out`. +// So any instantiation of the type already requires proving `T: 'static`. +#[cfg(pass)] +mod pass { + use super::*; + type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>; + fn define<T>() -> OuterOpaque<T> {} +} + +// Test the soundness of `pass` - We should require `T: 'static` at the use site. +#[cfg(pass_sound)] +mod pass_sound { + use super::*; + type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>; + fn define<T>() -> OuterOpaque<T> {} + + fn test<T>() { + let outer = define::<T>(); + let _ = outer.get(); //[pass_sound]~ ERROR `T` may not live long enough + } +} + +// Similar to `pass` but here `impl Sized` can be referenced directly as +// InnerOpaque<T>, so we require an explicit bound `T: 'static`. +#[cfg(fail)] +mod fail { + use super::*; + type InnerOpaque<T> = impl Sized; //[fail]~ ERROR `T` may not live long enough + type OuterOpaque<T> = impl Trait<&'static T, Out = InnerOpaque<T>>; + fn define<T>() -> OuterOpaque<T> {} +} + +fn main() {} diff --git a/tests/ui/type/issue-58355.stderr b/tests/ui/type/issue-58355.stderr index 6f89a7b0049..67078bcfe89 100644 --- a/tests/ui/type/issue-58355.stderr +++ b/tests/ui/type/issue-58355.stderr @@ -6,7 +6,7 @@ LL | x = Some(Box::new(callback)); | = help: within `fn() -> dyn ToString`, the trait `Sized` is not implemented for `dyn ToString` = note: required because it appears within the type `fn() -> dyn ToString` - = note: required for the cast from `fn() -> dyn ToString` to the object type `dyn Fn() -> (dyn ToString + 'static)` + = note: required for the cast from `Box<fn() -> dyn ToString>` to `Box<dyn Fn() -> (dyn ToString + 'static)>` error: aborting due to previous error diff --git a/tests/ui/type/missing-let-in-binding-2.fixed b/tests/ui/type/missing-let-in-binding-2.fixed new file mode 100644 index 00000000000..d64013c8c83 --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-2.fixed @@ -0,0 +1,5 @@ +// run-rustfix + +fn main() { + let _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:` +} diff --git a/tests/ui/type/missing-let-in-binding-2.rs b/tests/ui/type/missing-let-in-binding-2.rs new file mode 100644 index 00000000000..f95f7bef215 --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-2.rs @@ -0,0 +1,5 @@ +// run-rustfix + +fn main() { + _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:` +} diff --git a/tests/ui/type/missing-let-in-binding-2.stderr b/tests/ui/type/missing-let-in-binding-2.stderr new file mode 100644 index 00000000000..2e10125943e --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-2.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found `:` + --> $DIR/missing-let-in-binding-2.rs:4:7 + | +LL | _v: Vec<i32> = vec![1, 2, 3]; + | ^ expected identifier + | +help: you might have meant to introduce a new binding + | +LL | let _v: Vec<i32> = vec![1, 2, 3]; + | +++ + +error: aborting due to previous error + diff --git a/tests/ui/type/missing-let-in-binding-3.rs b/tests/ui/type/missing-let-in-binding-3.rs new file mode 100644 index 00000000000..d56b1393336 --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-3.rs @@ -0,0 +1,5 @@ +struct A { + : :u8, //~ ERROR expected identifier, found `:` +} + +fn main() {} diff --git a/tests/ui/type/missing-let-in-binding-3.stderr b/tests/ui/type/missing-let-in-binding-3.stderr new file mode 100644 index 00000000000..ca828ce37eb --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-3.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `:` + --> $DIR/missing-let-in-binding-3.rs:2:5 + | +LL | struct A { + | - while parsing this struct +LL | : :u8, + | ^ expected identifier + +error: aborting due to previous error + diff --git a/tests/ui/type/missing-let-in-binding-4.rs b/tests/ui/type/missing-let-in-binding-4.rs new file mode 100644 index 00000000000..879a6fedcd6 --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-4.rs @@ -0,0 +1,5 @@ +struct A { + : u8 =, //~ ERROR expected identifier, found `:` +} + +fn main() {} diff --git a/tests/ui/type/missing-let-in-binding-4.stderr b/tests/ui/type/missing-let-in-binding-4.stderr new file mode 100644 index 00000000000..e6f173a6658 --- /dev/null +++ b/tests/ui/type/missing-let-in-binding-4.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `:` + --> $DIR/missing-let-in-binding-4.rs:2:5 + | +LL | struct A { + | - while parsing this struct +LL | : u8 =, + | ^ expected identifier + +error: aborting due to previous error + 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-mismatch.stderr b/tests/ui/type/type-mismatch.stderr index 67a1f893050..ce6f29d354f 100644 --- a/tests/ui/type/type-mismatch.stderr +++ b/tests/ui/type/type-mismatch.stderr @@ -378,10 +378,8 @@ error[E0308]: mismatched types --> $DIR/type-mismatch.rs:47:23 | LL | want::<&Foo<foo>>(f); - | ----------------- ^ - | | | - | | expected `&Foo<foo>`, found `Foo<foo>` - | | help: consider borrowing here: `&f` + | ----------------- ^ expected `&Foo<foo>`, found `Foo<foo>` + | | | arguments to this function are incorrect | = note: expected reference `&Foo<foo>` @@ -391,6 +389,10 @@ note: function defined here | LL | fn want<T>(t: T) {} | ^^^^ ---- +help: consider borrowing here + | +LL | want::<&Foo<foo>>(&f); + | + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:48:26 @@ -556,10 +558,8 @@ error[E0308]: mismatched types --> $DIR/type-mismatch.rs:61:26 | LL | want::<&Foo<foo, B>>(f); - | -------------------- ^ - | | | - | | expected `&Foo<foo, B>`, found `Foo<foo, B>` - | | help: consider borrowing here: `&f` + | -------------------- ^ expected `&Foo<foo, B>`, found `Foo<foo, B>` + | | | arguments to this function are incorrect | = note: expected reference `&Foo<foo, B>` @@ -569,6 +569,10 @@ note: function defined here | LL | fn want<T>(t: T) {} | ^^^^ ---- +help: consider borrowing here + | +LL | want::<&Foo<foo, B>>(&f); + | + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:65:19 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/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr index cdb23372c4b..f9cdb280e27 100644 --- a/tests/ui/typeck/bad-index-due-to-nested.stderr +++ b/tests/ui/typeck/bad-index-due-to-nested.stderr @@ -42,13 +42,14 @@ error[E0308]: mismatched types LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { | - this type parameter LL | map[k] - | ^ - | | - | expected `&K`, found type parameter `K` - | help: consider borrowing here: `&k` + | ^ expected `&K`, found type parameter `K` | = note: expected reference `&K` found type parameter `K` +help: consider borrowing here + | +LL | map[&k] + | + error[E0308]: mismatched types --> $DIR/bad-index-due-to-nested.rs:20:5 @@ -56,13 +57,14 @@ error[E0308]: mismatched types LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { | - this type parameter ----- expected `&'a V` because of return type LL | map[k] - | ^^^^^^ - | | - | expected `&V`, found type parameter `V` - | help: consider borrowing here: `&map[k]` + | ^^^^^^ expected `&V`, found type parameter `V` | = note: expected reference `&'a V` found type parameter `V` +help: consider borrowing here + | +LL | &map[k] + | + error: aborting due to 4 previous errors diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr index 72533ab1fa3..b9b3a5fe5ec 100644 --- a/tests/ui/typeck/bad-type-in-vec-contains.stderr +++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr @@ -2,16 +2,18 @@ error[E0308]: mismatched types --> $DIR/bad-type-in-vec-contains.rs:5:21 | LL | primes.contains(3); - | -------- ^ - | | | - | | expected `&_`, found integer - | | help: consider borrowing here: `&3` + | -------- ^ expected `&_`, found integer + | | | arguments to this method are incorrect | = note: expected reference `&_` found type `{integer}` note: method defined here --> $SRC_DIR/core/src/slice/mod.rs:LL:COL +help: consider borrowing here + | +LL | primes.contains(&3); + | + error: aborting due to previous error diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr index 11d34f5b93b..8ecb8b68016 100644 --- a/tests/ui/typeck/issue-13853.stderr +++ b/tests/ui/typeck/issue-13853.stderr @@ -20,10 +20,8 @@ error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 | LL | iterate(graph); - | ------- ^^^^^ - | | | - | | expected `&_`, found `Vec<Stuff>` - | | help: consider borrowing here: `&graph` + | ------- ^^^^^ expected `&_`, found `Vec<Stuff>` + | | | arguments to this function are incorrect | = note: expected reference `&_` @@ -33,6 +31,10 @@ note: function defined here | LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) { | ^^^^^^^ --------- +help: consider borrowing here + | +LL | iterate(&graph); + | + error: aborting due to 3 previous errors 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/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr index d456c16de0d..8741b35cdcf 100644 --- a/tests/ui/unsized-locals/suggest-borrow.stderr +++ b/tests/ui/unsized-locals/suggest-borrow.stderr @@ -16,11 +16,14 @@ error[E0308]: mismatched types --> $DIR/suggest-borrow.rs:3:20 | LL | let x: &[u8] = vec!(1, 2, 3)[..]; - | ----- ^^^^^^^^^^^^^^^^^ - | | | - | | expected `&[u8]`, found `[{integer}]` - | | help: consider borrowing here: `&vec!(1, 2, 3)[..]` + | ----- ^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `[{integer}]` + | | | expected due to this + | +help: consider borrowing here + | +LL | let x: &[u8] = &vec!(1, 2, 3)[..]; + | + error[E0308]: mismatched types --> $DIR/suggest-borrow.rs:4:19 diff --git a/tests/ui/unsized/unsized-fn-param.stderr b/tests/ui/unsized/unsized-fn-param.stderr index b4772605432..0de3dbbb557 100644 --- a/tests/ui/unsized/unsized-fn-param.stderr +++ b/tests/ui/unsized/unsized-fn-param.stderr @@ -5,8 +5,8 @@ LL | foo11("bar", &"baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef<Path>` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>` + = note: required for the cast from `&'static str` to `&dyn AsRef<Path>` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<Path>` | LL | foo11(&"bar", &"baz"); | + @@ -18,8 +18,8 @@ LL | foo12(&"bar", "baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef<Path>` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>` + = note: required for the cast from `&'static str` to `&dyn AsRef<Path>` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<Path>` | LL | foo12(&"bar", &"baz"); | + @@ -31,8 +31,8 @@ LL | foo21("bar", &"baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef<str>` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>` + = note: required for the cast from `&'static str` to `&dyn AsRef<str>` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<str>` | LL | foo21(&"bar", &"baz"); | + @@ -44,8 +44,8 @@ LL | foo22(&"bar", "baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef<str>` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>` + = note: required for the cast from `&'static str` to `&dyn AsRef<str>` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef<str>` | LL | foo22(&"bar", &"baz"); | + 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/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 6cf4f33f947..40a25c7df6b 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -11,8 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>` - = note: required by cast to type `Box<dyn Trait>` + = note: required for the cast from `Box<S>` to `Box<dyn Trait>` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 @@ -27,8 +26,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>` - = note: required by cast to type `Box<(dyn Trait + 'static)>` + = note: required for the cast from `Box<S>` to `Box<(dyn Trait + 'static)>` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 @@ -43,8 +41,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box<S>` to implement `CoerceUnsized<Box<dyn Trait>>` - = note: required by cast to type `Box<dyn Trait>` + = note: required for the cast from `Box<S>` to `Box<dyn Trait>` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr index c9bd4549aaf..e2c71df2feb 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -11,8 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 @@ -27,8 +26,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 @@ -43,8 +41,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr index d2b41630976..66504e44060 100644 --- a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -25,8 +25,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 @@ -45,8 +44,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&R` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&R` to `&dyn Trait` error: aborting due to 3 previous errors 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", |