| author | bors <bors@rust-lang.org> 2026-07-07 04:38:49 UTC |
| committer | bors <bors@rust-lang.org> 2026-07-07 04:38:49 UTC |
| log | bcd9ae8b77e8a1d03d73b51f1fd9cb99565cfdc5 |
| tree | d3168a7abb2f6adb5290c541c71eba07476515e7 |
| parent | b960fcf2ff0f04967b30b947be8fc155fb067901 |
| parent | 6673d7de6123c4b9084113aef104520e3bd9fc7b |
Rollup of 13 pull requests
Successful merges:
- rust-lang/rust#158478 (Use correct typing mode in mir building for the next solver)
- rust-lang/rust#158796 (Distinguish null reference production from null pointer dereference in UB checks)
- rust-lang/rust#158821 (add regression test for late-bound type method probe ICE)
- rust-lang/rust#158245 (Update the rustc_perf submodule)
- rust-lang/rust#158346 (Prevent rustdoc auto-trait ICEs with `-Znext-solver=globally`)
- rust-lang/rust#158536 (Instatiate binder instead of skipping when suggesting function arg error)
- rust-lang/rust#158553 (Avoid infinite recursion when trying to build valtrees for self-referential consts)
- rust-lang/rust#158679 (Document blocking guarantees for `std::sync`)
- rust-lang/rust#158826 (Reorganize `tests/ui/issues` [19/N])
- rust-lang/rust#158860 (Delete `impl_def_id` field from `ImplHeader`)
- rust-lang/rust#158867 (rewrite `Align::max_for_target` in a more obvious way)
- rust-lang/rust#158878 (borrowck: Inline `free_region_constraint_info()` to simplify the code)
- rust-lang/rust#158881 (Update mdbook to 0.5.4)98 files changed, 1213 insertions(+), 586 deletions(-)
compiler/rustc_abi/src/lib.rs+3-8| ... | ... | @@ -36,6 +36,7 @@ even other Rust compilers, such as rust-analyzer! |
| 36 | 36 | |
| 37 | 37 | */ |
| 38 | 38 | |
| 39 | use std::cmp::min; | |
| 39 | 40 | use std::fmt; |
| 40 | 41 | #[cfg(feature = "nightly")] |
| 41 | 42 | use std::iter::Step; |
| ... | ... | @@ -1060,14 +1061,8 @@ impl Align { |
| 1060 | 1061 | /// Either `1 << (pointer_bits - 1)` or [`Align::MAX`], whichever is smaller. |
| 1061 | 1062 | #[inline] |
| 1062 | 1063 | pub fn max_for_target(tdl: &TargetDataLayout) -> Align { |
| 1063 | let pointer_bits = tdl.pointer_size().bits(); | |
| 1064 | if let Ok(pointer_bits) = u8::try_from(pointer_bits) | |
| 1065 | && pointer_bits <= Align::MAX.pow2 | |
| 1066 | { | |
| 1067 | Align { pow2: pointer_bits - 1 } | |
| 1068 | } else { | |
| 1069 | Align::MAX | |
| 1070 | } | |
| 1064 | let pointer_bits = u8::try_from(tdl.pointer_size().bits()).unwrap(); | |
| 1065 | min(Align { pow2: pointer_bits - 1 }, Align::MAX) | |
| 1071 | 1066 | } |
| 1072 | 1067 | |
| 1073 | 1068 | #[inline] |
compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs+9-22| ... | ... | @@ -12,7 +12,7 @@ use rustc_middle::mir::{ |
| 12 | 12 | Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, |
| 13 | 13 | }; |
| 14 | 14 | use rustc_middle::ty::adjustment::PointerCoercion; |
| 15 | use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; | |
| 15 | use rustc_middle::ty::{self, Ty, TyCtxt}; | |
| 16 | 16 | use rustc_span::{DesugaringKind, Span, kw, sym}; |
| 17 | 17 | use rustc_trait_selection::error_reporting::traits::FindExprBySpan; |
| 18 | 18 | use rustc_trait_selection::error_reporting::traits::call_kind::CallKind; |
| ... | ... | @@ -574,24 +574,6 @@ fn suggest_rewrite_if_let<G: EmissionGuarantee>( |
| 574 | 574 | } |
| 575 | 575 | |
| 576 | 576 | impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { |
| 577 | fn free_region_constraint_info( | |
| 578 | &self, | |
| 579 | borrow_region: RegionVid, | |
| 580 | outlived_region: RegionVid, | |
| 581 | ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<OutlivesConstraint<'tcx>>) | |
| 582 | { | |
| 583 | let (blame_constraint, path) = self.regioncx.best_blame_constraint( | |
| 584 | borrow_region, | |
| 585 | NllRegionVariableOrigin::FreeRegion, | |
| 586 | outlived_region, | |
| 587 | ); | |
| 588 | let BlameConstraint { category, from_closure, span, .. } = blame_constraint; | |
| 589 | ||
| 590 | let outlived_fr_name = self.give_region_a_name(outlived_region); | |
| 591 | ||
| 592 | (category, from_closure, span, outlived_fr_name, path) | |
| 593 | } | |
| 594 | ||
| 595 | 577 | /// Returns structured explanation for *why* the borrow contains the |
| 596 | 578 | /// point from `location`. This is key for the "3-point errors" |
| 597 | 579 | /// [described in the NLL RFC][d]. |
| ... | ... | @@ -707,9 +689,14 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { |
| 707 | 689 | // Here, under NLL: no cause was found. Under polonius: no cause was found, or a |
| 708 | 690 | // boring local was found, which we ignore like NLLs do to match its diagnostics. |
| 709 | 691 | if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) { |
| 710 | let (category, from_closure, span, region_name, path) = | |
| 711 | self.free_region_constraint_info(borrow_region_vid, region); | |
| 712 | if let Some(region_name) = region_name { | |
| 692 | let (blame_constraint, path) = self.regioncx.best_blame_constraint( | |
| 693 | borrow_region_vid, | |
| 694 | NllRegionVariableOrigin::FreeRegion, | |
| 695 | region, | |
| 696 | ); | |
| 697 | let BlameConstraint { category, from_closure, span, .. } = blame_constraint; | |
| 698 | ||
| 699 | if let Some(region_name) = self.give_region_a_name(region) { | |
| 713 | 700 | let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); |
| 714 | 701 | BorrowExplanation::MustBeValidFor { |
| 715 | 702 | category, |
compiler/rustc_codegen_cranelift/src/base.rs+11| ... | ... | @@ -421,6 +421,17 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { |
| 421 | 421 | source_info.span, |
| 422 | 422 | ) |
| 423 | 423 | } |
| 424 | AssertKind::NullReferenceConstructed => { | |
| 425 | let location = fx.get_caller_location(source_info).load_scalar(fx); | |
| 426 | ||
| 427 | codegen_panic_inner( | |
| 428 | fx, | |
| 429 | rustc_hir::LangItem::PanicNullReferenceConstructed, | |
| 430 | &[location], | |
| 431 | *unwind, | |
| 432 | source_info.span, | |
| 433 | ) | |
| 434 | } | |
| 424 | 435 | AssertKind::InvalidEnumConstruction(source) => { |
| 425 | 436 | let source = codegen_operand(fx, source).load_scalar(fx); |
| 426 | 437 | let location = fx.get_caller_location(source_info).load_scalar(fx); |
compiler/rustc_codegen_ssa/src/mir/block.rs+5| ... | ... | @@ -789,6 +789,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
| 789 | 789 | // `#[track_caller]` adds an implicit argument. |
| 790 | 790 | (LangItem::PanicNullPointerDereference, vec![location]) |
| 791 | 791 | } |
| 792 | AssertKind::NullReferenceConstructed => { | |
| 793 | // It's `fn panic_null_reference_constructed()`, | |
| 794 | // `#[track_caller]` adds an implicit argument. | |
| 795 | (LangItem::PanicNullReferenceConstructed, vec![location]) | |
| 796 | } | |
| 792 | 797 | AssertKind::InvalidEnumConstruction(source) => { |
| 793 | 798 | let source = self.codegen_operand(bx, source).immediate(); |
| 794 | 799 | // It's `fn panic_invalid_enum_construction(source: u128)`, |
compiler/rustc_const_eval/src/const_eval/machine.rs+1| ... | ... | @@ -772,6 +772,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { |
| 772 | 772 | found: eval_to_int(found)?, |
| 773 | 773 | }, |
| 774 | 774 | NullPointerDereference => NullPointerDereference, |
| 775 | NullReferenceConstructed => NullReferenceConstructed, | |
| 775 | 776 | InvalidEnumConstruction(source) => InvalidEnumConstruction(eval_to_int(source)?), |
| 776 | 777 | }; |
| 777 | 778 | Err(ConstEvalErrKind::AssertFailure(err)).into() |
compiler/rustc_const_eval/src/const_eval/valtrees.rs+60-31| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; |
| 2 | use rustc_data_structures::fx::{FxHashMap, FxHashSet}; | |
| 2 | 3 | use rustc_data_structures::stack::ensure_sufficient_stack; |
| 3 | 4 | use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError}; |
| 4 | 5 | use rustc_middle::traits::ObligationCause; |
| ... | ... | @@ -17,13 +18,15 @@ use crate::interpret::{ |
| 17 | 18 | intern_const_alloc_recursive, |
| 18 | 19 | }; |
| 19 | 20 | |
| 20 | #[instrument(skip(ecx), level = "debug")] | |
| 21 | #[instrument(skip(ecx, visited, settled), level = "debug")] | |
| 21 | 22 | fn branches<'tcx>( |
| 22 | 23 | ecx: &CompileTimeInterpCx<'tcx>, |
| 23 | 24 | place: &MPlaceTy<'tcx>, |
| 24 | 25 | field_count: usize, |
| 25 | 26 | variant: Option<VariantIdx>, |
| 26 | 27 | num_nodes: &mut usize, |
| 28 | visited: &mut FxHashSet<MPlaceTy<'tcx>>, | |
| 29 | settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>, | |
| 27 | 30 | ) -> EvalToValTreeResult<'tcx> { |
| 28 | 31 | let place = match variant { |
| 29 | 32 | Some(variant) => ecx.project_downcast(place, variant).unwrap(), |
| ... | ... | @@ -45,7 +48,7 @@ fn branches<'tcx>( |
| 45 | 48 | |
| 46 | 49 | for i in 0..field_count { |
| 47 | 50 | let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); |
| 48 | let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; | |
| 51 | let valtree = const_to_valtree_inner(ecx, &field, num_nodes, visited, settled)?; | |
| 49 | 52 | branches.push(ty::Const::new_value(*ecx.tcx, valtree, field.layout.ty)); |
| 50 | 53 | } |
| 51 | 54 | |
| ... | ... | @@ -57,39 +60,53 @@ fn branches<'tcx>( |
| 57 | 60 | Ok(ty::ValTree::from_branches(*ecx.tcx, branches)) |
| 58 | 61 | } |
| 59 | 62 | |
| 60 | #[instrument(skip(ecx), level = "debug")] | |
| 63 | #[instrument(skip(ecx, visited, settled), level = "debug")] | |
| 61 | 64 | fn slice_branches<'tcx>( |
| 62 | 65 | ecx: &CompileTimeInterpCx<'tcx>, |
| 63 | 66 | place: &MPlaceTy<'tcx>, |
| 64 | 67 | num_nodes: &mut usize, |
| 68 | visited: &mut FxHashSet<MPlaceTy<'tcx>>, | |
| 69 | settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>, | |
| 65 | 70 | ) -> EvalToValTreeResult<'tcx> { |
| 66 | 71 | let n = place.len(ecx).unwrap_or_else(|_| panic!("expected to use len of place {place:?}")); |
| 67 | 72 | |
| 68 | 73 | let mut elems = Vec::with_capacity(n as usize); |
| 69 | 74 | for i in 0..n { |
| 70 | 75 | let place_elem = ecx.project_index(place, i).unwrap(); |
| 71 | let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes)?; | |
| 76 | let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes, visited, settled)?; | |
| 72 | 77 | elems.push(ty::Const::new_value(*ecx.tcx, valtree, place_elem.layout.ty)); |
| 73 | 78 | } |
| 74 | 79 | |
| 75 | 80 | Ok(ty::ValTree::from_branches(*ecx.tcx, elems)) |
| 76 | 81 | } |
| 77 | 82 | |
| 78 | #[instrument(skip(ecx), level = "debug")] | |
| 83 | #[instrument(skip(ecx, visited, settled), level = "debug")] | |
| 79 | 84 | fn const_to_valtree_inner<'tcx>( |
| 80 | 85 | ecx: &CompileTimeInterpCx<'tcx>, |
| 81 | 86 | place: &MPlaceTy<'tcx>, |
| 82 | 87 | num_nodes: &mut usize, |
| 88 | visited: &mut FxHashSet<MPlaceTy<'tcx>>, | |
| 89 | settled: &mut FxHashMap<MPlaceTy<'tcx>, EvalToValTreeResult<'tcx>>, | |
| 83 | 90 | ) -> EvalToValTreeResult<'tcx> { |
| 84 | 91 | let tcx = *ecx.tcx; |
| 85 | 92 | let ty = place.layout.ty; |
| 86 | 93 | debug!("ty kind: {:?}", ty.kind()); |
| 87 | 94 | |
| 95 | if let Some(&result) = settled.get(place) { | |
| 96 | return result; | |
| 97 | } | |
| 98 | ||
| 99 | if visited.contains(place) { | |
| 100 | return Err(ValTreeCreationError::CyclicConst); | |
| 101 | } | |
| 102 | ||
| 88 | 103 | if *num_nodes >= VALTREE_MAX_NODES { |
| 89 | 104 | return Err(ValTreeCreationError::NodesOverflow); |
| 90 | 105 | } |
| 91 | 106 | |
| 92 | match ty.kind() { | |
| 107 | visited.insert(place.clone()); | |
| 108 | ||
| 109 | let result = ensure_sufficient_stack(|| match ty.kind() { | |
| 93 | 110 | ty::FnDef(..) => { |
| 94 | 111 | *num_nodes += 1; |
| 95 | 112 | Ok(ty::ValTree::zst(tcx)) |
| ... | ... | @@ -108,7 +125,7 @@ fn const_to_valtree_inner<'tcx>( |
| 108 | 125 | // Since the returned valtree does not contain the type or layout, we can just |
| 109 | 126 | // switch to the base type. |
| 110 | 127 | place.layout = ecx.layout_of(*base).unwrap(); |
| 111 | ensure_sufficient_stack(|| const_to_valtree_inner(ecx, &place, num_nodes)) | |
| 128 | const_to_valtree_inner(ecx, &place, num_nodes, visited, settled) | |
| 112 | 129 | } |
| 113 | 130 | |
| 114 | 131 | ty::RawPtr(_, _) => { |
| ... | ... | @@ -120,16 +137,16 @@ fn const_to_valtree_inner<'tcx>( |
| 120 | 137 | // We could allow wide raw pointers where both sides are integers in the future, |
| 121 | 138 | // but for now we reject them. |
| 122 | 139 | if matches!(val.layout.backend_repr, BackendRepr::ScalarPair(..)) { |
| 123 | return Err(ValTreeCreationError::NonSupportedType(ty)); | |
| 140 | Err(ValTreeCreationError::NonSupportedType(ty)) | |
| 141 | } else { | |
| 142 | let val = val.to_scalar(); | |
| 143 | // We are in the CTFE machine, so ptr-to-int casts will fail. | |
| 144 | // This can only be `Ok` if `val` already is an integer. | |
| 145 | match val.try_to_scalar_int() { | |
| 146 | Ok(val) => Ok(ty::ValTree::from_scalar_int(tcx, val)), | |
| 147 | Err(_) => Err(ValTreeCreationError::NonSupportedType(ty)), | |
| 148 | } | |
| 124 | 149 | } |
| 125 | let val = val.to_scalar(); | |
| 126 | // We are in the CTFE machine, so ptr-to-int casts will fail. | |
| 127 | // This can only be `Ok` if `val` already is an integer. | |
| 128 | let Ok(val) = val.try_to_scalar_int() else { | |
| 129 | return Err(ValTreeCreationError::NonSupportedType(ty)); | |
| 130 | }; | |
| 131 | // It's just a ScalarInt! | |
| 132 | Ok(ty::ValTree::from_scalar_int(tcx, val)) | |
| 133 | 150 | } |
| 134 | 151 | |
| 135 | 152 | // Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to |
| ... | ... | @@ -138,33 +155,39 @@ fn const_to_valtree_inner<'tcx>( |
| 138 | 155 | |
| 139 | 156 | ty::Ref(_, _, _) => { |
| 140 | 157 | let derefd_place = ecx.deref_pointer(place).report_err()?; |
| 141 | const_to_valtree_inner(ecx, &derefd_place, num_nodes) | |
| 158 | const_to_valtree_inner(ecx, &derefd_place, num_nodes, visited, settled) | |
| 142 | 159 | } |
| 143 | 160 | |
| 144 | ty::Str | ty::Slice(_) | ty::Array(_, _) => slice_branches(ecx, place, num_nodes), | |
| 161 | ty::Str | ty::Slice(_) | ty::Array(_, _) => { | |
| 162 | slice_branches(ecx, place, num_nodes, visited, settled) | |
| 163 | } | |
| 145 | 164 | // Trait objects are not allowed in type level constants, as we have no concept for |
| 146 | 165 | // resolving their backing type, even if we can do that at const eval time. We may |
| 147 | 166 | // hypothetically be able to allow `dyn StructuralPartialEq` trait objects in the future, |
| 148 | 167 | // but it is unclear if this is useful. |
| 149 | 168 | ty::Dynamic(..) => Err(ValTreeCreationError::NonSupportedType(ty)), |
| 150 | 169 | |
| 151 | ty::Tuple(elem_tys) => branches(ecx, place, elem_tys.len(), None, num_nodes), | |
| 170 | ty::Tuple(elem_tys) => { | |
| 171 | branches(ecx, place, elem_tys.len(), None, num_nodes, visited, settled) | |
| 172 | } | |
| 152 | 173 | |
| 153 | 174 | ty::Adt(def, _) => { |
| 154 | 175 | if def.is_union() { |
| 155 | return Err(ValTreeCreationError::NonSupportedType(ty)); | |
| 176 | Err(ValTreeCreationError::NonSupportedType(ty)) | |
| 156 | 177 | } else if def.variants().is_empty() { |
| 157 | 178 | bug!("uninhabited types should have errored and never gotten converted to valtree") |
| 179 | } else { | |
| 180 | let variant = ecx.read_discriminant(place).report_err()?; | |
| 181 | branches( | |
| 182 | ecx, | |
| 183 | place, | |
| 184 | def.variant(variant).fields.len(), | |
| 185 | def.is_enum().then_some(variant), | |
| 186 | num_nodes, | |
| 187 | visited, | |
| 188 | settled, | |
| 189 | ) | |
| 158 | 190 | } |
| 159 | ||
| 160 | let variant = ecx.read_discriminant(place).report_err()?; | |
| 161 | branches( | |
| 162 | ecx, | |
| 163 | place, | |
| 164 | def.variant(variant).fields.len(), | |
| 165 | def.is_enum().then_some(variant), | |
| 166 | num_nodes, | |
| 167 | ) | |
| 168 | 191 | } |
| 169 | 192 | |
| 170 | 193 | // FIXME(oli-obk): we could look behind opaque types |
| ... | ... | @@ -186,7 +209,11 @@ fn const_to_valtree_inner<'tcx>( |
| 186 | 209 | | ty::Coroutine(..) |
| 187 | 210 | | ty::CoroutineWitness(..) |
| 188 | 211 | | ty::UnsafeBinder(_) => Err(ValTreeCreationError::NonSupportedType(ty)), |
| 189 | } | |
| 212 | }); | |
| 213 | ||
| 214 | visited.remove(place); | |
| 215 | settled.insert(place.clone(), result); | |
| 216 | result | |
| 190 | 217 | } |
| 191 | 218 | |
| 192 | 219 | /// Valtrees don't store the `MemPlaceMeta` that all dynamically sized values have in the interpreter. |
| ... | ... | @@ -257,7 +284,9 @@ pub(crate) fn eval_to_valtree<'tcx>( |
| 257 | 284 | debug!(?place); |
| 258 | 285 | |
| 259 | 286 | let mut num_nodes = 0; |
| 260 | const_to_valtree_inner(&ecx, &place, &mut num_nodes) | |
| 287 | let mut visited = FxHashSet::default(); | |
| 288 | let mut settled = FxHashMap::default(); | |
| 289 | const_to_valtree_inner(&ecx, &place, &mut num_nodes, &mut visited, &mut settled) | |
| 261 | 290 | } |
| 262 | 291 | |
| 263 | 292 | /// Converts a `ValTree` to a `ConstValue`, which is needed after mir |
compiler/rustc_hir/src/lang_items.rs+1| ... | ... | @@ -309,6 +309,7 @@ language_item_table! { |
| 309 | 309 | PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None; |
| 310 | 310 | PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None; |
| 311 | 311 | PanicNullPointerDereference, sym::panic_null_pointer_dereference, panic_null_pointer_dereference, Target::Fn, GenericRequirement::None; |
| 312 | PanicNullReferenceConstructed, sym::panic_null_reference_constructed, panic_null_reference_constructed, Target::Fn, GenericRequirement::None; | |
| 312 | 313 | PanicInvalidEnumConstruction, sym::panic_invalid_enum_construction, panic_invalid_enum_construction, Target::Fn, GenericRequirement::None; |
| 313 | 314 | PanicCoroutineResumedDrop, sym::panic_const_coroutine_resumed_drop, panic_const_coroutine_resumed_drop, Target::Fn, GenericRequirement::None; |
| 314 | 315 | PanicAsyncFnResumedDrop, sym::panic_const_async_fn_resumed_drop, panic_const_async_fn_resumed_drop, Target::Fn, GenericRequirement::None; |
compiler/rustc_middle/src/error.rs+9| ... | ... | @@ -144,6 +144,15 @@ pub(crate) struct InvalidConstInValtree { |
| 144 | 144 | pub global_const_id: String, |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | #[derive(Diagnostic)] | |
| 148 | #[diag("constant {$global_const_id} cannot be used as pattern")] | |
| 149 | #[note("constants whose type references itself cannot be used as patterns")] | |
| 150 | pub(crate) struct CyclicConstInValtree { | |
| 151 | #[primary_span] | |
| 152 | pub span: Span, | |
| 153 | pub global_const_id: String, | |
| 154 | } | |
| 155 | ||
| 147 | 156 | #[derive(Diagnostic)] |
| 148 | 157 | #[diag("internal compiler error: reentrant incremental verify failure, suppressing message")] |
| 149 | 158 | pub(crate) struct Reentrant; |
compiler/rustc_middle/src/mir/interpret/error.rs+2| ... | ... | @@ -105,6 +105,8 @@ pub enum ValTreeCreationError<'tcx> { |
| 105 | 105 | InvalidConst, |
| 106 | 106 | /// Values of this type, or this particular value, are not supported as valtrees. |
| 107 | 107 | NonSupportedType(Ty<'tcx>), |
| 108 | /// Trying to valtree this constant would cause the valtree to have cycles. | |
| 109 | CyclicConst, | |
| 108 | 110 | /// The error has already been handled by const evaluation. |
| 109 | 111 | ErrorHandled(ErrorHandled), |
| 110 | 112 | } |
compiler/rustc_middle/src/mir/interpret/queries.rs+7| ... | ... | @@ -232,6 +232,13 @@ impl<'tcx> TyCtxt<'tcx> { |
| 232 | 232 | }); |
| 233 | 233 | Err(ReportedErrorInfo::allowed_in_infallible(handled).into()) |
| 234 | 234 | } |
| 235 | ValTreeCreationError::CyclicConst => { | |
| 236 | let handled = self.dcx().emit_err(error::CyclicConstInValtree { | |
| 237 | span, | |
| 238 | global_const_id: cid.display(self), | |
| 239 | }); | |
| 240 | Err(ReportedErrorInfo::allowed_in_infallible(handled).into()) | |
| 241 | } | |
| 235 | 242 | ValTreeCreationError::ErrorHandled(handled) => Err(handled), |
| 236 | 243 | } |
| 237 | 244 | } |
compiler/rustc_middle/src/mir/syntax.rs+1| ... | ... | @@ -1046,6 +1046,7 @@ pub enum AssertKind<O> { |
| 1046 | 1046 | ResumedAfterDrop(CoroutineKind), |
| 1047 | 1047 | MisalignedPointerDereference { required: O, found: O }, |
| 1048 | 1048 | NullPointerDereference, |
| 1049 | NullReferenceConstructed, | |
| 1049 | 1050 | InvalidEnumConstruction(O), |
| 1050 | 1051 | } |
| 1051 | 1052 |
compiler/rustc_middle/src/mir/terminator.rs+3| ... | ... | @@ -210,6 +210,7 @@ impl<O> AssertKind<O> { |
| 210 | 210 | LangItem::PanicGenFnNonePanic |
| 211 | 211 | } |
| 212 | 212 | NullPointerDereference => LangItem::PanicNullPointerDereference, |
| 213 | NullReferenceConstructed => LangItem::PanicNullReferenceConstructed, | |
| 213 | 214 | InvalidEnumConstruction(_) => LangItem::PanicInvalidEnumConstruction, |
| 214 | 215 | ResumedAfterDrop(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedDrop, |
| 215 | 216 | ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { |
| ... | ... | @@ -287,6 +288,7 @@ impl<O> AssertKind<O> { |
| 287 | 288 | ) |
| 288 | 289 | } |
| 289 | 290 | NullPointerDereference => write!(f, "\"null pointer dereference occurred\""), |
| 291 | NullReferenceConstructed => write!(f, "\"null reference produced\""), | |
| 290 | 292 | InvalidEnumConstruction(source) => { |
| 291 | 293 | write!(f, "\"trying to construct an enum from an invalid value {{}}\", {source:?}") |
| 292 | 294 | } |
| ... | ... | @@ -387,6 +389,7 @@ impl<O: fmt::Debug> fmt::Display for AssertKind<O> { |
| 387 | 389 | write!(f, "coroutine resumed after panicking") |
| 388 | 390 | } |
| 389 | 391 | NullPointerDereference => write!(f, "null pointer dereference occurred"), |
| 392 | NullReferenceConstructed => write!(f, "null reference produced"), | |
| 390 | 393 | InvalidEnumConstruction(source) => { |
| 391 | 394 | write!(f, "trying to construct an enum from an invalid value `{source:#?}`") |
| 392 | 395 | } |
compiler/rustc_middle/src/mir/visit.rs+1-1| ... | ... | @@ -668,7 +668,7 @@ macro_rules! make_mir_visitor { |
| 668 | 668 | OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) | InvalidEnumConstruction(op) => { |
| 669 | 669 | self.visit_operand(op, location); |
| 670 | 670 | } |
| 671 | ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference | ResumedAfterDrop(_) => { | |
| 671 | ResumedAfterReturn(_) | ResumedAfterPanic(_) | NullPointerDereference | NullReferenceConstructed | ResumedAfterDrop(_) => { | |
| 672 | 672 | // Nothing to visit |
| 673 | 673 | } |
| 674 | 674 | MisalignedPointerDereference { required, found } => { |
compiler/rustc_middle/src/ty/mod.rs+17| ... | ... | @@ -1128,6 +1128,23 @@ impl<'tcx> TypingEnv<'tcx> { |
| 1128 | 1128 | Self::new(tcx.param_env(def_id), TypingMode::non_body_analysis()) |
| 1129 | 1129 | } |
| 1130 | 1130 | |
| 1131 | /// Ideally we just use `TypingMode::PostTypeckUntilBorrowck`. | |
| 1132 | /// But that's not compatible with the old solver yet. | |
| 1133 | /// | |
| 1134 | /// FIXME: this should not be needed in the long term. | |
| 1135 | pub fn post_typeck_until_borrowck_for_mir_build( | |
| 1136 | tcx: TyCtxt<'tcx>, | |
| 1137 | def_id: LocalDefId, | |
| 1138 | ) -> TypingEnv<'tcx> { | |
| 1139 | if tcx.use_typing_mode_post_typeck_until_borrowck() { | |
| 1140 | TypingEnv::new(tcx.param_env(def_id.to_def_id()), ty::TypingMode::borrowck(tcx, def_id)) | |
| 1141 | } else { | |
| 1142 | // FIXME(#132279): We're in a body, we should use a typing | |
| 1143 | // mode which reveals the opaque types defined by that body. | |
| 1144 | TypingEnv::non_body_analysis(tcx, def_id) | |
| 1145 | } | |
| 1146 | } | |
| 1147 | ||
| 1131 | 1148 | pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey<DefId>) -> TypingEnv<'tcx> { |
| 1132 | 1149 | TypingEnv::new(tcx.param_env_normalized_for_post_analysis(def_id), TypingMode::PostAnalysis) |
| 1133 | 1150 | } |
compiler/rustc_mir_build/src/builder/mod.rs+18-6| ... | ... | @@ -505,9 +505,15 @@ fn construct_fn<'tcx>( |
| 505 | 505 | ); |
| 506 | 506 | } |
| 507 | 507 | |
| 508 | // FIXME(#132279): This should be able to reveal opaque | |
| 509 | // types defined during HIR typeck. | |
| 510 | let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); | |
| 508 | let typing_mode = if tcx.use_typing_mode_post_typeck_until_borrowck() { | |
| 509 | TypingMode::borrowck(tcx, fn_def) | |
| 510 | } else { | |
| 511 | // FIXME(#132279): This should be able to reveal opaque | |
| 512 | // types defined during HIR typeck. | |
| 513 | TypingMode::non_body_analysis() | |
| 514 | }; | |
| 515 | ||
| 516 | let infcx = tcx.infer_ctxt().build(typing_mode); | |
| 511 | 517 | let mut builder = Builder::new( |
| 512 | 518 | thir, |
| 513 | 519 | infcx, |
| ... | ... | @@ -587,9 +593,15 @@ fn construct_const<'a, 'tcx>( |
| 587 | 593 | _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), |
| 588 | 594 | }; |
| 589 | 595 | |
| 590 | // FIXME(#132279): We likely want to be able to use the hidden types of | |
| 591 | // opaques used by this function here. | |
| 592 | let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); | |
| 596 | let typing_mode = if tcx.use_typing_mode_post_typeck_until_borrowck() { | |
| 597 | TypingMode::borrowck(tcx, def) | |
| 598 | } else { | |
| 599 | // FIXME(#132279): This should be able to reveal opaque | |
| 600 | // types defined during HIR typeck. | |
| 601 | TypingMode::non_body_analysis() | |
| 602 | }; | |
| 603 | ||
| 604 | let infcx = tcx.infer_ctxt().build(typing_mode); | |
| 593 | 605 | let mut builder = |
| 594 | 606 | Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None); |
| 595 | 607 |
compiler/rustc_mir_build/src/builder/scope.rs+4-2| ... | ... | @@ -968,8 +968,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { |
| 968 | 968 | tcx: self.tcx, |
| 969 | 969 | typeck_results, |
| 970 | 970 | module: self.tcx.parent_module(self.hir_id).to_def_id(), |
| 971 | // FIXME(#132279): We're in a body, should handle opaques. | |
| 972 | typing_env: rustc_middle::ty::TypingEnv::non_body_analysis(self.tcx, self.def_id), | |
| 971 | typing_env: ty::TypingEnv::post_typeck_until_borrowck_for_mir_build( | |
| 972 | self.tcx, | |
| 973 | self.def_id, | |
| 974 | ), | |
| 973 | 975 | dropless_arena: &dropless_arena, |
| 974 | 976 | match_lint_level: self.hir_id, |
| 975 | 977 | whole_match_span: Some(rustc_span::Span::default()), |
compiler/rustc_mir_build/src/check_tail_calls.rs+1-2| ... | ... | @@ -27,8 +27,7 @@ pub(crate) fn check_tail_calls(tcx: TyCtxt<'_>, def: LocalDefId) -> Result<(), E |
| 27 | 27 | tcx, |
| 28 | 28 | thir, |
| 29 | 29 | found_errors: Ok(()), |
| 30 | // FIXME(#132279): we're clearly in a body here. | |
| 31 | typing_env: ty::TypingEnv::non_body_analysis(tcx, def), | |
| 30 | typing_env: ty::TypingEnv::post_typeck_until_borrowck_for_mir_build(tcx, def), | |
| 32 | 31 | is_closure, |
| 33 | 32 | caller_def_id: def, |
| 34 | 33 | }; |
compiler/rustc_mir_build/src/check_unsafety.rs+1-2| ... | ... | @@ -1093,8 +1093,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { |
| 1093 | 1093 | body_target_features, |
| 1094 | 1094 | assignment_info: None, |
| 1095 | 1095 | in_union_destructure: false, |
| 1096 | // FIXME(#132279): we're clearly in a body here. | |
| 1097 | typing_env: ty::TypingEnv::non_body_analysis(tcx, def), | |
| 1096 | typing_env: ty::TypingEnv::post_typeck_until_borrowck_for_mir_build(tcx, def), | |
| 1098 | 1097 | inside_adt: false, |
| 1099 | 1098 | warnings: &mut warnings, |
| 1100 | 1099 | suggest_unsafe_block: true, |
compiler/rustc_mir_build/src/thir/cx/mod.rs+1-3| ... | ... | @@ -99,9 +99,7 @@ impl<'tcx> ThirBuildCx<'tcx> { |
| 99 | 99 | Self { |
| 100 | 100 | tcx, |
| 101 | 101 | thir: Thir::new(body_type), |
| 102 | // FIXME(#132279): We're in a body, we should use a typing | |
| 103 | // mode which reveals the opaque types defined by that body. | |
| 104 | typing_env: ty::TypingEnv::non_body_analysis(tcx, def), | |
| 102 | typing_env: ty::TypingEnv::post_typeck_until_borrowck_for_mir_build(tcx, def), | |
| 105 | 103 | typeck_results, |
| 106 | 104 | body_owner: def.to_def_id(), |
| 107 | 105 | apply_adjustments: !find_attr!(tcx, hir_id, CustomMir(..)), |
compiler/rustc_mir_build/src/thir/pattern/check_match.rs+1-2| ... | ... | @@ -39,8 +39,7 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err |
| 39 | 39 | tcx, |
| 40 | 40 | thir: &*thir, |
| 41 | 41 | typeck_results, |
| 42 | // FIXME(#132279): We're in a body, should handle opaques. | |
| 43 | typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id), | |
| 42 | typing_env: ty::TypingEnv::post_typeck_until_borrowck_for_mir_build(tcx, def_id), | |
| 44 | 43 | hir_source: tcx.local_def_id_to_hir_id(def_id), |
| 45 | 44 | let_source: LetSource::None, |
| 46 | 45 | pattern_arena: &pattern_arena, |
compiler/rustc_mir_transform/src/check_null.rs+12-12| ... | ... | @@ -55,16 +55,19 @@ fn insert_null_check<'tcx>( |
| 55 | 55 | const_: Const::Val(ConstValue::from_target_usize(0, &tcx), tcx.types.usize), |
| 56 | 56 | })); |
| 57 | 57 | |
| 58 | let pointee_should_be_checked = match context { | |
| 58 | let (pointee_should_be_checked, assert_kind) = match context { | |
| 59 | 59 | // Borrows pointing to "null" are UB even if the pointee is a ZST. |
| 60 | 60 | PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
| 61 | 61 | | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => { |
| 62 | 62 | // Pointer should be checked unconditionally. |
| 63 | Operand::Constant(Box::new(ConstOperand { | |
| 64 | span: source_info.span, | |
| 65 | user_ty: None, | |
| 66 | const_: Const::from_bool(tcx, true), | |
| 67 | })) | |
| 63 | ( | |
| 64 | Operand::Constant(Box::new(ConstOperand { | |
| 65 | span: source_info.span, | |
| 66 | user_ty: None, | |
| 67 | const_: Const::from_bool(tcx, true), | |
| 68 | })), | |
| 69 | AssertKind::NullReferenceConstructed, | |
| 70 | ) | |
| 68 | 71 | } |
| 69 | 72 | // Other usages of null pointers only are UB if the pointee is not a ZST. |
| 70 | 73 | _ => { |
| ... | ... | @@ -79,7 +82,7 @@ fn insert_null_check<'tcx>( |
| 79 | 82 | source_info, |
| 80 | 83 | StatementKind::Assign(Box::new((pointee_should_be_checked, rvalue))), |
| 81 | 84 | )); |
| 82 | Operand::Copy(pointee_should_be_checked) | |
| 85 | (Operand::Copy(pointee_should_be_checked), AssertKind::NullPointerDereference) | |
| 83 | 86 | } |
| 84 | 87 | }; |
| 85 | 88 | |
| ... | ... | @@ -119,9 +122,6 @@ fn insert_null_check<'tcx>( |
| 119 | 122 | )); |
| 120 | 123 | |
| 121 | 124 | // Emit a PointerCheck that asserts on the condition and otherwise triggers |
| 122 | // a AssertKind::NullPointerDereference. | |
| 123 | PointerCheck { | |
| 124 | cond: Operand::Copy(is_ok), | |
| 125 | assert_kind: Box::new(AssertKind::NullPointerDereference), | |
| 126 | } | |
| 125 | // the chosen AssertKind. | |
| 126 | PointerCheck { cond: Operand::Copy(is_ok), assert_kind: Box::new(assert_kind) } | |
| 127 | 127 | } |
compiler/rustc_monomorphize/src/collector.rs+3| ... | ... | @@ -899,6 +899,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { |
| 899 | 899 | mir::AssertKind::NullPointerDereference => { |
| 900 | 900 | push_mono_lang_item(self, LangItem::PanicNullPointerDereference); |
| 901 | 901 | } |
| 902 | mir::AssertKind::NullReferenceConstructed => { | |
| 903 | push_mono_lang_item(self, LangItem::PanicNullReferenceConstructed); | |
| 904 | } | |
| 902 | 905 | mir::AssertKind::InvalidEnumConstruction(_) => { |
| 903 | 906 | push_mono_lang_item(self, LangItem::PanicInvalidEnumConstruction); |
| 904 | 907 | } |
compiler/rustc_public/src/mir/body.rs+2| ... | ... | @@ -269,6 +269,7 @@ pub enum AssertMessage { |
| 269 | 269 | ResumedAfterDrop(CoroutineKind), |
| 270 | 270 | MisalignedPointerDereference { required: Operand, found: Operand }, |
| 271 | 271 | NullPointerDereference, |
| 272 | NullReferenceConstructed, | |
| 272 | 273 | InvalidEnumConstruction(Operand), |
| 273 | 274 | } |
| 274 | 275 | |
| ... | ... | @@ -342,6 +343,7 @@ impl AssertMessage { |
| 342 | 343 | Ok("misaligned pointer dereference") |
| 343 | 344 | } |
| 344 | 345 | AssertMessage::NullPointerDereference => Ok("null pointer dereference occurred"), |
| 346 | AssertMessage::NullReferenceConstructed => Ok("null reference produced"), | |
| 345 | 347 | AssertMessage::InvalidEnumConstruction(_) => { |
| 346 | 348 | Ok("trying to construct an enum from an invalid value") |
| 347 | 349 | } |
compiler/rustc_public/src/mir/pretty.rs+3| ... | ... | @@ -310,6 +310,9 @@ fn pretty_assert_message<W: Write>(writer: &mut W, msg: &AssertMessage) -> io::R |
| 310 | 310 | AssertMessage::NullPointerDereference => { |
| 311 | 311 | write!(writer, "\"null pointer dereference occurred\"") |
| 312 | 312 | } |
| 313 | AssertMessage::NullReferenceConstructed => { | |
| 314 | write!(writer, "\"null reference produced\"") | |
| 315 | } | |
| 313 | 316 | AssertMessage::InvalidEnumConstruction(op) => { |
| 314 | 317 | let pretty_op = pretty_operand(op); |
| 315 | 318 | write!(writer, "\"trying to construct an enum from an invalid value {{}}\",{pretty_op}") |
compiler/rustc_public/src/mir/visit.rs+1| ... | ... | @@ -369,6 +369,7 @@ macro_rules! make_mir_visitor { |
| 369 | 369 | AssertMessage::ResumedAfterReturn(_) |
| 370 | 370 | | AssertMessage::ResumedAfterPanic(_) |
| 371 | 371 | | AssertMessage::NullPointerDereference |
| 372 | | AssertMessage::NullReferenceConstructed | |
| 372 | 373 | | AssertMessage::ResumedAfterDrop(_) => { |
| 373 | 374 | //nothing to visit |
| 374 | 375 | } |
compiler/rustc_public/src/unstable/convert/stable/mir.rs+3| ... | ... | @@ -559,6 +559,9 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { |
| 559 | 559 | } |
| 560 | 560 | } |
| 561 | 561 | AssertKind::NullPointerDereference => crate::mir::AssertMessage::NullPointerDereference, |
| 562 | AssertKind::NullReferenceConstructed => { | |
| 563 | crate::mir::AssertMessage::NullReferenceConstructed | |
| 564 | } | |
| 562 | 565 | AssertKind::InvalidEnumConstruction(source) => { |
| 563 | 566 | crate::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables, cx)) |
| 564 | 567 | } |
compiler/rustc_span/src/symbol.rs+1| ... | ... | @@ -1536,6 +1536,7 @@ symbols! { |
| 1536 | 1536 | panic_misaligned_pointer_dereference, |
| 1537 | 1537 | panic_nounwind, |
| 1538 | 1538 | panic_null_pointer_dereference, |
| 1539 | panic_null_reference_constructed, | |
| 1539 | 1540 | panic_runtime, |
| 1540 | 1541 | panic_str_2015, |
| 1541 | 1542 | panic_unwind, |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+14-4| ... | ... | @@ -4895,12 +4895,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { |
| 4895 | 4895 | }) |
| 4896 | 4896 | } else if let Some(where_pred) = where_pred.as_projection_clause() |
| 4897 | 4897 | && let Some(failed_pred) = failed_pred.as_projection_clause() |
| 4898 | && let Some(found) = failed_pred.skip_binder().term.as_type() | |
| 4898 | && let Some(found) = | |
| 4899 | failed_pred.map_bound(|pred| pred.term.as_type()).transpose().map(|term| { | |
| 4900 | self.instantiate_binder_with_fresh_vars( | |
| 4901 | expr.span, | |
| 4902 | BoundRegionConversionTime::FnCall, | |
| 4903 | term, | |
| 4904 | ) | |
| 4905 | }) | |
| 4899 | 4906 | { |
| 4900 | 4907 | type_diffs = vec![TypeError::Sorts(ty::error::ExpectedFound { |
| 4901 | expected: where_pred | |
| 4902 | .skip_binder() | |
| 4903 | .projection_term | |
| 4908 | expected: self | |
| 4909 | .instantiate_binder_with_fresh_vars( | |
| 4910 | expr.span, | |
| 4911 | BoundRegionConversionTime::FnCall, | |
| 4912 | where_pred.map_bound(|pred| pred.projection_term), | |
| 4913 | ) | |
| 4904 | 4914 | .expect_ty() |
| 4905 | 4915 | .to_ty(self.tcx, ty::IsRigid::No), |
| 4906 | 4916 | found, |
compiler/rustc_trait_selection/src/traits/auto_trait.rs+83| ... | ... | @@ -33,6 +33,7 @@ pub struct RegionDeps<'tcx> { |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | pub enum AutoTraitResult<A> { |
| 36 | NoImpl, | |
| 36 | 37 | ExplicitImpl, |
| 37 | 38 | PositiveImpl(A), |
| 38 | 39 | NegativeImpl, |
| ... | ... | @@ -80,6 +81,15 @@ impl<'tcx> AutoTraitFinder<'tcx> { |
| 80 | 81 | ) -> AutoTraitResult<A> { |
| 81 | 82 | let tcx = self.tcx; |
| 82 | 83 | |
| 84 | if tcx.next_trait_solver_globally() { | |
| 85 | return self.find_auto_trait_generics_next_solver( | |
| 86 | ty, | |
| 87 | typing_env, | |
| 88 | trait_did, | |
| 89 | auto_trait_callback, | |
| 90 | ); | |
| 91 | } | |
| 92 | ||
| 83 | 93 | let trait_ref = ty::TraitRef::new(tcx, trait_did, [ty]); |
| 84 | 94 | |
| 85 | 95 | let (infcx, orig_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); |
| ... | ... | @@ -175,6 +185,79 @@ impl<'tcx> AutoTraitFinder<'tcx> { |
| 175 | 185 | AutoTraitResult::PositiveImpl(auto_trait_callback(info)) |
| 176 | 186 | } |
| 177 | 187 | |
| 188 | fn find_auto_trait_generics_next_solver<A>( | |
| 189 | &self, | |
| 190 | ty: Ty<'tcx>, | |
| 191 | typing_env: ty::TypingEnv<'tcx>, | |
| 192 | trait_did: DefId, | |
| 193 | mut auto_trait_callback: impl FnMut(AutoTraitInfo<'tcx>) -> A, | |
| 194 | ) -> AutoTraitResult<A> { | |
| 195 | // When the new solver is enabled globally we keep things deliberately | |
| 196 | // simple. The precise auto-trait synthesis depends on old-solver | |
| 197 | // internals, so here we only synthesize a simple field-based auto-trait | |
| 198 | // impl for ADTs. | |
| 199 | // | |
| 200 | // If the self type is not an ADT we return `NoImpl` instead of trying | |
| 201 | // to do anything fancy. To decide whether to emit a negative impl, we | |
| 202 | // replace the ADT's generic arguments with inference variables and | |
| 203 | // check whether the auto trait can hold. A true error from that probe | |
| 204 | // becomes a `NegativeImpl`, otherwise we continue on to emit the | |
| 205 | // imprecise field-based impl. | |
| 206 | // | |
| 207 | // This keeps rustdoc from ICE-ing while `-Znext-solver=globally` is | |
| 208 | // used for testing, even if the generated synthetic impls are less | |
| 209 | // precise. | |
| 210 | let tcx = self.tcx; | |
| 211 | let ty::Adt(adt_def, args) = *ty.kind() else { | |
| 212 | return AutoTraitResult::NoImpl; | |
| 213 | }; | |
| 214 | ||
| 215 | let mut disqualifying_impl = None; | |
| 216 | tcx.for_each_relevant_impl(trait_did, ty, |impl_def_id| { | |
| 217 | disqualifying_impl = Some(impl_def_id); | |
| 218 | }); | |
| 219 | if let Some(impl_def_id) = disqualifying_impl { | |
| 220 | debug!( | |
| 221 | "find_auto_trait_generics({:?}): possible manual impl {impl_def_id:?} found, bailing", | |
| 222 | ty::TraitRef::new(tcx, trait_did, [ty]), | |
| 223 | ); | |
| 224 | return AutoTraitResult::ExplicitImpl; | |
| 225 | } | |
| 226 | ||
| 227 | let (infcx, orig_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); | |
| 228 | let field_clauses = adt_def | |
| 229 | .all_fields() | |
| 230 | .map(|field| field.ty(tcx, args).skip_norm_wip()) | |
| 231 | .filter(|field_ty| field_ty.has_non_region_param()) | |
| 232 | .map(|field_ty| { | |
| 233 | ty::TraitPredicate { | |
| 234 | trait_ref: ty::TraitRef::new(tcx, trait_did, [field_ty]), | |
| 235 | polarity: ty::PredicatePolarity::Positive, | |
| 236 | } | |
| 237 | .upcast(tcx) | |
| 238 | }) | |
| 239 | .collect::<Vec<ty::Clause<'tcx>>>(); | |
| 240 | let full_user_env = ty::ParamEnv::new( | |
| 241 | tcx.mk_clauses_from_iter(orig_env.caller_bounds().iter().chain(field_clauses)), | |
| 242 | ); | |
| 243 | ||
| 244 | let fresh_args = infcx.fresh_args_for_item(DUMMY_SP, adt_def.did()); | |
| 245 | let fresh_ty = ty::EarlyBinder::bind(tcx, ty).instantiate(tcx, fresh_args).skip_norm_wip(); | |
| 246 | let ocx = ObligationCtxt::new(&infcx); | |
| 247 | ocx.register_bound(ObligationCause::dummy(), orig_env, fresh_ty, trait_did); | |
| 248 | let errors = ocx.try_evaluate_obligations(); | |
| 249 | if !errors.is_empty() { | |
| 250 | return AutoTraitResult::NegativeImpl; | |
| 251 | } | |
| 252 | ||
| 253 | let info = AutoTraitInfo { | |
| 254 | full_user_env, | |
| 255 | region_data: RegionConstraintData::default(), | |
| 256 | vid_to_region: FxIndexMap::default(), | |
| 257 | }; | |
| 258 | AutoTraitResult::PositiveImpl(auto_trait_callback(info)) | |
| 259 | } | |
| 260 | ||
| 178 | 261 | /// The core logic responsible for computing the bounds for our synthesized impl. |
| 179 | 262 | /// |
| 180 | 263 | /// To calculate the bounds, we call `SelectionContext.select` in a loop. Like |
compiler/rustc_trait_selection/src/traits/coherence.rs-2| ... | ... | @@ -44,7 +44,6 @@ use crate::traits::{ |
| 44 | 44 | /// bounds / where-clauses). |
| 45 | 45 | #[derive(Clone, Debug, TypeFoldable, TypeVisitable)] |
| 46 | 46 | pub struct ImplHeader<'tcx> { |
| 47 | pub impl_def_id: DefId, | |
| 48 | 47 | pub impl_args: ty::GenericArgsRef<'tcx>, |
| 49 | 48 | pub self_ty: Ty<'tcx>, |
| 50 | 49 | pub trait_ref: Option<ty::TraitRef<'tcx>>, |
| ... | ... | @@ -207,7 +206,6 @@ fn fresh_impl_header<'tcx>( |
| 207 | 206 | let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); |
| 208 | 207 | |
| 209 | 208 | ImplHeader { |
| 210 | impl_def_id, | |
| 211 | 209 | impl_args, |
| 212 | 210 | self_ty: tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(), |
| 213 | 211 | trait_ref: is_of_trait |
library/core/src/panicking.rs+13| ... | ... | @@ -305,6 +305,19 @@ fn panic_null_pointer_dereference() -> ! { |
| 305 | 305 | ) |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))] | |
| 309 | #[cfg_attr(panic = "immediate-abort", inline)] | |
| 310 | #[track_caller] | |
| 311 | #[lang = "panic_null_reference_constructed"] // needed by codegen for panic on null reference formation | |
| 312 | #[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind | |
| 313 | fn panic_null_reference_constructed() -> ! { | |
| 314 | if cfg!(panic = "immediate-abort") { | |
| 315 | super::intrinsics::abort() | |
| 316 | } | |
| 317 | ||
| 318 | panic_nounwind_fmt(format_args!("null reference produced"), /* force_no_backtrace */ false) | |
| 319 | } | |
| 320 | ||
| 308 | 321 | #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))] |
| 309 | 322 | #[cfg_attr(panic = "immediate-abort", inline)] |
| 310 | 323 | #[track_caller] |
library/std/src/sync/mod.rs+8| ... | ... | @@ -164,6 +164,14 @@ |
| 164 | 164 | //! [`Once`]: crate::sync::Once |
| 165 | 165 | //! [`OnceLock`]: crate::sync::OnceLock |
| 166 | 166 | //! [`RwLock`]: crate::sync::RwLock |
| 167 | //! | |
| 168 | //! ## Blocking guarantees | |
| 169 | //! | |
| 170 | //! Methods that are documented not to block will never block for an unbounded length of time. | |
| 171 | //! That is, they may internally block through platform primitives but still "behave" like they are non-blocking. This difference is invisible to most programs. | |
| 172 | //! | |
| 173 | //! This is only of note to platforms which disallow blocking, such as multithreaded WebAssembly on the main thread. | |
| 174 | //! None of the implementations in `std::sync` are guaranteed to be (or remain) non-blocking in this regard. | |
| 167 | 175 | |
| 168 | 176 | #![stable(feature = "rust1", since = "1.0.0")] |
| 169 | 177 |
library/std/src/sync/mpmc/mod.rs+15-4| ... | ... | @@ -15,8 +15,9 @@ |
| 15 | 15 | //! |
| 16 | 16 | //! 1. An asynchronous, infinitely buffered channel. The [`channel`] function |
| 17 | 17 | //! will return a `(Sender, Receiver)` tuple where all sends will be |
| 18 | //! **asynchronous** (they never block). The channel conceptually has an | |
| 19 | //! infinite buffer. | |
| 18 | //! **asynchronous** (they never block for space to become available; see | |
| 19 | //! [`std::sync`] for precise guarantees on blocking.) The channel | |
| 20 | //! conceptually has an infinite buffer. | |
| 20 | 21 | //! |
| 21 | 22 | //! 2. A synchronous, bounded channel. The [`sync_channel`] function will |
| 22 | 23 | //! return a `(Sender, Receiver)` tuple where the storage for pending |
| ... | ... | @@ -26,6 +27,7 @@ |
| 26 | 27 | //! channel where each sender atomically hands off a message to a receiver. |
| 27 | 28 | //! |
| 28 | 29 | //! [`send`]: Sender::send |
| 30 | //! [`std::sync`]: ../index.html#blocking-guarantees | |
| 29 | 31 | //! |
| 30 | 32 | //! ## Disconnection |
| 31 | 33 | //! |
| ... | ... | @@ -374,6 +376,11 @@ impl<T> Sender<T> { |
| 374 | 376 | /// If called on a zero-capacity channel, this method will wait for a receive |
| 375 | 377 | /// operation to appear on the other side of the channel. |
| 376 | 378 | /// |
| 379 | /// If called on an unbounded channel, this method will never block in order to wait for space to | |
| 380 | /// become available. (See [`std::sync`] for precise guarantees on blocking.) | |
| 381 | /// | |
| 382 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 383 | /// | |
| 377 | 384 | /// # Examples |
| 378 | 385 | /// |
| 379 | 386 | /// ``` |
| ... | ... | @@ -770,9 +777,11 @@ pub struct Iter<'a, T: 'a> { |
| 770 | 777 | /// if the corresponding channel has hung up. |
| 771 | 778 | /// |
| 772 | 779 | /// This iterator will never block the caller in order to wait for data to |
| 773 | /// become available. Instead, it will return [`None`]. | |
| 780 | /// become available. Instead, it will return [`None`]. (See [`std::sync`] for | |
| 781 | /// precise guarantees on blocking.) | |
| 774 | 782 | /// |
| 775 | 783 | /// [`try_iter`]: Receiver::try_iter |
| 784 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 776 | 785 | /// |
| 777 | 786 | /// # Examples |
| 778 | 787 | /// |
| ... | ... | @@ -917,7 +926,8 @@ impl<T> Receiver<T> { |
| 917 | 926 | /// |
| 918 | 927 | /// This method will never block the caller in order to wait for data to |
| 919 | 928 | /// become available. Instead, this will always return immediately with a |
| 920 | /// possible option of pending data on the channel. | |
| 929 | /// possible option of pending data on the channel. (See [`std::sync`] for precise | |
| 930 | /// guarantees on blocking.) | |
| 921 | 931 | /// |
| 922 | 932 | /// If called on a zero-capacity channel, this method will receive a message only if there |
| 923 | 933 | /// happens to be a send operation on the other side of the channel at the same time. |
| ... | ... | @@ -929,6 +939,7 @@ impl<T> Receiver<T> { |
| 929 | 939 | /// (one for disconnection, one for an empty buffer). |
| 930 | 940 | /// |
| 931 | 941 | /// [`recv`]: Self::recv |
| 942 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 932 | 943 | /// |
| 933 | 944 | /// # Examples |
| 934 | 945 | /// |
library/std/src/sync/mpsc.rs+14-5| ... | ... | @@ -15,8 +15,9 @@ |
| 15 | 15 | //! |
| 16 | 16 | //! 1. An asynchronous, infinitely buffered channel. The [`channel`] function |
| 17 | 17 | //! will return a `(Sender, Receiver)` tuple where all sends will be |
| 18 | //! **asynchronous** (they never block). The channel conceptually has an | |
| 19 | //! infinite buffer. | |
| 18 | //! **asynchronous** (they never block for space to become available; see | |
| 19 | //! [`std::sync`] for precise guarantees on blocking.) The channel | |
| 20 | //! conceptually has an infinite buffer. | |
| 20 | 21 | //! |
| 21 | 22 | //! 2. A synchronous, bounded channel. The [`sync_channel`] function will |
| 22 | 23 | //! return a `(SyncSender, Receiver)` tuple where the storage for pending |
| ... | ... | @@ -26,6 +27,7 @@ |
| 26 | 27 | //! channel where each sender atomically hands off a message to a receiver. |
| 27 | 28 | //! |
| 28 | 29 | //! [`send`]: Sender::send |
| 30 | //! [`std::sync`]: ../index.html#blocking-guarantees | |
| 29 | 31 | //! |
| 30 | 32 | //! ## Disconnection |
| 31 | 33 | //! |
| ... | ... | @@ -228,9 +230,11 @@ pub struct Iter<'a, T: 'a> { |
| 228 | 230 | /// if the corresponding channel has hung up. |
| 229 | 231 | /// |
| 230 | 232 | /// This iterator will never block the caller in order to wait for data to |
| 231 | /// become available. Instead, it will return [`None`]. | |
| 233 | /// become available. Instead, it will return [`None`]. (See [`std::sync`] for | |
| 234 | /// precise guarantees on blocking.) | |
| 232 | 235 | /// |
| 233 | 236 | /// [`try_iter`]: Receiver::try_iter |
| 237 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 234 | 238 | /// |
| 235 | 239 | /// # Examples |
| 236 | 240 | /// |
| ... | ... | @@ -590,7 +594,10 @@ impl<T> Sender<T> { |
| 590 | 594 | /// will be received. It is possible for the corresponding receiver to |
| 591 | 595 | /// hang up immediately after this function returns [`Ok`]. |
| 592 | 596 | /// |
| 593 | /// This method will never block the current thread. | |
| 597 | /// This method will never block the caller in order to wait for space to | |
| 598 | /// become available. (See [`std::sync`] for precise guarantees on blocking.) | |
| 599 | /// | |
| 600 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 594 | 601 | /// |
| 595 | 602 | /// # Examples |
| 596 | 603 | /// |
| ... | ... | @@ -798,7 +805,8 @@ impl<T> Receiver<T> { |
| 798 | 805 | /// |
| 799 | 806 | /// This method will never block the caller in order to wait for data to |
| 800 | 807 | /// become available. Instead, this will always return immediately with a |
| 801 | /// possible option of pending data on the channel. | |
| 808 | /// possible option of pending data on the channel. (See [`std::sync`] for | |
| 809 | /// precise guarantees on blocking.) | |
| 802 | 810 | /// |
| 803 | 811 | /// This is useful for a flavor of "optimistic check" before deciding to |
| 804 | 812 | /// block on a receiver. |
| ... | ... | @@ -807,6 +815,7 @@ impl<T> Receiver<T> { |
| 807 | 815 | /// (one for disconnection, one for an empty buffer). |
| 808 | 816 | /// |
| 809 | 817 | /// [`recv`]: Self::recv |
| 818 | /// [`std::sync`]: ../index.html#blocking-guarantees | |
| 810 | 819 | /// |
| 811 | 820 | /// # Examples |
| 812 | 821 | /// |
src/librustdoc/clean/auto_trait.rs+1| ... | ... | @@ -110,6 +110,7 @@ fn synthesize_auto_trait_impl<'tcx>( |
| 110 | 110 | |
| 111 | 111 | (generics, ty::ImplPolarity::Negative) |
| 112 | 112 | } |
| 113 | auto_trait::AutoTraitResult::NoImpl => return None, | |
| 113 | 114 | auto_trait::AutoTraitResult::ExplicitImpl => return None, |
| 114 | 115 | }; |
| 115 | 116 |
src/tools/rustbook/Cargo.lock+33-26| ... | ... | @@ -78,9 +78,9 @@ dependencies = [ |
| 78 | 78 | |
| 79 | 79 | [[package]] |
| 80 | 80 | name = "anyhow" |
| 81 | version = "1.0.102" | |
| 81 | version = "1.0.103" | |
| 82 | 82 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 83 | checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" | |
| 83 | checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" | |
| 84 | 84 | |
| 85 | 85 | [[package]] |
| 86 | 86 | name = "autocfg" |
| ... | ... | @@ -149,7 +149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
| 149 | 149 | checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" |
| 150 | 150 | dependencies = [ |
| 151 | 151 | "find-msvc-tools", |
| 152 | "shlex", | |
| 152 | "shlex 1.3.0", | |
| 153 | 153 | ] |
| 154 | 154 | |
| 155 | 155 | [[package]] |
| ... | ... | @@ -545,9 +545,9 @@ dependencies = [ |
| 545 | 545 | |
| 546 | 546 | [[package]] |
| 547 | 547 | name = "handlebars" |
| 548 | version = "6.4.1" | |
| 548 | version = "6.4.2" | |
| 549 | 549 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 550 | checksum = "d43ccdfe15a81ab0a8af639e90254227c9a46afd9c5f5b6ec7efaa345c4b0f00" | |
| 550 | checksum = "f26569a2763497b7bd3fbd19374b774ea6038c5293678771259cd534d49740ff" | |
| 551 | 551 | dependencies = [ |
| 552 | 552 | "derive_builder", |
| 553 | 553 | "log", |
| ... | ... | @@ -762,9 +762,9 @@ dependencies = [ |
| 762 | 762 | |
| 763 | 763 | [[package]] |
| 764 | 764 | name = "mdbook-core" |
| 765 | version = "0.5.3" | |
| 765 | version = "0.5.4" | |
| 766 | 766 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 767 | checksum = "6fc1c4da7fd9e2e412f3891428f9468fab890ed159723ed0892bb85a049ac1c1" | |
| 767 | checksum = "8725b7f8e94a5c40a00c907e4006301ba2fc06722de489a0cb19db1823fdf200" | |
| 768 | 768 | dependencies = [ |
| 769 | 769 | "anyhow", |
| 770 | 770 | "regex", |
| ... | ... | @@ -776,9 +776,9 @@ dependencies = [ |
| 776 | 776 | |
| 777 | 777 | [[package]] |
| 778 | 778 | name = "mdbook-driver" |
| 779 | version = "0.5.3" | |
| 779 | version = "0.5.4" | |
| 780 | 780 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 781 | checksum = "2068566fc3c100cfd19f4a13e4e0eb4fdcd2250cfd0aa633ec25102b1c98d53e" | |
| 781 | checksum = "485612ee2a91847760e742ce441673fa127306a43f44e666796f7d99d4592272" | |
| 782 | 782 | dependencies = [ |
| 783 | 783 | "anyhow", |
| 784 | 784 | "indexmap", |
| ... | ... | @@ -791,7 +791,7 @@ dependencies = [ |
| 791 | 791 | "regex", |
| 792 | 792 | "serde", |
| 793 | 793 | "serde_json", |
| 794 | "shlex", | |
| 794 | "shlex 2.0.1", | |
| 795 | 795 | "tempfile", |
| 796 | 796 | "toml 1.1.2+spec-1.1.0", |
| 797 | 797 | "topological-sort", |
| ... | ... | @@ -800,9 +800,9 @@ dependencies = [ |
| 800 | 800 | |
| 801 | 801 | [[package]] |
| 802 | 802 | name = "mdbook-html" |
| 803 | version = "0.5.3" | |
| 803 | version = "0.5.4" | |
| 804 | 804 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 805 | checksum = "85ed2140251689f928615f0a5615413eb072eb28e003d179257aa4f034c95513" | |
| 805 | checksum = "8d25933e4d7cbaa342db9ab9f414c2a09b1c59becb63ad344520370d822ab28a" | |
| 806 | 806 | dependencies = [ |
| 807 | 807 | "anyhow", |
| 808 | 808 | "ego-tree", |
| ... | ... | @@ -846,9 +846,9 @@ dependencies = [ |
| 846 | 846 | |
| 847 | 847 | [[package]] |
| 848 | 848 | name = "mdbook-markdown" |
| 849 | version = "0.5.3" | |
| 849 | version = "0.5.4" | |
| 850 | 850 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 851 | checksum = "2cb3ca9eadf02ce206118a0b9c264718723d669b110c01a720fa9a0786f30642" | |
| 851 | checksum = "9ca553aa4330b15fa2c706aef373bc714cc719513d1da73c17be3dba208b9aab" | |
| 852 | 852 | dependencies = [ |
| 853 | 853 | "pulldown-cmark 0.13.4", |
| 854 | 854 | "regex", |
| ... | ... | @@ -857,9 +857,9 @@ dependencies = [ |
| 857 | 857 | |
| 858 | 858 | [[package]] |
| 859 | 859 | name = "mdbook-preprocessor" |
| 860 | version = "0.5.3" | |
| 860 | version = "0.5.4" | |
| 861 | 861 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 862 | checksum = "8eff7b4afaafd664a649a03b8891ad8199aef359a35b911ad6c31acab38ed209" | |
| 862 | checksum = "f8e75b08763e31982701d5b2680124bd4bd9bed4a4e1b5a499381320ccae199f" | |
| 863 | 863 | dependencies = [ |
| 864 | 864 | "anyhow", |
| 865 | 865 | "mdbook-core", |
| ... | ... | @@ -869,9 +869,9 @@ dependencies = [ |
| 869 | 869 | |
| 870 | 870 | [[package]] |
| 871 | 871 | name = "mdbook-renderer" |
| 872 | version = "0.5.3" | |
| 872 | version = "0.5.4" | |
| 873 | 873 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 874 | checksum = "e607259410d53aa5cdaf5b6c1c6b3fd61f2e0f0523ebf457d34cd4f0b71e2a88" | |
| 874 | checksum = "75d378308f820f05c6c89e4ec552a3c64a0cc10ccab7dcc93a2baa3bc714ea1b" | |
| 875 | 875 | dependencies = [ |
| 876 | 876 | "anyhow", |
| 877 | 877 | "mdbook-core", |
| ... | ... | @@ -900,9 +900,9 @@ dependencies = [ |
| 900 | 900 | |
| 901 | 901 | [[package]] |
| 902 | 902 | name = "mdbook-summary" |
| 903 | version = "0.5.3" | |
| 903 | version = "0.5.4" | |
| 904 | 904 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 905 | checksum = "cae8a734e5e35b0bc145b46d01fd27e266ba647dcdb9b8c907cb6a29eca9122b" | |
| 905 | checksum = "2453622fa7236139365a9acd20314ab859ff747d57ba36ff0d476b64adc75cf8" | |
| 906 | 906 | dependencies = [ |
| 907 | 907 | "anyhow", |
| 908 | 908 | "mdbook-core", |
| ... | ... | @@ -930,9 +930,9 @@ dependencies = [ |
| 930 | 930 | |
| 931 | 931 | [[package]] |
| 932 | 932 | name = "memchr" |
| 933 | version = "2.8.0" | |
| 933 | version = "2.8.2" | |
| 934 | 934 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 935 | checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" | |
| 935 | checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" | |
| 936 | 936 | |
| 937 | 937 | [[package]] |
| 938 | 938 | name = "miniz_oxide" |
| ... | ... | @@ -1230,9 +1230,9 @@ dependencies = [ |
| 1230 | 1230 | |
| 1231 | 1231 | [[package]] |
| 1232 | 1232 | name = "regex" |
| 1233 | version = "1.12.3" | |
| 1233 | version = "1.12.4" | |
| 1234 | 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1235 | checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" | |
| 1235 | checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" | |
| 1236 | 1236 | dependencies = [ |
| 1237 | 1237 | "aho-corasick", |
| 1238 | 1238 | "memchr", |
| ... | ... | @@ -1253,9 +1253,9 @@ dependencies = [ |
| 1253 | 1253 | |
| 1254 | 1254 | [[package]] |
| 1255 | 1255 | name = "regex-syntax" |
| 1256 | version = "0.8.10" | |
| 1256 | version = "0.8.11" | |
| 1257 | 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1258 | checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" | |
| 1258 | checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" | |
| 1259 | 1259 | |
| 1260 | 1260 | [[package]] |
| 1261 | 1261 | name = "rustbook" |
| ... | ... | @@ -1345,6 +1345,7 @@ version = "1.0.150" |
| 1345 | 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1346 | 1346 | checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" |
| 1347 | 1347 | dependencies = [ |
| 1348 | "indexmap", | |
| 1348 | 1349 | "itoa", |
| 1349 | 1350 | "memchr", |
| 1350 | 1351 | "serde", |
| ... | ... | @@ -1407,6 +1408,12 @@ version = "1.3.0" |
| 1407 | 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1408 | 1409 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" |
| 1409 | 1410 | |
| 1411 | [[package]] | |
| 1412 | name = "shlex" | |
| 1413 | version = "2.0.1" | |
| 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1415 | checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" | |
| 1416 | ||
| 1410 | 1417 | [[package]] |
| 1411 | 1418 | name = "simd-adler32" |
| 1412 | 1419 | version = "0.3.9" |
src/tools/rustbook/Cargo.toml+1-1| ... | ... | @@ -9,7 +9,7 @@ edition = "2021" |
| 9 | 9 | |
| 10 | 10 | [dependencies] |
| 11 | 11 | clap = { version = "4.0.32", features = ["cargo"] } |
| 12 | mdbook-driver = { version = "0.5.3", features = ["search"] } | |
| 12 | mdbook-driver = { version = "0.5.4", features = ["search"] } | |
| 13 | 13 | mdbook-i18n-helpers = "0.4.0" |
| 14 | 14 | mdbook-spec = { path = "../../doc/reference/tools/mdbook-spec" } |
| 15 | 15 | mdbook-trpl = { path = "../../doc/book/packages/mdbook-trpl" } |
src/tools/rustc-perf+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | Subproject commit c0301bc44d175b9b2c5442b25049475c39d7700c | |
| 1 | Subproject commit dec492af8eb74903879bd356648fc42d7aaf8555 |
src/tools/tidy/src/deps.rs+4| ... | ... | @@ -244,6 +244,10 @@ const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ |
| 244 | 244 | // tidy-alphabetical-start |
| 245 | 245 | ("inferno", "CDDL-1.0"), |
| 246 | 246 | ("option-ext", "MPL-2.0"), |
| 247 | ("terminfo", "WTFPL"), | |
| 248 | ("wasite", "Apache-2.0 OR BSL-1.0 OR MIT"), | |
| 249 | ("wezterm-bidi", "MIT AND Unicode-DFS-2016"), | |
| 250 | ("whoami", "Apache-2.0 OR BSL-1.0 OR MIT"), | |
| 247 | 251 | // tidy-alphabetical-end |
| 248 | 252 | ]; |
| 249 | 253 |
tests/rustdoc-html/synthetic_auto/next-solver-ambiguity.rs created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | //@ compile-flags: -Znext-solver=globally | |
| 2 | //@ edition: 2021 | |
| 3 | #![crate_name = "foo"] | |
| 4 | ||
| 5 | //@ has 'foo/struct.Foo.html' | |
| 6 | //@ has - '//h3[@class="code-header"]' "impl<'a, 'b, T> Send for Foo<'a, 'b, T>where &'a T: Send, &'b T: Send" | |
| 7 | pub struct Foo<'a, 'b, T: 'a + 'b>(&'a T, &'b T); |
tests/rustdoc-html/synthetic_auto/next-solver-possible-impl.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //@ compile-flags: -Znext-solver=globally | |
| 2 | ||
| 3 | #![feature(auto_traits)] | |
| 4 | #![crate_name = "foo"] | |
| 5 | ||
| 6 | pub auto trait Marker {} | |
| 7 | ||
| 8 | //@ has 'foo/struct.MyType.html' | |
| 9 | //@ !has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 'Marker for MyType<T>' | |
| 10 | pub struct MyType<T>(T); | |
| 11 | ||
| 12 | impl Marker for MyType<u32> {} |
tests/rustdoc-ui/synthetic-auto-trait-impls/next-solver-globally.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | // We used to ICE here while trying to synthesize auto trait impls | |
| 2 | // with the next trait solver enabled globally. | |
| 3 | //@ check-pass | |
| 4 | //@ compile-flags: -Znext-solver=globally | |
| 5 | ||
| 6 | #![feature(const_default)] | |
| 7 | #![feature(const_trait_impl)] | |
| 8 | ||
| 9 | pub struct Inner<T>(T); | |
| 10 | ||
| 11 | pub struct Outer<T>(Inner<T>); | |
| 12 | ||
| 13 | impl<T> Unpin for Inner<T> | |
| 14 | where | |
| 15 | T: const std::default::Default, | |
| 16 | {} |
tests/ui/associated-types/self-type-projection-dyn-coerce.rs created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/33461>. | |
| 2 | //! This used to ICE as coercion to trait object didn't normalize associated | |
| 3 | //! type. | |
| 4 | //@ run-pass | |
| 5 | ||
| 6 | #![allow(unused_variables)] | |
| 7 | use std::marker::PhantomData; | |
| 8 | ||
| 9 | struct TheType<T> { | |
| 10 | t: PhantomData<T> | |
| 11 | } | |
| 12 | ||
| 13 | pub trait TheTrait { | |
| 14 | type TheAssociatedType; | |
| 15 | } | |
| 16 | ||
| 17 | impl TheTrait for () { | |
| 18 | type TheAssociatedType = (); | |
| 19 | } | |
| 20 | ||
| 21 | pub trait Shape<P: TheTrait> { | |
| 22 | fn doit(&self) { | |
| 23 | } | |
| 24 | } | |
| 25 | ||
| 26 | impl<P: TheTrait> Shape<P> for TheType<P::TheAssociatedType> { | |
| 27 | } | |
| 28 | ||
| 29 | fn main() { | |
| 30 | let ball = TheType { t: PhantomData }; | |
| 31 | let handle: &dyn Shape<()> = &ball; | |
| 32 | } |
tests/ui/coherence/error-type-coherence-no-ice.rs created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/29857>. | |
| 2 | //! This used to ICE during coherence on Error types. | |
| 3 | //@ check-pass | |
| 4 | ||
| 5 | use std::marker::PhantomData; | |
| 6 | ||
| 7 | pub trait Foo<P> {} | |
| 8 | ||
| 9 | impl <P, T: Foo<P>> Foo<P> for Option<T> {} | |
| 10 | ||
| 11 | pub struct Qux<T> (PhantomData<*mut T>); | |
| 12 | ||
| 13 | impl<T> Foo<*mut T> for Option<Qux<T>> {} | |
| 14 | ||
| 15 | pub trait Bar { | |
| 16 | type Output: 'static; | |
| 17 | } | |
| 18 | ||
| 19 | impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {} | |
| 20 | ||
| 21 | fn main() {} |
tests/ui/const-generics/adt_const_params/cyclic-const-generic-issue-144719.rs created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | //! Const generic variant of #144719 | |
| 2 | ||
| 3 | #![feature(adt_const_params, unsized_const_params)] | |
| 4 | #![allow(incomplete_features)] | |
| 5 | ||
| 6 | use std::marker::ConstParamTy; | |
| 7 | ||
| 8 | #[derive(PartialEq, Eq, ConstParamTy)] | |
| 9 | struct Thing(&'static Thing); | |
| 10 | ||
| 11 | static X: Thing = Thing(&X); | |
| 12 | const Y: &Thing = &X; | |
| 13 | ||
| 14 | fn foo<const N: &'static Thing>() -> usize { 0 } | |
| 15 | ||
| 16 | fn main() { | |
| 17 | foo::<Y>(); | |
| 18 | //~^ ERROR constant main::{constant#0} cannot be used as pattern | |
| 19 | //~| ERROR constant main::{constant#0} cannot be used as pattern | |
| 20 | } |
tests/ui/const-generics/adt_const_params/cyclic-const-generic-issue-144719.stderr created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | error: constant main::{constant#0} cannot be used as pattern | |
| 2 | --> $DIR/cyclic-const-generic-issue-144719.rs:17:11 | |
| 3 | | | |
| 4 | LL | foo::<Y>(); | |
| 5 | | ^ | |
| 6 | | | |
| 7 | = note: constants whose type references itself cannot be used as patterns | |
| 8 | ||
| 9 | error: constant main::{constant#0} cannot be used as pattern | |
| 10 | --> $DIR/cyclic-const-generic-issue-144719.rs:17:11 | |
| 11 | | | |
| 12 | LL | foo::<Y>(); | |
| 13 | | ^ | |
| 14 | | | |
| 15 | = note: constants whose type references itself cannot be used as patterns | |
| 16 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 17 | ||
| 18 | error: aborting due to 2 previous errors | |
| 19 |
tests/ui/consts/const_in_pattern/cyclic-const-dag-pass.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //@ run-pass | |
| 2 | //! Regression test: shared references to the same static (DAG) must not be | |
| 3 | //! misidentified as cyclic during valtree construction. | |
| 4 | ||
| 5 | #[derive(PartialEq)] | |
| 6 | struct Pair(&'static i32, &'static i32); | |
| 7 | ||
| 8 | static X: i32 = 42; | |
| 9 | const P: Pair = Pair(&X, &X); | |
| 10 | ||
| 11 | fn main() { | |
| 12 | if let P = P {} | |
| 13 | } |
tests/ui/consts/const_in_pattern/cyclic-const-long-chain-issue-144719.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //! Regression test for #144719: long reference cycles shouldn't | |
| 2 | //! overflow the stack. | |
| 3 | //@ rustc-env:RUST_MIN_STACK=3000000 | |
| 4 | ||
| 5 | #[derive(PartialEq, Copy, Clone)] | |
| 6 | struct Thing(&'static Thing); | |
| 7 | ||
| 8 | const N: usize = 8000; | |
| 9 | static A: Thing = Thing(&B[0]); | |
| 10 | static B: [Thing; N] = { | |
| 11 | let mut x = [Thing(&A); N]; | |
| 12 | let mut i = 0; | |
| 13 | while i < N - 1 { | |
| 14 | x[i] = Thing(&B[i + 1]); | |
| 15 | i += 1; | |
| 16 | } | |
| 17 | x | |
| 18 | }; | |
| 19 | const C: &Thing = &A; | |
| 20 | ||
| 21 | fn main() { | |
| 22 | if let C = C {} | |
| 23 | //~^ ERROR constant C cannot be used as pattern | |
| 24 | } |
tests/ui/consts/const_in_pattern/cyclic-const-long-chain-issue-144719.stderr created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | error: constant C cannot be used as pattern | |
| 2 | --> $DIR/cyclic-const-long-chain-issue-144719.rs:22:12 | |
| 3 | | | |
| 4 | LL | if let C = C {} | |
| 5 | | ^ | |
| 6 | | | |
| 7 | = note: constants whose type references itself cannot be used as patterns | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 |
tests/ui/consts/const_in_pattern/cyclic-const-mutual-issue-144719.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //! Regression test for #144719: mutually recursive statics forming a | |
| 2 | //! reference cycle caused a stack overflow during valtree construction. | |
| 3 | ||
| 4 | #[derive(PartialEq)] | |
| 5 | struct Thing(&'static Thing); | |
| 6 | ||
| 7 | static A: Thing = Thing(&B); | |
| 8 | static B: Thing = Thing(&A); | |
| 9 | const C: &Thing = &A; | |
| 10 | ||
| 11 | fn main() { | |
| 12 | if let C = C {} | |
| 13 | //~^ ERROR constant C cannot be used as pattern | |
| 14 | } |
tests/ui/consts/const_in_pattern/cyclic-const-mutual-issue-144719.stderr created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | error: constant C cannot be used as pattern | |
| 2 | --> $DIR/cyclic-const-mutual-issue-144719.rs:12:12 | |
| 3 | | | |
| 4 | LL | if let C = C {} | |
| 5 | | ^ | |
| 6 | | | |
| 7 | = note: constants whose type references itself cannot be used as patterns | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 |
tests/ui/consts/const_in_pattern/cyclic-const-pattern-issue-144719.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //! Regression test for #144719: using a self-referential static in a | |
| 2 | //! pattern position caused a stack overflow during valtree construction. | |
| 3 | ||
| 4 | #[derive(PartialEq)] | |
| 5 | struct Thing(&'static Thing); | |
| 6 | ||
| 7 | static X: Thing = Thing(&X); | |
| 8 | const Y: &Thing = &X; | |
| 9 | ||
| 10 | fn main() { | |
| 11 | if let Y = Y {} | |
| 12 | //~^ ERROR constant Y cannot be used as pattern | |
| 13 | } |
tests/ui/consts/const_in_pattern/cyclic-const-pattern-issue-144719.stderr created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | error: constant Y cannot be used as pattern | |
| 2 | --> $DIR/cyclic-const-pattern-issue-144719.rs:11:12 | |
| 3 | | | |
| 4 | LL | if let Y = Y {} | |
| 5 | | ^ | |
| 6 | | | |
| 7 | = note: constants whose type references itself cannot be used as patterns | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 |
tests/ui/drop/drop-value-by-method.rs created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/3220>. | |
| 2 | //! Initially a pretty-printer bug, which omitted parentheses around `move` | |
| 3 | //! keyword in lhs (`(move z).f()`), now this behaviour is untestable as | |
| 4 | //! plain `move` outside a closure doesn't exist. | |
| 5 | //! | |
| 6 | //! Now appears to test that drop works correctly when value is moved by method. | |
| 7 | //@ run-pass | |
| 8 | ||
| 9 | #![allow(dead_code)] | |
| 10 | #![allow(non_camel_case_types)] | |
| 11 | ||
| 12 | struct thing { x: isize, } | |
| 13 | ||
| 14 | impl Drop for thing { | |
| 15 | fn drop(&mut self) {} | |
| 16 | } | |
| 17 | ||
| 18 | fn thing() -> thing { | |
| 19 | thing { | |
| 20 | x: 0 | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | impl thing { | |
| 25 | pub fn f(self) {} | |
| 26 | } | |
| 27 | ||
| 28 | pub fn main() { | |
| 29 | let z = thing(); | |
| 30 | (z).f(); | |
| 31 | } |
tests/ui/drop/panic-in-drop-during-assignment.rs created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/30380>. | |
| 2 | //! Check that panics in destructors during assignment do not leave | |
| 3 | //! destroyed values lying around for other destructors to observe. | |
| 4 | ||
| 5 | //@ run-fail | |
| 6 | //@ error-pattern:panicking destructors ftw! | |
| 7 | //@ needs-subprocess | |
| 8 | ||
| 9 | struct Observer<'a>(&'a mut FilledOnDrop); | |
| 10 | ||
| 11 | struct FilledOnDrop(u32); | |
| 12 | impl Drop for FilledOnDrop { | |
| 13 | fn drop(&mut self) { | |
| 14 | if self.0 == 0 { | |
| 15 | // this is only set during the destructor - safe | |
| 16 | // code should not be able to observe this. | |
| 17 | self.0 = 0x1c1c1c1c; | |
| 18 | panic!("panicking destructors ftw!"); | |
| 19 | } | |
| 20 | } | |
| 21 | } | |
| 22 | ||
| 23 | impl<'a> Drop for Observer<'a> { | |
| 24 | fn drop(&mut self) { | |
| 25 | assert_eq!(self.0 .0, 1); | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn foo(b: &mut Observer) { | |
| 30 | *b.0 = FilledOnDrop(1); | |
| 31 | } | |
| 32 | ||
| 33 | fn main() { | |
| 34 | let mut bomb = FilledOnDrop(0); | |
| 35 | let mut observer = Observer(&mut bomb); | |
| 36 | foo(&mut observer); | |
| 37 | } |
tests/ui/dst/unsized-tuple-trait-tail.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/33241>. | |
| 2 | //! This used to fire LLVM assertion, and later on ICE because of | |
| 3 | //! `t` type size incosistency between LLVM and rustc. | |
| 4 | //@ check-pass | |
| 5 | ||
| 6 | use std::fmt; | |
| 7 | ||
| 8 | // CoerceUnsized is not implemented for tuples. You can still create | |
| 9 | // an unsized tuple by transmuting a trait object. | |
| 10 | fn any<T>() -> T { unreachable!() } | |
| 11 | ||
| 12 | fn main() { | |
| 13 | let t: &(u8, dyn fmt::Debug) = any(); | |
| 14 | println!("{:?}", &t.1); | |
| 15 | } |
tests/ui/issues/issue-29857.rs deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | ||
| 3 | use std::marker::PhantomData; | |
| 4 | ||
| 5 | pub trait Foo<P> {} | |
| 6 | ||
| 7 | impl <P, T: Foo<P>> Foo<P> for Option<T> {} | |
| 8 | ||
| 9 | pub struct Qux<T> (PhantomData<*mut T>); | |
| 10 | ||
| 11 | impl<T> Foo<*mut T> for Option<Qux<T>> {} | |
| 12 | ||
| 13 | pub trait Bar { | |
| 14 | type Output: 'static; | |
| 15 | } | |
| 16 | ||
| 17 | impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {} | |
| 18 | ||
| 19 | fn main() {} |
tests/ui/issues/issue-30255.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | // | |
| 2 | // Test that lifetime elision error messages correctly omit parameters | |
| 3 | // with no elided lifetimes | |
| 4 | ||
| 5 | struct S<'a> { | |
| 6 | field: &'a i32, | |
| 7 | } | |
| 8 | ||
| 9 | fn f(a: &S, b: i32) -> &i32 { | |
| 10 | //~^ ERROR missing lifetime specifier [E0106] | |
| 11 | panic!(); | |
| 12 | } | |
| 13 | ||
| 14 | fn g(a: &S, b: bool, c: &i32) -> &i32 { | |
| 15 | //~^ ERROR missing lifetime specifier [E0106] | |
| 16 | panic!(); | |
| 17 | } | |
| 18 | ||
| 19 | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | |
| 20 | //~^ ERROR missing lifetime specifier [E0106] | |
| 21 | panic!(); | |
| 22 | } | |
| 23 | ||
| 24 | fn main() {} |
tests/ui/issues/issue-30255.stderr deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | error[E0106]: missing lifetime specifier | |
| 2 | --> $DIR/issue-30255.rs:9:24 | |
| 3 | | | |
| 4 | LL | fn f(a: &S, b: i32) -> &i32 { | |
| 5 | | -- ^ expected named lifetime parameter | |
| 6 | | | |
| 7 | = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from | |
| 8 | help: consider introducing a named lifetime parameter | |
| 9 | | | |
| 10 | LL | fn f<'a>(a: &'a S<'a>, b: i32) -> &'a i32 { | |
| 11 | | ++++ ++ ++++ ++ | |
| 12 | ||
| 13 | error[E0106]: missing lifetime specifier | |
| 14 | --> $DIR/issue-30255.rs:14:34 | |
| 15 | | | |
| 16 | LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | |
| 17 | | -- ---- ^ expected named lifetime parameter | |
| 18 | | | |
| 19 | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` | |
| 20 | help: consider introducing a named lifetime parameter | |
| 21 | | | |
| 22 | LL | fn g<'a>(a: &'a S<'a>, b: bool, c: &'a i32) -> &'a i32 { | |
| 23 | | ++++ ++ ++++ ++ ++ | |
| 24 | ||
| 25 | error[E0106]: missing lifetime specifier | |
| 26 | --> $DIR/issue-30255.rs:19:44 | |
| 27 | | | |
| 28 | LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | |
| 29 | | ----- -- ---- ^ expected named lifetime parameter | |
| 30 | | | |
| 31 | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` | |
| 32 | help: consider introducing a named lifetime parameter | |
| 33 | | | |
| 34 | LL | fn h<'a>(a: &'a bool, b: bool, c: &'a S<'a>, d: &'a i32) -> &'a i32 { | |
| 35 | | ++++ ++ ++ ++++ ++ ++ | |
| 36 | ||
| 37 | error: aborting due to 3 previous errors | |
| 38 | ||
| 39 | For more information about this error, try `rustc --explain E0106`. |
tests/ui/issues/issue-30371.rs deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unreachable_code)] | |
| 3 | #![allow(for_loops_over_fallibles)] | |
| 4 | #![deny(unused_variables)] | |
| 5 | ||
| 6 | fn main() { | |
| 7 | for _ in match return () { | |
| 8 | () => Some(0), | |
| 9 | } {} | |
| 10 | } |
tests/ui/issues/issue-30380.rs deleted-36| ... | ... | @@ -1,36 +0,0 @@ |
| 1 | // check that panics in destructors during assignment do not leave | |
| 2 | // destroyed values lying around for other destructors to observe. | |
| 3 | ||
| 4 | //@ run-fail | |
| 5 | //@ error-pattern:panicking destructors ftw! | |
| 6 | //@ needs-subprocess | |
| 7 | ||
| 8 | struct Observer<'a>(&'a mut FilledOnDrop); | |
| 9 | ||
| 10 | struct FilledOnDrop(u32); | |
| 11 | impl Drop for FilledOnDrop { | |
| 12 | fn drop(&mut self) { | |
| 13 | if self.0 == 0 { | |
| 14 | // this is only set during the destructor - safe | |
| 15 | // code should not be able to observe this. | |
| 16 | self.0 = 0x1c1c1c1c; | |
| 17 | panic!("panicking destructors ftw!"); | |
| 18 | } | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | impl<'a> Drop for Observer<'a> { | |
| 23 | fn drop(&mut self) { | |
| 24 | assert_eq!(self.0 .0, 1); | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn foo(b: &mut Observer) { | |
| 29 | *b.0 = FilledOnDrop(1); | |
| 30 | } | |
| 31 | ||
| 32 | fn main() { | |
| 33 | let mut bomb = FilledOnDrop(0); | |
| 34 | let mut observer = Observer(&mut bomb); | |
| 35 | foo(&mut observer); | |
| 36 | } |
tests/ui/issues/issue-30589.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | use std::fmt; | |
| 2 | ||
| 3 | impl fmt::Display for DecoderError { //~ ERROR cannot find type `DecoderError` in this scope | |
| 4 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
| 5 | write!(f, "Missing data: {}", self.0) | |
| 6 | } | |
| 7 | } | |
| 8 | fn main() { | |
| 9 | } |
tests/ui/issues/issue-30589.stderr deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | error[E0425]: cannot find type `DecoderError` in this scope | |
| 2 | --> $DIR/issue-30589.rs:3:23 | |
| 3 | | | |
| 4 | LL | impl fmt::Display for DecoderError { | |
| 5 | | ^^^^^^^^^^^^ not found in this scope | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/issues/issue-31011.rs deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | //@ dont-require-annotations: NOTE | |
| 2 | ||
| 3 | macro_rules! log { | |
| 4 | ( $ctx:expr, $( $args:expr),* ) => { | |
| 5 | if $ctx.trace { | |
| 6 | //~^ ERROR no field `trace` on type `&T` | |
| 7 | println!( $( $args, )* ); | |
| 8 | } | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | // Create a structure. | |
| 13 | struct Foo { | |
| 14 | trace: bool, | |
| 15 | } | |
| 16 | ||
| 17 | // Generic wrapper calls log! with a structure. | |
| 18 | fn wrap<T>(context: &T) -> () | |
| 19 | { | |
| 20 | log!(context, "entered wrapper"); | |
| 21 | //~^ NOTE in this expansion of log! | |
| 22 | } | |
| 23 | ||
| 24 | fn main() { | |
| 25 | // Create a structure. | |
| 26 | let x = Foo { trace: true }; | |
| 27 | log!(x, "run started"); | |
| 28 | // Apply a closure which accesses internal fields. | |
| 29 | wrap(&x); | |
| 30 | log!(x, "run finished"); | |
| 31 | } |
tests/ui/issues/issue-31011.stderr deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | error[E0609]: no field `trace` on type `&T` | |
| 2 | --> $DIR/issue-31011.rs:5:17 | |
| 3 | | | |
| 4 | LL | if $ctx.trace { | |
| 5 | | ^^^^^ unknown field | |
| 6 | ... | |
| 7 | LL | fn wrap<T>(context: &T) -> () | |
| 8 | | - type parameter 'T' declared here | |
| 9 | LL | { | |
| 10 | LL | log!(context, "entered wrapper"); | |
| 11 | | -------------------------------- in this macro invocation | |
| 12 | | | |
| 13 | = note: this error originates in the macro `log` (in Nightly builds, run with -Z macro-backtrace for more info) | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0609`. |
tests/ui/issues/issue-3149.rs deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | //@ check-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | #![allow(non_snake_case)] | |
| 4 | ||
| 5 | fn Matrix4<T>(m11: T, m12: T, m13: T, m14: T, | |
| 6 | m21: T, m22: T, m23: T, m24: T, | |
| 7 | m31: T, m32: T, m33: T, m34: T, | |
| 8 | m41: T, m42: T, m43: T, m44: T) | |
| 9 | -> Matrix4<T> { | |
| 10 | Matrix4 { | |
| 11 | m11: m11, m12: m12, m13: m13, m14: m14, | |
| 12 | m21: m21, m22: m22, m23: m23, m24: m24, | |
| 13 | m31: m31, m32: m32, m33: m33, m34: m34, | |
| 14 | m41: m41, m42: m42, m43: m43, m44: m44 | |
| 15 | } | |
| 16 | } | |
| 17 | ||
| 18 | struct Matrix4<T> { | |
| 19 | m11: T, m12: T, m13: T, m14: T, | |
| 20 | m21: T, m22: T, m23: T, m24: T, | |
| 21 | m31: T, m32: T, m33: T, m34: T, | |
| 22 | m41: T, m42: T, m43: T, m44: T, | |
| 23 | } | |
| 24 | ||
| 25 | pub fn main() {} |
tests/ui/issues/issue-31776.rs deleted-56| ... | ... | @@ -1,56 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | #![allow(unused_variables)] | |
| 4 | #![allow(non_local_definitions)] | |
| 5 | // Various scenarios in which `pub` is required in blocks | |
| 6 | ||
| 7 | struct S; | |
| 8 | ||
| 9 | mod m { | |
| 10 | fn f() { | |
| 11 | impl crate::S { | |
| 12 | pub fn s(&self) {} | |
| 13 | } | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | // Scenario 1 | |
| 18 | ||
| 19 | pub trait Tr { | |
| 20 | type A; | |
| 21 | } | |
| 22 | pub struct S1; | |
| 23 | ||
| 24 | fn f() { | |
| 25 | pub struct Z; | |
| 26 | ||
| 27 | impl crate::Tr for crate::S1 { | |
| 28 | type A = Z; // Private-in-public error unless `struct Z` is pub | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | // Scenario 2 | |
| 33 | ||
| 34 | trait Tr1 { | |
| 35 | type A; | |
| 36 | fn pull(&self) -> Self::A; | |
| 37 | } | |
| 38 | struct S2; | |
| 39 | ||
| 40 | mod m1 { | |
| 41 | fn f() { | |
| 42 | pub struct Z { | |
| 43 | pub field: u8 | |
| 44 | } | |
| 45 | ||
| 46 | impl crate::Tr1 for crate::S2 { | |
| 47 | type A = Z; | |
| 48 | fn pull(&self) -> Self::A { Z{field: 10} } | |
| 49 | } | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | fn main() { | |
| 54 | S.s(); // Privacy error, unless `fn s` is pub | |
| 55 | let a = S2.pull().field; // Privacy error unless `field: u8` is pub | |
| 56 | } |
tests/ui/issues/issue-3220.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(dead_code)] | |
| 3 | #![allow(non_camel_case_types)] | |
| 4 | ||
| 5 | struct thing { x: isize, } | |
| 6 | ||
| 7 | impl Drop for thing { | |
| 8 | fn drop(&mut self) {} | |
| 9 | } | |
| 10 | ||
| 11 | fn thing() -> thing { | |
| 12 | thing { | |
| 13 | x: 0 | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | impl thing { | |
| 18 | pub fn f(self) {} | |
| 19 | } | |
| 20 | ||
| 21 | pub fn main() { | |
| 22 | let z = thing(); | |
| 23 | (z).f(); | |
| 24 | } |
tests/ui/issues/issue-32995.rs deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | fn main() { | |
| 2 | let x: usize() = 1; | |
| 3 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 4 | ||
| 5 | let b: ::std::boxed()::Box<_> = Box::new(1); | |
| 6 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 7 | ||
| 8 | let p = ::std::str::()::from_utf8(b"foo").unwrap(); | |
| 9 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 10 | ||
| 11 | let p = ::std::str::from_utf8::()(b"foo").unwrap(); | |
| 12 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 13 | ||
| 14 | let o : Box<dyn (::std::marker()::Send)> = Box::new(1); | |
| 15 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 16 | ||
| 17 | let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1); | |
| 18 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 19 | } | |
| 20 | ||
| 21 | fn foo<X:Default>() { | |
| 22 | let d : X() = Default::default(); | |
| 23 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 24 | } |
tests/ui/issues/issue-32995.stderr deleted-45| ... | ... | @@ -1,45 +0,0 @@ |
| 1 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 2 | --> $DIR/issue-32995.rs:2:12 | |
| 3 | | | |
| 4 | LL | let x: usize() = 1; | |
| 5 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 6 | ||
| 7 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 8 | --> $DIR/issue-32995.rs:5:19 | |
| 9 | | | |
| 10 | LL | let b: ::std::boxed()::Box<_> = Box::new(1); | |
| 11 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 12 | ||
| 13 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 14 | --> $DIR/issue-32995.rs:8:20 | |
| 15 | | | |
| 16 | LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); | |
| 17 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 18 | ||
| 19 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 20 | --> $DIR/issue-32995.rs:11:25 | |
| 21 | | | |
| 22 | LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); | |
| 23 | | ^^^^^^^^^^^^^ only `Fn` traits may use parentheses | |
| 24 | ||
| 25 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 26 | --> $DIR/issue-32995.rs:14:29 | |
| 27 | | | |
| 28 | LL | let o : Box<dyn (::std::marker()::Send)> = Box::new(1); | |
| 29 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 30 | ||
| 31 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 32 | --> $DIR/issue-32995.rs:17:35 | |
| 33 | | | |
| 34 | LL | let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1); | |
| 35 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 36 | ||
| 37 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 38 | --> $DIR/issue-32995.rs:22:13 | |
| 39 | | | |
| 40 | LL | let d : X() = Default::default(); | |
| 41 | | ^^^ only `Fn` traits may use parentheses | |
| 42 | ||
| 43 | error: aborting due to 7 previous errors | |
| 44 | ||
| 45 | For more information about this error, try `rustc --explain E0214`. |
tests/ui/issues/issue-3344.rs deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | #[derive(PartialEq)] | |
| 2 | struct Thing(usize); | |
| 3 | impl PartialOrd for Thing { //~ ERROR not all trait items implemented, missing: `partial_cmp` | |
| 4 | fn le(&self, other: &Thing) -> bool { true } | |
| 5 | fn ge(&self, other: &Thing) -> bool { true } | |
| 6 | } | |
| 7 | fn main() {} |
tests/ui/issues/issue-3344.stderr deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | error[E0046]: not all trait items implemented, missing: `partial_cmp` | |
| 2 | --> $DIR/issue-3344.rs:3:1 | |
| 3 | | | |
| 4 | LL | impl PartialOrd for Thing { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | |
| 6 | | | |
| 7 | = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }` | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0046`. |
tests/ui/issues/issue-33461.rs deleted-28| ... | ... | @@ -1,28 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | #![allow(unused_variables)] | |
| 3 | use std::marker::PhantomData; | |
| 4 | ||
| 5 | struct TheType<T> { | |
| 6 | t: PhantomData<T> | |
| 7 | } | |
| 8 | ||
| 9 | pub trait TheTrait { | |
| 10 | type TheAssociatedType; | |
| 11 | } | |
| 12 | ||
| 13 | impl TheTrait for () { | |
| 14 | type TheAssociatedType = (); | |
| 15 | } | |
| 16 | ||
| 17 | pub trait Shape<P: TheTrait> { | |
| 18 | fn doit(&self) { | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | impl<P: TheTrait> Shape<P> for TheType<P::TheAssociatedType> { | |
| 23 | } | |
| 24 | ||
| 25 | fn main() { | |
| 26 | let ball = TheType { t: PhantomData }; | |
| 27 | let handle: &dyn Shape<()> = &ball; | |
| 28 | } |
tests/ui/lifetimes/lifetime-errors/elision-error-omits-lifetimeless-params.rs created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/30255>. | |
| 2 | //! Test that lifetime elision error messages correctly omit parameters | |
| 3 | //! with no elided lifetimes. | |
| 4 | ||
| 5 | struct S<'a> { | |
| 6 | field: &'a i32, | |
| 7 | } | |
| 8 | ||
| 9 | fn f(a: &S, b: i32) -> &i32 { | |
| 10 | //~^ ERROR missing lifetime specifier [E0106] | |
| 11 | panic!(); | |
| 12 | } | |
| 13 | ||
| 14 | fn g(a: &S, b: bool, c: &i32) -> &i32 { | |
| 15 | //~^ ERROR missing lifetime specifier [E0106] | |
| 16 | panic!(); | |
| 17 | } | |
| 18 | ||
| 19 | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | |
| 20 | //~^ ERROR missing lifetime specifier [E0106] | |
| 21 | panic!(); | |
| 22 | } | |
| 23 | ||
| 24 | fn main() {} |
tests/ui/lifetimes/lifetime-errors/elision-error-omits-lifetimeless-params.stderr created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | error[E0106]: missing lifetime specifier | |
| 2 | --> $DIR/elision-error-omits-lifetimeless-params.rs:9:24 | |
| 3 | | | |
| 4 | LL | fn f(a: &S, b: i32) -> &i32 { | |
| 5 | | -- ^ expected named lifetime parameter | |
| 6 | | | |
| 7 | = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from | |
| 8 | help: consider introducing a named lifetime parameter | |
| 9 | | | |
| 10 | LL | fn f<'a>(a: &'a S<'a>, b: i32) -> &'a i32 { | |
| 11 | | ++++ ++ ++++ ++ | |
| 12 | ||
| 13 | error[E0106]: missing lifetime specifier | |
| 14 | --> $DIR/elision-error-omits-lifetimeless-params.rs:14:34 | |
| 15 | | | |
| 16 | LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | |
| 17 | | -- ---- ^ expected named lifetime parameter | |
| 18 | | | |
| 19 | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` | |
| 20 | help: consider introducing a named lifetime parameter | |
| 21 | | | |
| 22 | LL | fn g<'a>(a: &'a S<'a>, b: bool, c: &'a i32) -> &'a i32 { | |
| 23 | | ++++ ++ ++++ ++ ++ | |
| 24 | ||
| 25 | error[E0106]: missing lifetime specifier | |
| 26 | --> $DIR/elision-error-omits-lifetimeless-params.rs:19:44 | |
| 27 | | | |
| 28 | LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | |
| 29 | | ----- -- ---- ^ expected named lifetime parameter | |
| 30 | | | |
| 31 | = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` | |
| 32 | help: consider introducing a named lifetime parameter | |
| 33 | | | |
| 34 | LL | fn h<'a>(a: &'a bool, b: bool, c: &'a S<'a>, d: &'a i32) -> &'a i32 { | |
| 35 | | ++++ ++ ++ ++++ ++ ++ | |
| 36 | ||
| 37 | error: aborting due to 3 previous errors | |
| 38 | ||
| 39 | For more information about this error, try `rustc --explain E0106`. |
tests/ui/lint/unused/for-loop-no-spurious-unused-variable-lint.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/30371>. | |
| 2 | //! This used to emit unused variable warning. | |
| 3 | //@ run-pass | |
| 4 | ||
| 5 | #![allow(unreachable_code)] | |
| 6 | #![allow(for_loops_over_fallibles)] | |
| 7 | #![deny(unused_variables)] | |
| 8 | ||
| 9 | fn main() { | |
| 10 | for _ in match return () { | |
| 11 | () => Some(0), | |
| 12 | } {} | |
| 13 | } |
tests/ui/macros/no-field-error-in-macro-expansion-for-generic.rs created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/31011>. | |
| 2 | //! This macro used to ICE with unprintable span. | |
| 3 | //@ dont-require-annotations: NOTE | |
| 4 | ||
| 5 | macro_rules! log { | |
| 6 | ( $ctx:expr, $( $args:expr),* ) => { | |
| 7 | if $ctx.trace { | |
| 8 | //~^ ERROR no field `trace` on type `&T` | |
| 9 | println!( $( $args, )* ); | |
| 10 | } | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | // Create a structure. | |
| 15 | struct Foo { | |
| 16 | trace: bool, | |
| 17 | } | |
| 18 | ||
| 19 | // Generic wrapper calls log! with a structure. | |
| 20 | fn wrap<T>(context: &T) -> () | |
| 21 | { | |
| 22 | log!(context, "entered wrapper"); | |
| 23 | //~^ NOTE in this expansion of log! | |
| 24 | } | |
| 25 | ||
| 26 | fn main() { | |
| 27 | // Create a structure. | |
| 28 | let x = Foo { trace: true }; | |
| 29 | log!(x, "run started"); | |
| 30 | // Apply a closure which accesses internal fields. | |
| 31 | wrap(&x); | |
| 32 | log!(x, "run finished"); | |
| 33 | } |
tests/ui/macros/no-field-error-in-macro-expansion-for-generic.stderr created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | error[E0609]: no field `trace` on type `&T` | |
| 2 | --> $DIR/no-field-error-in-macro-expansion-for-generic.rs:7:17 | |
| 3 | | | |
| 4 | LL | if $ctx.trace { | |
| 5 | | ^^^^^ unknown field | |
| 6 | ... | |
| 7 | LL | fn wrap<T>(context: &T) -> () | |
| 8 | | - type parameter 'T' declared here | |
| 9 | LL | { | |
| 10 | LL | log!(context, "entered wrapper"); | |
| 11 | | -------------------------------- in this macro invocation | |
| 12 | | | |
| 13 | = note: this error originates in the macro `log` (in Nightly builds, run with -Z macro-backtrace for more info) | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0609`. |
tests/ui/mir/null/borrowed_mut_null.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-crash |
| 2 | 2 | //@ compile-flags: -C debug-assertions |
| 3 | //@ error-pattern: null pointer dereference occurred | |
| 3 | //@ error-pattern: null reference produced | |
| 4 | 4 | |
| 5 | 5 | fn main() { |
| 6 | 6 | let ptr: *mut u32 = std::ptr::null_mut(); |
tests/ui/mir/null/borrowed_null.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-crash |
| 2 | 2 | //@ compile-flags: -C debug-assertions |
| 3 | //@ error-pattern: null pointer dereference occurred | |
| 3 | //@ error-pattern: null reference produced | |
| 4 | 4 | |
| 5 | 5 | fn main() { |
| 6 | 6 | let ptr: *const u32 = std::ptr::null(); |
tests/ui/mir/null/borrowed_null_zst.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-crash |
| 2 | 2 | //@ compile-flags: -C debug-assertions |
| 3 | //@ error-pattern: null pointer dereference occurred | |
| 3 | //@ error-pattern: null reference produced | |
| 4 | 4 | |
| 5 | 5 | fn main() { |
| 6 | 6 | let ptr: *const () = std::ptr::null(); |
tests/ui/privacy/required-pub-in-blocks.rs created+58| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/31776>. | |
| 2 | //! Various scenarios in which `pub` is required in blocks. | |
| 3 | //@ run-pass | |
| 4 | ||
| 5 | #![allow(dead_code)] | |
| 6 | #![allow(unused_variables)] | |
| 7 | #![allow(non_local_definitions)] | |
| 8 | ||
| 9 | struct S; | |
| 10 | ||
| 11 | mod m { | |
| 12 | fn f() { | |
| 13 | impl crate::S { | |
| 14 | pub fn s(&self) {} | |
| 15 | } | |
| 16 | } | |
| 17 | } | |
| 18 | ||
| 19 | // Scenario 1 | |
| 20 | ||
| 21 | pub trait Tr { | |
| 22 | type A; | |
| 23 | } | |
| 24 | pub struct S1; | |
| 25 | ||
| 26 | fn f() { | |
| 27 | pub struct Z; | |
| 28 | ||
| 29 | impl crate::Tr for crate::S1 { | |
| 30 | type A = Z; // Private-in-public error unless `struct Z` is pub | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | // Scenario 2 | |
| 35 | ||
| 36 | trait Tr1 { | |
| 37 | type A; | |
| 38 | fn pull(&self) -> Self::A; | |
| 39 | } | |
| 40 | struct S2; | |
| 41 | ||
| 42 | mod m1 { | |
| 43 | fn f() { | |
| 44 | pub struct Z { | |
| 45 | pub field: u8 | |
| 46 | } | |
| 47 | ||
| 48 | impl crate::Tr1 for crate::S2 { | |
| 49 | type A = Z; | |
| 50 | fn pull(&self) -> Self::A { Z{field: 10} } | |
| 51 | } | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | fn main() { | |
| 56 | S.s(); // Privacy error, unless `fn s` is pub | |
| 57 | let a = S2.pull().field; // Privacy error unless `field: u8` is pub | |
| 58 | } |
tests/ui/resolve/generic-struct-and-fn-share-name.rs created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/3149>. | |
| 2 | //! This wrongly emitted a duplicate definition of value error. | |
| 3 | //@ check-pass | |
| 4 | ||
| 5 | #![allow(dead_code)] | |
| 6 | #![allow(non_snake_case)] | |
| 7 | ||
| 8 | fn Matrix4<T>(m11: T, m12: T, m13: T, m14: T, | |
| 9 | m21: T, m22: T, m23: T, m24: T, | |
| 10 | m31: T, m32: T, m33: T, m34: T, | |
| 11 | m41: T, m42: T, m43: T, m44: T) | |
| 12 | -> Matrix4<T> { | |
| 13 | Matrix4 { | |
| 14 | m11: m11, m12: m12, m13: m13, m14: m14, | |
| 15 | m21: m21, m22: m22, m23: m23, m24: m24, | |
| 16 | m31: m31, m32: m32, m33: m33, m34: m34, | |
| 17 | m41: m41, m42: m42, m43: m43, m44: m44 | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | struct Matrix4<T> { | |
| 22 | m11: T, m12: T, m13: T, m14: T, | |
| 23 | m21: T, m22: T, m23: T, m24: T, | |
| 24 | m31: T, m32: T, m33: T, m34: T, | |
| 25 | m41: T, m42: T, m43: T, m44: T, | |
| 26 | } | |
| 27 | ||
| 28 | pub fn main() {} |
tests/ui/resolve/impl-trait-for-undeclared-type.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/30589>. | |
| 2 | //! This used to ICE when coherence encountered an erroneous type. | |
| 3 | ||
| 4 | use std::fmt; | |
| 5 | ||
| 6 | impl fmt::Display for DecoderError { //~ ERROR cannot find type `DecoderError` in this scope | |
| 7 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
| 8 | write!(f, "Missing data: {}", self.0) | |
| 9 | } | |
| 10 | } | |
| 11 | fn main() { | |
| 12 | } |
tests/ui/resolve/impl-trait-for-undeclared-type.stderr created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | error[E0425]: cannot find type `DecoderError` in this scope | |
| 2 | --> $DIR/impl-trait-for-undeclared-type.rs:6:23 | |
| 3 | | | |
| 4 | LL | impl fmt::Display for DecoderError { | |
| 5 | | ^^^^^^^^^^^^ not found in this scope | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/traits/error-reporting/incomplete-partial-ord-impl.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/3344>. | |
| 2 | //! Unimplemented items in impl caused ICE. | |
| 3 | ||
| 4 | #[derive(PartialEq)] | |
| 5 | struct Thing(usize); | |
| 6 | impl PartialOrd for Thing { //~ ERROR not all trait items implemented, missing: `partial_cmp` | |
| 7 | fn le(&self, other: &Thing) -> bool { true } | |
| 8 | fn ge(&self, other: &Thing) -> bool { true } | |
| 9 | } | |
| 10 | fn main() {} |
tests/ui/traits/error-reporting/incomplete-partial-ord-impl.stderr created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | error[E0046]: not all trait items implemented, missing: `partial_cmp` | |
| 2 | --> $DIR/incomplete-partial-ord-impl.rs:6:1 | |
| 3 | | | |
| 4 | LL | impl PartialOrd for Thing { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | |
| 6 | | | |
| 7 | = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }` | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0046`. |
tests/ui/traits/late-bound-type-method-probe.rs created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | // A method probe involving a late-bound type parameter should report normal | |
| 2 | // diagnostics instead of ICEing while structurally normalizing obligations. | |
| 3 | ||
| 4 | #![feature(non_lifetime_binders)] | |
| 5 | #![allow(incomplete_features)] | |
| 6 | ||
| 7 | pub trait T { | |
| 8 | fn t<Tail>(&self, _: F) {} | |
| 9 | //~^ ERROR cannot find type `F` in this scope | |
| 10 | } | |
| 11 | ||
| 12 | pub fn crash<V>(v: &V) | |
| 13 | where | |
| 14 | for<F> F: T + 'static, | |
| 15 | { | |
| 16 | v.t(|| {}); | |
| 17 | } | |
| 18 | ||
| 19 | fn main() {} |
tests/ui/traits/late-bound-type-method-probe.stderr created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | error[E0425]: cannot find type `F` in this scope | |
| 2 | --> $DIR/late-bound-type-method-probe.rs:8:26 | |
| 3 | | | |
| 4 | LL | fn t<Tail>(&self, _: F) {} | |
| 5 | | ^ | |
| 6 | | | |
| 7 | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | |
| 8 | | | |
| 9 | = note: similarly named trait `Fn` defined here | |
| 10 | help: a trait with a similar name exists | |
| 11 | | | |
| 12 | LL | fn t<Tail>(&self, _: Fn) {} | |
| 13 | | + | |
| 14 | ||
| 15 | error: aborting due to 1 previous error | |
| 16 | ||
| 17 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/traits/next-solver/diagnostics/iterator-item-suggest-no-ice.rs created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/158317> | |
| 2 | //@ compile-flags: -Znext-solver | |
| 3 | ||
| 4 | trait FooMut { | |
| 5 | fn bar<I>(&self, _: I) | |
| 6 | where | |
| 7 | for<'b> &'b I: Iterator<Item = &'b ()>; | |
| 8 | ||
| 9 | fn bar<I>(&self, _: I) | |
| 10 | //~^ ERROR: the name `bar` is defined multiple times | |
| 11 | where | |
| 12 | I: Iterator, | |
| 13 | { | |
| 14 | let collection = vec![_I].iter().map(|x| ()); | |
| 15 | //~^ ERROR: cannot find value `_I` in this scope | |
| 16 | self.bar(collection); | |
| 17 | //~^ ERROR: `&'b _` is not an iterator | |
| 18 | //~| ERROR: type mismatch resolving `<&_ as Iterator>::Item == &()` | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn main() {} |
tests/ui/traits/next-solver/diagnostics/iterator-item-suggest-no-ice.stderr created+71| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | error[E0428]: the name `bar` is defined multiple times | |
| 2 | --> $DIR/iterator-item-suggest-no-ice.rs:9:5 | |
| 3 | | | |
| 4 | LL | / fn bar<I>(&self, _: I) | |
| 5 | LL | | where | |
| 6 | LL | | for<'b> &'b I: Iterator<Item = &'b ()>; | |
| 7 | | |_______________________________________________- previous definition of the value `bar` here | |
| 8 | LL | | |
| 9 | LL | / fn bar<I>(&self, _: I) | |
| 10 | LL | | | |
| 11 | LL | | where | |
| 12 | LL | | I: Iterator, | |
| 13 | ... | | |
| 14 | LL | | } | |
| 15 | | |_____^ `bar` redefined here | |
| 16 | | | |
| 17 | = note: `bar` must be defined only once in the value namespace of this trait | |
| 18 | ||
| 19 | error[E0425]: cannot find value `_I` in this scope | |
| 20 | --> $DIR/iterator-item-suggest-no-ice.rs:14:31 | |
| 21 | | | |
| 22 | LL | let collection = vec![_I].iter().map(|x| ()); | |
| 23 | | ^^ not found in this scope | |
| 24 | ||
| 25 | error[E0277]: `&'b _` is not an iterator | |
| 26 | --> $DIR/iterator-item-suggest-no-ice.rs:16:18 | |
| 27 | | | |
| 28 | LL | self.bar(collection); | |
| 29 | | --- ^^^^^^^^^^ `&'b _` is not an iterator | |
| 30 | | | | |
| 31 | | required by a bound introduced by this call | |
| 32 | | | |
| 33 | = help: the trait `for<'b> Iterator` is not implemented for `&'b _` | |
| 34 | note: required by a bound in `FooMut::bar` | |
| 35 | --> $DIR/iterator-item-suggest-no-ice.rs:7:24 | |
| 36 | | | |
| 37 | LL | fn bar<I>(&self, _: I) | |
| 38 | | --- required by a bound in this associated function | |
| 39 | LL | where | |
| 40 | LL | for<'b> &'b I: Iterator<Item = &'b ()>; | |
| 41 | | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `FooMut::bar` | |
| 42 | ||
| 43 | error[E0271]: type mismatch resolving `<&_ as Iterator>::Item == &()` | |
| 44 | --> $DIR/iterator-item-suggest-no-ice.rs:16:18 | |
| 45 | | | |
| 46 | LL | self.bar(collection); | |
| 47 | | --- ^^^^^^^^^^ types differ | |
| 48 | | | | |
| 49 | | required by a bound introduced by this call | |
| 50 | | | |
| 51 | note: the method call chain might not have had the expected associated types | |
| 52 | --> $DIR/iterator-item-suggest-no-ice.rs:14:35 | |
| 53 | | | |
| 54 | LL | let collection = vec![_I].iter().map(|x| ()); | |
| 55 | | -------- ^^^^^^ ----------- `Iterator::Item` remains `<{type error} as Iterator>::Item` here | |
| 56 | | | | | |
| 57 | | | `Iterator::Item` is `<{type error} as Iterator>::Item` here | |
| 58 | | this expression has type `Vec<{type error}>` | |
| 59 | note: required by a bound in `FooMut::bar` | |
| 60 | --> $DIR/iterator-item-suggest-no-ice.rs:7:33 | |
| 61 | | | |
| 62 | LL | fn bar<I>(&self, _: I) | |
| 63 | | --- required by a bound in this associated function | |
| 64 | LL | where | |
| 65 | LL | for<'b> &'b I: Iterator<Item = &'b ()>; | |
| 66 | | ^^^^^^^^^^^^^ required by this bound in `FooMut::bar` | |
| 67 | ||
| 68 | error: aborting due to 4 previous errors | |
| 69 | ||
| 70 | Some errors have detailed explanations: E0271, E0277, E0425, E0428. | |
| 71 | For more information about an error, try `rustc --explain E0271`. |
tests/ui/traits/next-solver/opaques/wrong-typing-mode-ice-1.rs created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | //@ compile-flags: -Znext-solver | |
| 2 | //@ edition: 2024 | |
| 3 | ||
| 4 | // Previously, when building MIR body, we were using typing env | |
| 5 | // `non_body_analysis` which is wrong since we're indeed in a body. | |
| 6 | // It caused opaque types in defining body to be not revealed. | |
| 7 | // This caused opaque types in the defining body not to be revealed. | |
| 8 | ||
| 9 | #![feature(type_alias_impl_trait)] | |
| 10 | ||
| 11 | struct Task<F>(F); | |
| 12 | ||
| 13 | impl Task<Foo> { | |
| 14 | fn spawn(&self, _: impl FnOnce() -> Foo) {} | |
| 15 | } | |
| 16 | type Foo = impl Sized; | |
| 17 | ||
| 18 | #[define_opaque(Foo)] | |
| 19 | fn foo() { | |
| 20 | async fn cb() {} | |
| 21 | Task::spawn(&POOL, cb) | |
| 22 | } | |
| 23 | ||
| 24 | static POOL: Task<Foo> = todo!(); | |
| 25 | //~^ ERROR: evaluation panicked | |
| 26 | ||
| 27 | fn main() {} |
tests/ui/traits/next-solver/opaques/wrong-typing-mode-ice-1.stderr created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | error[E0080]: evaluation panicked: not yet implemented | |
| 2 | --> $DIR/wrong-typing-mode-ice-1.rs:24:26 | |
| 3 | | | |
| 4 | LL | static POOL: Task<Foo> = todo!(); | |
| 5 | | ^^^^^^^ evaluation of `POOL` failed here | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For more information about this error, try `rustc --explain E0080`. |
tests/ui/traits/next-solver/opaques/wrong-typing-mode-ice-2.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | //@ compile-flags: -Znext-solver | |
| 2 | //@ check-pass | |
| 3 | ||
| 4 | // Previously, when building MIR body, we were using typing env | |
| 5 | // `non_body_analysis` which is wrong since we're indeed in a body. | |
| 6 | // It caused opaque types in defining body to be not revealed. | |
| 7 | // This caused opaque types in the defining body not to be revealed. | |
| 8 | ||
| 9 | #![feature(type_alias_impl_trait)] | |
| 10 | fn main() { | |
| 11 | struct Foo(U); | |
| 12 | type U = impl Copy; | |
| 13 | let foo: _ = Foo(()); | |
| 14 | let Foo(()) = foo; | |
| 15 | } |
tests/ui/typeck/parenthesized-type-parameters-error-32995.rs deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | // https://github.com/rust-lang/rust/issues/32995 | |
| 2 | fn main() { | |
| 3 | { fn f<X: ::std::marker()::Send>() {} } | |
| 4 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 5 | ||
| 6 | { fn f() -> impl ::std::marker()::Send { } } | |
| 7 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 8 | } | |
| 9 | ||
| 10 | #[derive(Clone)] | |
| 11 | struct X; | |
| 12 | ||
| 13 | impl ::std::marker()::Copy for X {} | |
| 14 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait |
tests/ui/typeck/parenthesized-type-parameters-error-32995.stderr deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 2 | --> $DIR/parenthesized-type-parameters-error-32995.rs:3:22 | |
| 3 | | | |
| 4 | LL | { fn f<X: ::std::marker()::Send>() {} } | |
| 5 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 6 | ||
| 7 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 8 | --> $DIR/parenthesized-type-parameters-error-32995.rs:6:29 | |
| 9 | | | |
| 10 | LL | { fn f() -> impl ::std::marker()::Send { } } | |
| 11 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 12 | ||
| 13 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 14 | --> $DIR/parenthesized-type-parameters-error-32995.rs:13:13 | |
| 15 | | | |
| 16 | LL | impl ::std::marker()::Copy for X {} | |
| 17 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 18 | ||
| 19 | error: aborting due to 3 previous errors | |
| 20 | ||
| 21 | For more information about this error, try `rustc --explain E0214`. |
tests/ui/typeck/parenthesized-type-params-in-paths.rs created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/32995>. | |
| 2 | //! Test parenthesized type params syntax is forbidden for non `Fn` trait, | |
| 3 | //! and can't be used in paths. | |
| 4 | ||
| 5 | fn main() { | |
| 6 | let x: usize() = 1; | |
| 7 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 8 | ||
| 9 | let b: ::std::boxed()::Box<_> = Box::new(1); | |
| 10 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 11 | ||
| 12 | let p = ::std::str::()::from_utf8(b"foo").unwrap(); | |
| 13 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 14 | ||
| 15 | let p = ::std::str::from_utf8::()(b"foo").unwrap(); | |
| 16 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 17 | ||
| 18 | let o : Box<dyn (::std::marker()::Send)> = Box::new(1); | |
| 19 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 20 | ||
| 21 | let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1); | |
| 22 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 23 | ||
| 24 | { fn f<X: ::std::marker()::Send>() {} } | |
| 25 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 26 | ||
| 27 | { fn f() -> impl ::std::marker()::Send { } } | |
| 28 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 29 | ||
| 30 | } | |
| 31 | ||
| 32 | #[derive(Clone)] | |
| 33 | struct X; | |
| 34 | ||
| 35 | impl ::std::marker()::Copy for X {} | |
| 36 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 37 | ||
| 38 | fn foo<X:Default>() { | |
| 39 | let d : X() = Default::default(); | |
| 40 | //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait | |
| 41 | } |
tests/ui/typeck/parenthesized-type-params-in-paths.stderr created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 2 | --> $DIR/parenthesized-type-params-in-paths.rs:6:12 | |
| 3 | | | |
| 4 | LL | let x: usize() = 1; | |
| 5 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 6 | ||
| 7 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 8 | --> $DIR/parenthesized-type-params-in-paths.rs:9:19 | |
| 9 | | | |
| 10 | LL | let b: ::std::boxed()::Box<_> = Box::new(1); | |
| 11 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 12 | ||
| 13 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 14 | --> $DIR/parenthesized-type-params-in-paths.rs:12:20 | |
| 15 | | | |
| 16 | LL | let p = ::std::str::()::from_utf8(b"foo").unwrap(); | |
| 17 | | ^^^^^^^ only `Fn` traits may use parentheses | |
| 18 | ||
| 19 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 20 | --> $DIR/parenthesized-type-params-in-paths.rs:15:25 | |
| 21 | | | |
| 22 | LL | let p = ::std::str::from_utf8::()(b"foo").unwrap(); | |
| 23 | | ^^^^^^^^^^^^^ only `Fn` traits may use parentheses | |
| 24 | ||
| 25 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 26 | --> $DIR/parenthesized-type-params-in-paths.rs:18:29 | |
| 27 | | | |
| 28 | LL | let o : Box<dyn (::std::marker()::Send)> = Box::new(1); | |
| 29 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 30 | ||
| 31 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 32 | --> $DIR/parenthesized-type-params-in-paths.rs:21:35 | |
| 33 | | | |
| 34 | LL | let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1); | |
| 35 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 36 | ||
| 37 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 38 | --> $DIR/parenthesized-type-params-in-paths.rs:24:22 | |
| 39 | | | |
| 40 | LL | { fn f<X: ::std::marker()::Send>() {} } | |
| 41 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 42 | ||
| 43 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 44 | --> $DIR/parenthesized-type-params-in-paths.rs:27:29 | |
| 45 | | | |
| 46 | LL | { fn f() -> impl ::std::marker()::Send { } } | |
| 47 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 48 | ||
| 49 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 50 | --> $DIR/parenthesized-type-params-in-paths.rs:35:13 | |
| 51 | | | |
| 52 | LL | impl ::std::marker()::Copy for X {} | |
| 53 | | ^^^^^^^^ only `Fn` traits may use parentheses | |
| 54 | ||
| 55 | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait | |
| 56 | --> $DIR/parenthesized-type-params-in-paths.rs:39:13 | |
| 57 | | | |
| 58 | LL | let d : X() = Default::default(); | |
| 59 | | ^^^ only `Fn` traits may use parentheses | |
| 60 | ||
| 61 | error: aborting due to 10 previous errors | |
| 62 | ||
| 63 | For more information about this error, try `rustc --explain E0214`. |