diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 6ddd9f2c1fb5a..25b295c162aab 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -1,6 +1,7 @@ use std::num::NonZero; use rustc_errors::ErrorGuaranteed; +use rustc_feature::ACCEPTED_LANG_FEATURES; use rustc_hir::target::GenericParamKind; use rustc_hir::{ DefaultBodyStability, MethodKind, PartialConstStability, Stability, StabilityLevel, @@ -366,7 +367,7 @@ pub(crate) fn parse_stability( } } -// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` +/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` /// attribute, and return the feature name and its stability information. pub(crate) fn parse_unstability( cx: &AcceptContext<'_, '_, S>, @@ -451,6 +452,16 @@ pub(crate) fn parse_unstability( match (feature, issue) { (Ok(feature), Ok(_)) => { + // Stable *language* features shouldn't be used as unstable library features. + // (Not doing this for stable library features is checked by tidy.) + if ACCEPTED_LANG_FEATURES.iter().any(|f| f.name == feature) { + cx.emit_err(session_diagnostics::UnstableAttrForAlreadyStableFeature { + attr_span: cx.attr_span, + item_span: cx.target_span, + }); + return None; + } + let level = StabilityLevel::Unstable { reason: UnstableReason::from_opt_reason(reason), issue: issue_num, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 0694889488687..bab830098f1a8 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -1046,3 +1046,14 @@ pub(crate) struct CustomMirIncompatibleDialectAndPhase { #[label("... is not compatible with this phase")] pub phase_span: Span, } + +#[derive(Diagnostic)] +#[diag("can't mark as unstable using an already stable feature")] +pub(crate) struct UnstableAttrForAlreadyStableFeature { + #[primary_span] + #[label("this feature is already stable")] + #[help("consider removing the attribute")] + pub attr_span: Span, + #[label("the stability attribute annotates this item")] + pub item_span: Span, +} diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 2423880ab8696..45e16a735fed6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -394,8 +394,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { // ABI bugs et al. (full // list at ) (Arch::PowerPC | Arch::PowerPC64, _) => false, - // ABI unsupported - (Arch::Sparc, _) => false, + // ABI unsupported (fixed in llvm22) + (Arch::Sparc, _) if major < 22 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // There are no known problems on other platforms, so the only requirement is that symbols diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 881165706a034..51f33691bb7dd 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -866,6 +866,13 @@ pub enum PatKind<'tcx> { pats: Box<[Pat<'tcx>]>, }, + /// A guard pattern, e.g. `x if guard(x)` + Guard { + subpattern: Box>, + #[type_visitable(ignore)] + condition: ExprId, + }, + /// A never pattern `!`. Never, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index c17e15513cdf2..aa1b6b1663bfd 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -247,6 +247,12 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor: &mut V, pat: &'thir Pat<'tcx>, ) { + if let PatKind::Guard { subpattern, condition } = &pat.kind { + visitor.visit_pat(subpattern); + visitor.visit_expr(&visitor.thir()[*condition]); + return; + }; + for_each_immediate_subpat(pat, |p| visitor.visit_pat(p)); } @@ -287,5 +293,9 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( callback(pat); } } + + PatKind::Guard { subpattern, .. } => { + callback(subpattern); + } } } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index 7698af4cd38b0..cbe31fd7d1325 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -360,6 +360,11 @@ impl<'tcx> MatchPairTree<'tcx> { Some(TestableCase::Deref { temp, mutability }) } + PatKind::Guard { .. } => { + // FIXME(guard_patterns) + None + } + PatKind::Never => Some(TestableCase::Never), }; diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index d7edf82ae4aff..d4f5fe84e0ff9 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -944,6 +944,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visit_subpat(self, subpattern, user_tys, f); } } + PatKind::Guard { ref subpattern, .. } => { + visit_subpat(self, subpattern, user_tys, f); + } } } } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index ee35539221e69..aed0c6e6085d3 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -315,6 +315,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { | PatKind::Range { .. } | PatKind::Slice { .. } | PatKind::Array { .. } + | PatKind::Guard { .. } // Never constitutes a witness of uninhabitedness. | PatKind::Never => { self.requires_unsafe(pat.span, AccessToUnionField); diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index b108dff5555ff..ea27252ad6ce8 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -83,6 +83,7 @@ impl<'tcx> ThirBuildCx<'tcx> { } Some(_) | None => local.span, }; + let initializer = local.init.map(|init| self.mirror_expr(init)); let stmt = Stmt { kind: StmtKind::Let { remainder_scope, @@ -91,7 +92,7 @@ impl<'tcx> ThirBuildCx<'tcx> { data: region::ScopeData::Node, }, pattern, - initializer: local.init.map(|init| self.mirror_expr(init)), + initializer, else_block, hir_id: local.hir_id, span, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c646b0fc45ea1..b79bda2044058 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -876,7 +876,7 @@ impl<'tcx> ThirBuildCx<'tcx> { }; let indices = self.typeck_results.offset_of_data().get(expr.hir_id).unwrap(); - let mut expr = None::>; + let mut expr = None::>; for &(container, variant, field) in indices.iter() { let next = mk_call(&mut self.thir, container, variant, field); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 60cb509ee9dd2..7f4b70b956140 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -13,14 +13,14 @@ use rustc_middle::thir::*; use rustc_middle::ty::{self, TyCtxt}; /// Query implementation for [`TyCtxt::thir_body`]. -pub(crate) fn thir_body( - tcx: TyCtxt<'_>, +pub(crate) fn thir_body<'tcx>( + tcx: TyCtxt<'tcx>, owner_def: LocalDefId, -) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { +) -> Result<(&'tcx Steal>, ExprId), ErrorGuaranteed> { debug_assert!(!tcx.is_type_const(owner_def.to_def_id()), "thir_body queried for type_const"); let body = tcx.hir_body_owned_by(owner_def); - let mut cx = ThirBuildCx::new(tcx, owner_def); + let mut cx: ThirBuildCx<'tcx> = ThirBuildCx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); } @@ -50,7 +50,7 @@ pub(crate) fn thir_body( } /// Context for lowering HIR to THIR for a single function body (or other kind of body). -struct ThirBuildCx<'tcx> { +pub(crate) struct ThirBuildCx<'tcx> { tcx: TyCtxt<'tcx>, /// The THIR data that this context is building. thir: Thir<'tcx>, @@ -118,6 +118,7 @@ impl<'tcx> ThirBuildCx<'tcx> { let_stmt_type: Option<&hir::Ty<'tcx>>, ) -> Box> { crate::thir::pattern::pat_from_hir( + self, self.tcx, self.typing_env, self.typeck_results, @@ -201,7 +202,7 @@ impl<'tcx> ThirBuildCx<'tcx> { fn_sig.inputs()[index] }; - let pat = self.pattern_from_hir(param.pat); + let pat: Box> = self.pattern_from_hir(param.pat); Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) } }) } 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 ff9d456f7e708..ff4778dacc8d0 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 @@ -25,7 +25,7 @@ use crate::errors::{ PointerPattern, TypeNotPartialEq, TypeNotStructural, UnionPattern, UnsizedPattern, }; -impl<'tcx> PatCtxt<'tcx> { +impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> { /// Converts a constant to a pattern (if possible). /// This means aggregate values (like structs and enums) are converted /// to a pattern that matches the value (as if you'd compared via structural equality). @@ -61,7 +61,7 @@ struct ConstToPat<'tcx> { } impl<'tcx> ConstToPat<'tcx> { - fn new(pat_ctxt: &PatCtxt<'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { + fn new(pat_ctxt: &PatCtxt<'tcx, '_>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self { trace!(?pat_ctxt.typeck_results.hir_owner); ConstToPat { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, id, c } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index fec2fb9ca5719..7d4e25cd814b9 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -30,9 +30,11 @@ use tracing::{debug, instrument}; pub(crate) use self::check_match::check_match; use self::migration::PatMigration; use crate::errors::*; +use crate::thir::cx::ThirBuildCx; /// Context for lowering HIR patterns to THIR patterns. -struct PatCtxt<'tcx> { +struct PatCtxt<'tcx, 'ptcx> { + upper: &'ptcx mut ThirBuildCx<'tcx>, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, @@ -41,8 +43,9 @@ struct PatCtxt<'tcx> { rust_2024_migration: Option>, } -#[instrument(level = "debug", skip(tcx, typing_env, typeck_results), ret)] -pub(super) fn pat_from_hir<'tcx>( +#[instrument(level = "debug", skip(upper, tcx, typing_env, typeck_results), ret)] +pub(super) fn pat_from_hir<'tcx, 'ptcx>( + upper: &'ptcx mut ThirBuildCx<'tcx>, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, @@ -51,6 +54,7 @@ pub(super) fn pat_from_hir<'tcx>( let_stmt_type: Option<&hir::Ty<'tcx>>, ) -> Box> { let mut pcx = PatCtxt { + upper, tcx, typing_env, typeck_results, @@ -87,7 +91,7 @@ pub(super) fn pat_from_hir<'tcx>( thir_pat } -impl<'tcx> PatCtxt<'tcx> { +impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> { fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box> { let adjustments: &[PatAdjustment<'tcx>] = self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v); @@ -443,8 +447,10 @@ impl<'tcx> PatCtxt<'tcx> { hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) }, - // FIXME(guard_patterns): implement guard pattern lowering - hir::PatKind::Guard(pat, _) => self.lower_pattern(pat).kind, + hir::PatKind::Guard(pat, condition) => PatKind::Guard { + subpattern: self.lower_pattern(pat), + condition: self.upper.mirror_expr(condition), + }, hir::PatKind::Err(guar) => PatKind::Error(guar), }; diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 27dec99696f5f..ea34e5f4d97df 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -844,6 +844,14 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, "]", depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } + PatKind::Guard { subpattern, condition } => { + print_indented!(self, "Guard pattern: {", depth_lvl + 1); + print_indented!(self, "subpattern: ", depth_lvl + 2); + self.print_pat(subpattern, depth_lvl + 3); + print_indented!(self, "guard: ", depth_lvl + 2); + self.print_expr(*condition, depth_lvl + 3); + print_indented!(self, "}", depth_lvl + 1); + } PatKind::Error(_) => { print_indented!(self, "Error", depth_lvl + 1); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9945802d70c14..a8ca8011b5710 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -16,10 +16,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordMap; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey, msg}; -use rustc_feature::{ - ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, - BuiltinAttribute, -}; +use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; use rustc_hir::attrs::diagnostic::Directive; use rustc_hir::attrs::{ AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr, @@ -30,8 +27,7 @@ use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ self as hir, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParamKind, HirId, - Item, ItemKind, MethodKind, Node, ParamName, PartialConstStability, Safety, Stability, - StabilityLevel, Target, TraitItem, find_attr, + Item, ItemKind, MethodKind, Node, ParamName, Safety, Target, TraitItem, find_attr, }; use rustc_macros::Diagnostic; use rustc_middle::hir::nested_filter; @@ -156,16 +152,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::ProcMacroDerive { .. }) => { self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } - Attribute::Parsed( - AttributeKind::Stability { - span: attr_span, - stability: Stability { level, feature }, - } - | AttributeKind::RustcConstStability { - span: attr_span, - stability: PartialConstStability { level, feature, .. }, - }, - ) => self.check_stability(*attr_span, span, level, *feature), Attribute::Parsed(AttributeKind::Inline(InlineAttr::Force { .. }, ..)) => {} // handled separately below Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => { self.check_inline(hir_id, *attr_span, kind, target) @@ -312,6 +298,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::RustcCoinductive(..) | AttributeKind::RustcConfusables { .. } + | AttributeKind::RustcConstStability { .. } | AttributeKind::RustcConstStableIndirect | AttributeKind::RustcConversionSuggestion | AttributeKind::RustcDeallocator @@ -384,6 +371,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcTrivialFieldReads | AttributeKind::RustcUnsafeSpecializationMarker(..) | AttributeKind::ShouldPanic { .. } + | AttributeKind::Stability { .. } | AttributeKind::TestRunner(..) | AttributeKind::ThreadLocal | AttributeKind::TypeLengthLimit { .. } @@ -1570,24 +1558,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_stability( - &self, - attr_span: Span, - item_span: Span, - level: &StabilityLevel, - feature: Symbol, - ) { - // Stable *language* features shouldn't be used as unstable library features. - // (Not doing this for stable library features is checked by tidy.) - if level.is_unstable() - && ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() - { - self.tcx - .dcx() - .emit_err(errors::UnstableAttrForAlreadyStableFeature { attr_span, item_span }); - } - } - fn check_deprecated(&self, hir_id: HirId, attr_span: Span, target: Target) { match target { Target::AssocConst | Target::Method(..) | Target::AssocTy diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6efbcd7bf85b6..5e84122fcb10e 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -871,17 +871,6 @@ pub(crate) struct CannotStabilizeDeprecated { pub item_sp: Span, } -#[derive(Diagnostic)] -#[diag("can't mark as unstable using an already stable feature")] -pub(crate) struct UnstableAttrForAlreadyStableFeature { - #[primary_span] - #[label("this feature is already stable")] - #[help("consider removing the attribute")] - pub attr_span: Span, - #[label("the stability attribute annotates this item")] - pub item_span: Span, -} - #[derive(Diagnostic)] #[diag("{$descr} has missing stability attribute")] pub(crate) struct MissingStabilityAttr<'a> { diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index dc38f2d8bc70f..0226c54db58cd 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -462,7 +462,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let arity; let fields: Vec<_>; match &pat.kind { - PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat), + PatKind::Binding { subpattern: Some(subpat), .. } + | PatKind::Guard { subpattern: subpat, .. } => return self.lower_pat(subpat), PatKind::Missing | PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { ctor = Wildcard; fields = vec![]; diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index 3eb8ca44a9d14..99ebcb4ada296 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -1,4 +1,4 @@ -use core::{ptr, slice}; +use core::ptr; use super::{Drain, Vec}; use crate::alloc::{Allocator, Global}; @@ -107,15 +107,13 @@ impl Drain<'_, T, A> { let vec = unsafe { self.vec.as_mut() }; let range_start = vec.len; let range_end = self.tail_start; - let range_slice = unsafe { - slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start) - }; + // The elements in this range are not initialized so we avoid creating a slice. - for place in range_slice { + for idx in range_start..range_end { let Some(new_item) = replace_with.next() else { return false; }; - unsafe { ptr::write(place, new_item) }; + unsafe { vec.as_mut_ptr().add(idx).write(new_item) }; vec.len += 1; } true diff --git a/library/std/src/io/copy/tests.rs b/library/std/src/io/copy/tests.rs index 25b1ece2745b9..7bdba3a04416e 100644 --- a/library/std/src/io/copy/tests.rs +++ b/library/std/src/io/copy/tests.rs @@ -97,16 +97,17 @@ fn copy_specializes_to_vec() { #[test] fn copy_specializes_from_vecdeque() { - let mut source = VecDeque::with_capacity(100 * 1024); - for _ in 0..20 * 1024 { + let num: usize = if cfg!(miri) { 512 } else { 20 * 1024 }; + let mut source = VecDeque::with_capacity(4 * num); + for _ in 0..num { source.push_front(0); } - for _ in 0..20 * 1024 { + for _ in 0..num { source.push_back(0); } let mut sink = WriteObserver { observed_buffer: 0 }; - assert_eq!(40 * 1024u64, io::copy(&mut source, &mut sink).unwrap()); - assert_eq!(20 * 1024, sink.observed_buffer); + assert_eq!(2 * num as u64, io::copy(&mut source, &mut sink).unwrap()); + assert_eq!(num, sink.observed_buffer); } #[test] diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.rs b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.rs index 83ad8c76bb1cf..21edb9ceeff48 100644 --- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.rs +++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.rs @@ -6,6 +6,7 @@ #![expect(incomplete_features)] fn good_fn_item(((x if x) | x): bool) -> bool { x } +//~^ ERROR: used binding `x` is possibly-uninitialized [E0381] fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} //~^ ERROR cannot find value `x` in this scope diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr index 44e42f1427074..a95ffdd42532f 100644 --- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr +++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr @@ -1,5 +1,5 @@ error[E0408]: variable `y` is not bound in all patterns - --> $DIR/name-resolution.rs:37:10 + --> $DIR/name-resolution.rs:38:10 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | ^^^^^^^^^^^^ - variable not in all patterns @@ -13,7 +13,7 @@ LL + ((Ok(x) if y) | (Err(x) if x),) => x && y, | error[E0408]: variable `x` is not bound in all patterns - --> $DIR/name-resolution.rs:37:25 + --> $DIR/name-resolution.rs:38:25 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | - ^^^^^^^^^^^^^ pattern doesn't bind `x` @@ -27,7 +27,7 @@ LL + ((Ok(y) if y) | (Err(y) if x),) => x && y, | error[E0408]: variable `x` is not bound in all patterns - --> $DIR/name-resolution.rs:63:28 + --> $DIR/name-resolution.rs:64:28 | LL | Some(x if x > 0) | None => {} | - ^^^^ pattern doesn't bind `x` @@ -35,7 +35,7 @@ LL | Some(x if x > 0) | None => {} | variable not in all patterns error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:10:34 + --> $DIR/name-resolution.rs:11:34 | LL | fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} | ^ @@ -47,7 +47,7 @@ LL + fn bad_fn_item_1(x: bool, ((y if y) | y): bool) {} | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:12:25 + --> $DIR/name-resolution.rs:13:25 | LL | fn bad_fn_item_2(((x if y) | x): bool, y: bool) {} | ^ @@ -59,7 +59,7 @@ LL + fn bad_fn_item_2(((x if x) | x): bool, y: bool) {} | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:20:18 + --> $DIR/name-resolution.rs:21:18 | LL | (x, y if x) => x && y, | ^ @@ -71,7 +71,7 @@ LL + (x, y if y) => x && y, | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:22:15 + --> $DIR/name-resolution.rs:23:15 | LL | (x if y, y) => x && y, | ^ @@ -83,7 +83,7 @@ LL + (x if x, y) => x && y, | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:29:20 + --> $DIR/name-resolution.rs:30:20 | LL | (x @ (y if x),) => x && y, | ^ @@ -95,7 +95,7 @@ LL + (x @ (y if y),) => x && y, | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:37:20 + --> $DIR/name-resolution.rs:38:20 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | ^ @@ -107,7 +107,7 @@ LL + ((Ok(x) if x) | (Err(y) if x),) => x && y, | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:37:36 + --> $DIR/name-resolution.rs:38:36 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | ^ @@ -119,13 +119,13 @@ LL + ((Ok(x) if y) | (Err(y) if y),) => x && y, | error[E0425]: cannot find value `nonexistent` in this scope - --> $DIR/name-resolution.rs:44:15 + --> $DIR/name-resolution.rs:45:15 | LL | let (_ if nonexistent) = true; | ^^^^^^^^^^^ not found in this scope error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:46:22 + --> $DIR/name-resolution.rs:47:22 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } | ^ @@ -137,7 +137,7 @@ LL + if let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:46:33 + --> $DIR/name-resolution.rs:47:33 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } | ^ @@ -149,7 +149,7 @@ LL + if let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:49:25 + --> $DIR/name-resolution.rs:50:25 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } | ^ @@ -161,7 +161,7 @@ LL + while let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:49:36 + --> $DIR/name-resolution.rs:50:36 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } | ^ @@ -173,7 +173,7 @@ LL + while let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:52:19 + --> $DIR/name-resolution.rs:53:19 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } | ^ @@ -185,7 +185,7 @@ LL + for ((x, y if y) | (x if y, y)) in [(true, true)] { x && y; } | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:52:30 + --> $DIR/name-resolution.rs:53:30 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } | ^ @@ -197,7 +197,7 @@ LL + for ((x, y if x) | (x if x, y)) in [(true, true)] { x && y; } | error[E0425]: cannot find value `y` in this scope - --> $DIR/name-resolution.rs:57:13 + --> $DIR/name-resolution.rs:58:13 | LL | (|(x if y), (y if x)| x && y)(true, true); | ^ @@ -209,7 +209,7 @@ LL + (|(x if x), (y if x)| x && y)(true, true); | error[E0425]: cannot find value `x` in this scope - --> $DIR/name-resolution.rs:57:23 + --> $DIR/name-resolution.rs:58:23 | LL | (|(x if y), (y if x)| x && y)(true, true); | ^ @@ -221,7 +221,7 @@ LL + (|(x if y), (y if y)| x && y)(true, true); | error[E0308]: mismatched types - --> $DIR/name-resolution.rs:75:18 + --> $DIR/name-resolution.rs:76:18 | LL | local if local => 0, | ^^^^^ expected `bool`, found `({integer}, {integer})` @@ -229,7 +229,16 @@ LL | local if local => 0, = note: expected type `bool` found tuple `({integer}, {integer})` -error: aborting due to 20 previous errors +error[E0381]: used binding `x` is possibly-uninitialized + --> $DIR/name-resolution.rs:8:49 + | +LL | fn good_fn_item(((x if x) | x): bool) -> bool { x } + | - - ^ `x` used here but it is possibly-uninitialized + | | | + | | binding initialized here in some conditions + | binding declared here but left uninitialized + +error: aborting due to 21 previous errors -Some errors have detailed explanations: E0308, E0408, E0425. +Some errors have detailed explanations: E0308, E0381, E0408, E0425. For more information about an error, try `rustc --explain E0308`.