jiebi/CodeConvo huggingface dataset:
/// This can be used to safely get a strong reference (by calling [`upgrade`] /// later) or to deallocate the weak count by dropping the `Weak<T>`. /// <del> /// It takes ownership of one weak count (with the exception of pointers created by [`new`], /// as these don't have any corresponding weak count). </del> <ins> /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], /// as these don't own anything; the method still works on them). </ins> /// /// # Safety /// <del> /// The pointer must have originated from the [`into_raw`]  and must still own its potential /// weak reference count. </del> <ins> /// The pointer must have originated from the [`into_raw`] and must still own its potential /// weak reference. </ins> /// <del> /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created /// by [`new`]). </del> <ins> /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this /// takes ownership of one weak reference currently represented as a raw pointer (the weak /// count is not modified by this operation) and therefore it must be paired with a previous /// call to [`into_raw`]. </ins> /// /// # Examples ///
/// Consumes the `Weak<T>` and turns it into a raw pointer. /// <del> /// This converts the weak pointer into a raw pointer, preserving the original weak count. It /// can be turned back into the `Weak<T>` with [`from_raw`]. </del> <ins> /// This converts the weak pointer into a raw pointer, while still preserving the ownership of /// one weak reference (the weak count is not modified by this operation). It can be turned /// back into the `Weak<T>` with [`from_raw`]. </ins> /// /// The same restrictions of accessing the target of the pointer as with /// [`as_ptr`] apply.
result } <del> /// Converts a raw pointer previously created by [`into_raw`] back into /// `Weak<T>`. </del> <ins> /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`. </ins> /// /// This can be used to safely get a strong reference (by calling [`upgrade`] /// later) or to deallocate the weak count by dropping the `Weak<T>`. /// <del> /// It takes ownership of one weak count (with the exception of pointers created by [`new`], /// as these don't have any corresponding weak count). </del> <ins> /// It takes ownership of one weak reference (with the exception of pointers created by [`new`], /// as these don't own anything; the method still works on them). </ins> /// /// # Safety /// /// The pointer must have originated from the [`into_raw`] and must still own its potential <del> /// weak reference count. /// /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created /// by [`new`]). </del> <ins> /// weak reference. </ins> /// <ins> /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this /// takes ownership of one weak reference currently represented as a raw pointer (the weak /// count is not modified by this operation) and therefore it must be paired with a previous /// call to [`into_raw`]. </ins> /// # Examples /// /// ```
Greater | // `{ 42 } > 3` GreaterEqual | // `{ 42 } >= 3` AssignOp(_) | // `{ 42 } +=` <del> LAnd | // `{ 42 } &&foo` </del> As | // `{ 42 } as usize` // Equal | // `{ 42 } == { 42 }`    Accepting these here would regress incorrect // NotEqual | // `{ 42 } != { 42 }  struct literals parser recovery.
// want to keep their span info to improve diagnostics in these cases in a later stage. (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3` (true, Some(AssocOp::Subtract)) | // `{ 42 } -5` <del> (true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475) </del> (true, Some(AssocOp::Add)) // `{ 42 } + 42 // If the next token is a keyword, then the tokens above *are* unambiguously incorrect: // `if x { a } else { b } && if y { c } else { d }` <del> if !self.look_ahead(1, |t| t.is_reserved_ident()) => { </del> <ins> if !self.look_ahead(1, |t| t.is_used_keyword()) => { // These cases are ambiguous and can't be identified in the parser alone. let sp = self.sess.source_map().start_point(self.token.span); self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span); false } (true, Some(AssocOp::LAnd)) => { // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the // above due to #74233. </ins> // These cases are ambiguous and can't be identified in the parser alone. let sp = self.sess.source_map().start_point(self.token.span); self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
} } <ins> fn suggest_missing_parentheses(&self, err: &mut DiagnosticBuilder<'_>, expr: &hir::Expr<'_>) { let sp = self.tcx.sess.source_map().start_point(expr.span); if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None); } } </ins> fn note_need_for_fn_pointer( &self, err: &mut DiagnosticBuilder<'_>,
<ins> // This is not autofixable because we give extra suggestions to end the first expression with `;`. fn foo(a: Option<u32>, b: Option<u32>) -> bool { if let Some(x) = a { true } else { false } //~^ ERROR mismatched types //~| ERROR mismatched types && //~ ERROR mismatched types if let Some(y) = a { true } else { false } } fn main() {} </ins>
<ins> error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:3:26 | LL |     if let Some(x) = a { true } else { false } |     ---------------------^^^^------------------ help: consider using a semicolon here |     |                    | |     |                    expected `()`, found `bool` |     expected this to be `()` error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:3:40 | LL |     if let Some(x) = a { true } else { false } |     -----------------------------------^^^^^--- help: consider using a semicolon here |     |                                  | |     |                                  expected `()`, found `bool` |     expected this to be `()` error[E0308]: mismatched types --> $DIR/expr-as-stmt-2.rs:6:5 | LL |   fn foo(a: Option<u32>, b: Option<u32>) -> bool { |                                             ---- expected `bool` because of return type LL |       if let Some(x) = a { true } else { false } |       ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })` ... LL | /     && LL | |     if let Some(y) = a { true } else { false } | |______________________________________________^ expected `bool`, found `&&bool` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. </ins>
|     | |     help: parentheses are required to parse this as an expression: `({ 42 })` <del> error: expected expression, found `&&` --> $DIR/expr-as-stmt.rs:30:5 | LL |     if let Some(x) = a { true } else { false } |     ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })` LL |     && |     ^^ expected expression </del> error: expected expression, found `>` <del> --> $DIR/expr-as-stmt.rs:37:7 </del> <ins> --> $DIR/expr-as-stmt.rs:31:7 </ins> | LL |     } > 0 |       ^ expected expression
pat_src: PatternSource, bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>, ) { <ins> let is_tuple_struct_pat = matches!(pat.kind, PatKind::TupleStruct(_, _)); </ins> // Visit all direct subpatterns of this pattern. pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { <del> PatKind::Ident(bmode, ident, ref sub) => { </del> <ins> // In tuple struct patterns ignore the invalid `ident @ ...`. // It will be handled as an error by the AST lowering. PatKind::Ident(bmode, ident, ref sub) if !(is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some()) => { </ins> // First try to resolve the identifier as some existing entity, // then fall back to a fresh binding. let has_sub = sub.is_some();
<ins> error[E0425]: cannot find value `x` in this scope --> $DIR/issue-74539.rs:9:13 | LL |             x |             ^ help: a local variable with a similar name exists: `e` error: `x @` is not allowed in a tuple struct --> $DIR/issue-74539.rs:8:14 | LL |         E::A(x @ ..) => { |              ^^^^^^ this is only allowed in slice patterns | = help: remove this and bind each tuple field independently help: if you don't need to use the contents of x, discard the tuple's remaining fields | LL |         E::A(..) => { |              ^^ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`. </ins>
} match expr.kind { <del> hir::ExprKind::Index(ref base_expr, ref index_expr) => { // We need to get the final type in case dereferences were needed for the trait // to apply (#72002). let index_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(index_expr); self.convert_place_op_to_mutable( PlaceOp::Index, expr, base_expr, &[index_expr_ty], ); </del> <ins> hir::ExprKind::Index(ref base_expr, ..) => { self.convert_place_op_to_mutable(PlaceOp::Index, expr, base_expr); </ins> } hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => { <del> self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]); </del> <ins> self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr); </ins> } _ => {} }
op: PlaceOp, expr: &hir::Expr<'_>, base_expr: &hir::Expr<'_>, <del> arg_tys: &[Ty<'tcx>], </del> ) { <del> debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys); </del> <ins> debug!("convert_place_op_to_mutable({:?}, {:?}, {:?})", op, expr, base_expr); </ins> if !self.typeck_results.borrow().is_method_call(expr) { debug!("convert_place_op_to_mutable - builtin, nothing to do"); return;
.expect("place op takes something that is not a ref") .ty; <ins> let arg_ty = match op { PlaceOp::Deref => None, PlaceOp::Index => { // We would need to recover the `T` used when we resolve `<_ as Index<T>>::index` // in try_index_step. This is the subst at index 1. // // Note: we should *not* use `expr_ty` of index_expr here because autoderef // during coercions can cause type of index_expr to differ from `T` (#72002). // We also could not use `expr_ty_adjusted` of index_expr because reborrowing // during coercions can also cause type of index_expr to differ from `T`, // which can potentially cause regionck failure (#74933). Some(self.typeck_results.borrow().node_substs(expr.hir_id).type_at(1)) } }; let arg_tys = match arg_ty { None => &[], Some(ref ty) => slice::from_ref(ty), }; </ins> let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op); let method = match method { Some(ok) => self.register_infer_ok_obligations(ok),
<ins> // check-pass // // rust-lang/rust#74933: Lifetime error when indexing with borrowed index use std::ops::{Index, IndexMut}; struct S(V); struct K<'a>(&'a ()); struct V; impl<'a> Index<&'a K<'a>> for S { type Output = V; fn index(&self, _: &'a K<'a>) -> &V { &self.0 } } impl<'a> IndexMut<&'a K<'a>> for S { fn index_mut(&mut self, _: &'a K<'a>) -> &mut V { &mut self.0 } } impl V { fn foo(&mut self) {} } fn test(s: &mut S, k: &K<'_>) { s[k] = V; s[k].foo(); } fn main() { let mut s = S(V); let k = K(&()); test(&mut s, &k); } </ins>
) = binding.kind { let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); <del> if let Some(fields) = self.field_names.get(&def_id) { let first_field = fields.first().expect("empty field list in the map"); return Some(fields.iter().fold(first_field.span, |acc, field| acc.to(field.span))); } </del> <ins> let fields = self.field_names.get(&def_id)?; let first_field = fields.first()?; // Handle `struct Foo()` return Some(fields.iter().fold(first_field.span, |acc, field| acc.to(field.span))); </ins> } None }
<ins> error[E0603]: tuple struct `Bar` is private --> $DIR/issue-75062-fieldless-tuple-struct.rs:9:10 | LL |     foo::Bar(); |          ^^^ private tuple struct | note: the tuple struct `Bar` is defined here --> $DIR/issue-75062-fieldless-tuple-struct.rs:5:5 | LL |     struct Bar(); |     ^^^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0603`. </ins>
TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Array(ref ty, ref length) => { let def_id = cx.tcx.hir().local_def_id(length.hir_id); <del> let length = match cx.tcx.const_eval_poly(def_id.to_def_id()) { Ok(length) => { print_const(cx, ty::Const::from_value(cx.tcx, length, cx.tcx.types.usize)) } Err(_) => cx .sess() .source_map() .span_to_snippet(cx.tcx.def_span(def_id)) .unwrap_or_else(|_| "_".to_string()), }; </del> <ins> // NOTE(min_const_generics): We can't use `const_eval_poly` for constants // as we currently do not supply the parent generics to anonymous constants // but do allow `ConstKind::Param`. // // `const_eval_poly` tries to to first substitute generic parameters which // results in an ICE while manually constructing the constant and using `eval` // does nothing for `ConstKind::Param`. let ct = ty::Const::from_anon_const(cx.tcx, def_id); let param_env = cx.tcx.param_env(def_id); let length = print_const(cx, ct.eval(cx.tcx, param_env)); </ins> Array(box ty.clean(cx), length) } TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
once: Once, // Whether or not the value is initialized is tracked by `state_and_queue`. value: UnsafeCell<MaybeUninit<T>>, <ins> /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl. /// /// ```compile_fail,E0597 /// #![feature(once_cell)] /// /// use std::lazy::SyncOnceCell; /// /// struct A<'a>(&'a str); /// /// impl<'a> Drop for A<'a> { ///     fn drop(&mut self) {} /// } /// /// let cell = SyncOnceCell::new(); /// { ///     let s = String::new(); ///     let _ = cell.set(A(&s)); /// } /// ``` _marker: PhantomData<T>, </ins> } // Why do we need `T: Send`?
/// Creates a new empty cell. #[unstable(feature = "once_cell", issue = "74465")] pub const fn new() -> SyncOnceCell<T> { <del> SyncOnceCell { once: Once::new(), value: UnsafeCell::new(MaybeUninit::uninit()) } </del> <ins> SyncOnceCell { once: Once::new(), value: UnsafeCell::new(MaybeUninit::uninit()), _marker: PhantomData, } </ins> } /// Gets the reference to the underlying value.
self.index = index; } <del> pub fn look_ahead(&self, n: usize) -> Option<&TokenTree> { self.stream.0[self.index..].get(n).map(|(tree, _)| tree) </del> <ins> pub fn look_ahead(&self, n: usize) -> Option<TokenTree> { self.stream.0[self.index..].get(n).map(|(tree, _)| tree.clone()) </ins> } }
} } <del> impl FromInternal<( TreeAndJoint, Option<&'_ tokenstream::TokenTree>, &'_ ParseSess, &'_ mut Vec<Self>, )> for TokenTree<Group, Punct, Ident, Literal> </del> <ins> impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)> for TokenTree<Group, Punct, Ident, Literal> </ins> { fn from_internal( <del> ((tree, is_joint), look_ahead, sess, stack): ( TreeAndJoint, Option<&tokenstream::TokenTree>, &ParseSess, &mut Vec<Self>, ), </del> <ins> ((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec<Self>), </ins> ) -> Self { use rustc_ast::token::*; <del> let joint = is_joint == Joint && matches!(look_ahead, Some(tokenstream::TokenTree::Token(t)) if t.is_op()); </del> <ins> let joint = is_joint == Joint; </ins> let Token { kind, span } = match tree { tokenstream::TokenTree::Delimited(span, delim, tts) => { let delimiter = Delimiter::from_internal(delim);
loop { let tree = iter.stack.pop().or_else(|| { let next = iter.cursor.next_with_joint()?; <del> let lookahead = iter.cursor.look_ahead(0); Some(TokenTree::from_internal((next, lookahead, self.sess, &mut iter.stack))) </del> <ins> Some(TokenTree::from_internal((next, self.sess, &mut iter.stack))) </ins> })?; // A hack used to pass AST fragments to attribute and derive macros // as a single nonterminal token instead of a token stream.
} let frame = &self.token_cursor.frame; <del> match frame.tree_cursor.look_ahead(dist - 1) { </del> <ins> looker(&match frame.tree_cursor.look_ahead(dist - 1) { </ins> Some(tree) => match tree { <del> TokenTree::Token(token) => looker(token), </del> <ins> TokenTree::Token(token) => token, </ins> TokenTree::Delimited(dspan, delim, _) => { <del> looker(&Token::new(token::OpenDelim(delim.clone()), dspan.open)) </del> <ins> Token::new(token::OpenDelim(delim), dspan.open) </ins> } }, <del> None => looker(&Token::new(token::CloseDelim(frame.delim), frame.span.close)), } </del> <ins> None => Token::new(token::CloseDelim(frame.delim), frame.span.close), }) </ins> } /// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
/// # Examples /// /// ``` <del> /// #![feature(duration_saturating_ops)] </del> /// #![feature(duration_constants)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1)); /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX); /// ``` <del> #[unstable(feature = "duration_saturating_ops", issue = "76416")] </del> <ins> #[stable(feature = "duration_saturating_ops", since = "1.53.0")] </ins> #[inline] #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")] pub const fn saturating_add(self, rhs: Duration) -> Duration {
/// # Examples /// /// ``` <del> /// #![feature(duration_saturating_ops)] </del> /// #![feature(duration_zero)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1)); /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO); /// ``` <del> #[unstable(feature = "duration_saturating_ops", issue = "76416")] </del> <ins> #[stable(feature = "duration_saturating_ops", since = "1.53.0")] </ins> #[inline] #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")] pub const fn saturating_sub(self, rhs: Duration) -> Duration {
/// # Examples /// /// ``` <del> /// #![feature(duration_saturating_ops)] </del> /// #![feature(duration_constants)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2)); /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX); /// ``` <del> #[unstable(feature = "duration_saturating_ops", issue = "76416")] </del> <ins> #[stable(feature = "duration_saturating_ops", since = "1.53.0")] </ins> #[inline] #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")] pub const fn saturating_mul(self, rhs: u32) -> Duration {
_marker: PhantomData<&'a mut T>, } <ins> unsafe impl<'a, T> Sync for DormantMutRef<'a, T> where &'a mut T: Sync {} unsafe impl<'a, T> Send for DormantMutRef<'a, T> where &'a mut T: Send {} </ins> impl<'a, T> DormantMutRef<'a, T> { /// Capture a unique borrow, and immediately reborrow it. For the compiler, /// the lifetime of the new reference is the same as the lifetime of the
} #[test] <ins> #[allow(dead_code)] fn test_sync() { fn map<T: Sync>(v: &BTreeMap<T, T>) -> impl Sync + '_ { v } fn into_iter<T: Sync>(v: BTreeMap<T, T>) -> impl Sync { v.into_iter() } fn into_keys<T: Sync + Ord>(v: BTreeMap<T, T>) -> impl Sync { v.into_keys() } fn into_values<T: Sync + Ord>(v: BTreeMap<T, T>) -> impl Sync { v.into_values() } fn drain_filter<T: Sync + Ord>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { v.drain_filter(|_, _| false) } fn iter<T: Sync>(v: &BTreeMap<T, T>) -> impl Sync + '_ { v.iter() } fn iter_mut<T: Sync>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { v.iter_mut() } fn keys<T: Sync>(v: &BTreeMap<T, T>) -> impl Sync + '_ { v.keys() } fn values<T: Sync>(v: &BTreeMap<T, T>) -> impl Sync + '_ { v.values() } fn values_mut<T: Sync>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { v.values_mut() } fn range<T: Sync + Ord>(v: &BTreeMap<T, T>) -> impl Sync + '_ { v.range(..) } fn range_mut<T: Sync + Ord>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { v.range_mut(..) } fn entry<T: Sync + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { v.entry(Default::default()) } fn occupied_entry<T: Sync + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { match v.entry(Default::default()) { Occupied(entry) => entry, _ => unreachable!(), } } fn vacant_entry<T: Sync + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Sync + '_ { match v.entry(Default::default()) { Vacant(entry) => entry, _ => unreachable!(), } } } #[test] #[allow(dead_code)] fn test_send() { fn map<T: Send>(v: BTreeMap<T, T>) -> impl Send { v } fn into_iter<T: Send>(v: BTreeMap<T, T>) -> impl Send { v.into_iter() } fn into_keys<T: Send + Ord>(v: BTreeMap<T, T>) -> impl Send { v.into_keys() } fn into_values<T: Send + Ord>(v: BTreeMap<T, T>) -> impl Send { v.into_values() } fn drain_filter<T: Send + Ord>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { v.drain_filter(|_, _| false) } fn iter<T: Send + Sync>(v: &BTreeMap<T, T>) -> impl Send + '_ { v.iter() } fn iter_mut<T: Send + Sync>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { v.iter_mut() } fn keys<T: Send + Sync>(v: &BTreeMap<T, T>) -> impl Send + '_ { v.keys() } fn values<T: Send + Sync>(v: &BTreeMap<T, T>) -> impl Send + '_ { v.values() } fn values_mut<T: Send + Sync>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { v.values_mut() } fn range<T: Send + Sync + Ord>(v: &BTreeMap<T, T>) -> impl Send + '_ { v.range(..) } fn range_mut<T: Send + Sync + Ord>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { v.range_mut(..) } fn entry<T: Send + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { v.entry(Default::default()) } fn occupied_entry<T: Send + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { match v.entry(Default::default()) { Occupied(entry) => entry, _ => unreachable!(), } } fn vacant_entry<T: Send + Ord + Default>(v: &mut BTreeMap<T, T>) -> impl Send + '_ { match v.entry(Default::default()) { Vacant(entry) => entry, _ => unreachable!(), } } } #[test] </ins> fn test_occupied_entry_key() { let mut a = BTreeMap::new(); let key = "hello there";
<del> //! Note: most of the tests relevant to this file can be found (at the time of writing) in //! src/tests/ui/pattern/usefulness. </del> <ins> //! Note: tests specific to this file can be found in: //!     - ui/pattern/usefulness //!     - ui/or-patterns //!     - ui/consts/const_in_pattern //!     - ui/rfc-2008-non-exhaustive //!     - probably many others //! I (Nadrieril) prefer to put new tests in `ui/pattern/usefulness` unless there's a specific //! reason not to, for example if they depend on a particular feature like or_patterns. </ins> //! //! This file includes the logic for exhaustiveness and usefulness checking for //! pattern-matching. Specifically, given a list of patterns for a type, we can
#[derive(Clone, Debug)] crate enum Usefulness<'tcx> { <del> /// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns. Useful(Vec<Span>), </del> <ins> /// Carries, for each column in the matrix, a set of sub-branches that have been found to be /// unreachable. Used only in the presence of or-patterns, otherwise it stays empty. Useful(Vec<FxHashSet<Span>>), </ins> /// Carries a list of witnesses of non-exhaustiveness. UsefulWithWitness(Vec<Witness<'tcx>>), NotUseful,
}; UsefulWithWitness(new_witnesses) } <ins> Useful(mut unreachables) => { if !unreachables.is_empty() { // When we apply a constructor, there are `arity` columns of the matrix that // corresponded to its arguments. All the unreachables found in these columns // will, after `apply`, come from the first column. So we take the union of all // the corresponding sets and put them in the first column. // Note that `arity` may be 0, in which case we just push a new empty set. let len = unreachables.len(); let arity = ctor_wild_subpatterns.len(); let mut unioned = FxHashSet::default(); for set in unreachables.drain((len - arity)..) { unioned.extend(set) } unreachables.push(unioned); } Useful(unreachables) } </ins> x => x, } }