| author | bors <bors@rust-lang.org> 2025-02-26 20:21:40 UTC |
| committer | bors <bors@rust-lang.org> 2025-02-26 20:21:40 UTC |
| log | 00f245915b0c7839d42c26f9628220c4f1b93bf6 |
| tree | 56e236afc296a927ebe0bef418743021b5156509 |
| parent | ac91805f3179fc2225c60e8ccf5a1daa09d43f3d |
| parent | 46eb43e71b82512c7e29f4e91f87a74223215fea |
Rollup of 10 pull requests
Successful merges:
- #134585 (remove `MaybeUninit::uninit_array`)
- #136187 (Use less CString in the examples of CStr.)
- #137201 (Teach structured errors to display short `Ty<'_>`)
- #137620 (Fix `attr` cast for espidf)
- #137631 (Avoid collecting associated types for undefined trait)
- #137635 (Don't suggest constraining unstable associated types)
- #137642 (Rustc dev guide subtree update)
- #137660 (Update gcc submodule)
- #137670 (revert accidental change in get_closest_merge_commit)
- #137671 (Make -Z unpretty=mir suggest -Z dump-mir as well for discoverability)
r? `@ghost`
`@rustbot` modify labels: rollup87 files changed, 700 insertions(+), 328 deletions(-)
compiler/rustc_ast_passes/src/errors.rs-1| ... | ... | @@ -535,7 +535,6 @@ pub(crate) struct WhereClauseBeforeTypeAlias { |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | 537 | #[derive(Subdiagnostic)] |
| 538 | ||
| 539 | 538 | pub(crate) enum WhereClauseBeforeTypeAliasSugg { |
| 540 | 539 | #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")] |
| 541 | 540 | Remove { |
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs-1| ... | ... | @@ -287,7 +287,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 287 | 287 | None => "value".to_owned(), |
| 288 | 288 | }; |
| 289 | 289 | if needs_note { |
| 290 | let ty = self.infcx.tcx.short_string(ty, err.long_ty_path()); | |
| 291 | 290 | if let Some(local) = place.as_local() { |
| 292 | 291 | let span = self.body.local_decls[local].source_info.span; |
| 293 | 292 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { |
compiler/rustc_borrowck/src/diagnostics/move_errors.rs+3-6| ... | ... | @@ -596,10 +596,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 596 | 596 | self.suggest_cloning(err, place_ty, expr, None); |
| 597 | 597 | } |
| 598 | 598 | |
| 599 | let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); | |
| 600 | 599 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { |
| 601 | 600 | is_partial_move: false, |
| 602 | ty, | |
| 601 | ty: place_ty, | |
| 603 | 602 | place: &place_desc, |
| 604 | 603 | span, |
| 605 | 604 | }); |
| ... | ... | @@ -629,10 +628,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 629 | 628 | self.suggest_cloning(err, place_ty, expr, Some(use_spans)); |
| 630 | 629 | } |
| 631 | 630 | |
| 632 | let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); | |
| 633 | 631 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { |
| 634 | 632 | is_partial_move: false, |
| 635 | ty, | |
| 633 | ty: place_ty, | |
| 636 | 634 | place: &place_desc, |
| 637 | 635 | span: use_span, |
| 638 | 636 | }); |
| ... | ... | @@ -833,10 +831,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { |
| 833 | 831 | self.suggest_cloning(err, bind_to.ty, expr, None); |
| 834 | 832 | } |
| 835 | 833 | |
| 836 | let ty = self.infcx.tcx.short_string(bind_to.ty, err.long_ty_path()); | |
| 837 | 834 | err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { |
| 838 | 835 | is_partial_move: false, |
| 839 | ty, | |
| 836 | ty: bind_to.ty, | |
| 840 | 837 | place: place_desc, |
| 841 | 838 | span: binding_span, |
| 842 | 839 | }); |
compiler/rustc_borrowck/src/diagnostics/region_name.rs+2-2| ... | ... | @@ -194,8 +194,8 @@ impl Display for RegionName { |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | impl rustc_errors::IntoDiagArg for RegionName { |
| 197 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 198 | self.to_string().into_diag_arg() | |
| 197 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 198 | self.to_string().into_diag_arg(path) | |
| 199 | 199 | } |
| 200 | 200 | } |
| 201 | 201 |
compiler/rustc_borrowck/src/session_diagnostics.rs+3-3| ... | ... | @@ -459,17 +459,17 @@ pub(crate) enum OnClosureNote<'a> { |
| 459 | 459 | } |
| 460 | 460 | |
| 461 | 461 | #[derive(Subdiagnostic)] |
| 462 | pub(crate) enum TypeNoCopy<'a> { | |
| 462 | pub(crate) enum TypeNoCopy<'a, 'tcx> { | |
| 463 | 463 | #[label(borrowck_ty_no_impl_copy)] |
| 464 | 464 | Label { |
| 465 | 465 | is_partial_move: bool, |
| 466 | ty: String, | |
| 466 | ty: Ty<'tcx>, | |
| 467 | 467 | place: &'a str, |
| 468 | 468 | #[primary_span] |
| 469 | 469 | span: Span, |
| 470 | 470 | }, |
| 471 | 471 | #[note(borrowck_ty_no_impl_copy)] |
| 472 | Note { is_partial_move: bool, ty: String, place: &'a str }, | |
| 472 | Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, | |
| 473 | 473 | } |
| 474 | 474 | |
| 475 | 475 | #[derive(Diagnostic)] |
compiler/rustc_codegen_ssa/src/assert_module_sources.rs+1-1| ... | ... | @@ -211,7 +211,7 @@ impl fmt::Display for CguReuse { |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | impl IntoDiagArg for CguReuse { |
| 214 | fn into_diag_arg(self) -> DiagArgValue { | |
| 214 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 215 | 215 | DiagArgValue::Str(Cow::Owned(self.to_string())) |
| 216 | 216 | } |
| 217 | 217 | } |
compiler/rustc_codegen_ssa/src/errors.rs+2-2| ... | ... | @@ -161,7 +161,7 @@ impl<'a> CopyPath<'a> { |
| 161 | 161 | struct DebugArgPath<'a>(pub &'a Path); |
| 162 | 162 | |
| 163 | 163 | impl IntoDiagArg for DebugArgPath<'_> { |
| 164 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 164 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 165 | 165 | DiagArgValue::Str(Cow::Owned(format!("{:?}", self.0))) |
| 166 | 166 | } |
| 167 | 167 | } |
| ... | ... | @@ -1087,7 +1087,7 @@ pub enum ExpectedPointerMutability { |
| 1087 | 1087 | } |
| 1088 | 1088 | |
| 1089 | 1089 | impl IntoDiagArg for ExpectedPointerMutability { |
| 1090 | fn into_diag_arg(self) -> DiagArgValue { | |
| 1090 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 1091 | 1091 | match self { |
| 1092 | 1092 | ExpectedPointerMutability::Mut => DiagArgValue::Str(Cow::Borrowed("*mut")), |
| 1093 | 1093 | ExpectedPointerMutability::Not => DiagArgValue::Str(Cow::Borrowed("*_")), |
compiler/rustc_const_eval/src/const_eval/error.rs+4-4| ... | ... | @@ -49,10 +49,10 @@ impl MachineStopType for ConstEvalErrKind { |
| 49 | 49 | | WriteThroughImmutablePointer => {} |
| 50 | 50 | AssertFailure(kind) => kind.add_args(adder), |
| 51 | 51 | Panic { msg, line, col, file } => { |
| 52 | adder("msg".into(), msg.into_diag_arg()); | |
| 53 | adder("file".into(), file.into_diag_arg()); | |
| 54 | adder("line".into(), line.into_diag_arg()); | |
| 55 | adder("col".into(), col.into_diag_arg()); | |
| 52 | adder("msg".into(), msg.into_diag_arg(&mut None)); | |
| 53 | adder("file".into(), file.into_diag_arg(&mut None)); | |
| 54 | adder("line".into(), line.into_diag_arg(&mut None)); | |
| 55 | adder("col".into(), col.into_diag_arg(&mut None)); | |
| 56 | 56 | } |
| 57 | 57 | } |
| 58 | 58 | } |
compiler/rustc_const_eval/src/errors.rs+1-1| ... | ... | @@ -967,7 +967,7 @@ impl ReportErrorExt for ResourceExhaustionInfo { |
| 967 | 967 | } |
| 968 | 968 | |
| 969 | 969 | impl rustc_errors::IntoDiagArg for InternKind { |
| 970 | fn into_diag_arg(self) -> DiagArgValue { | |
| 970 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 971 | 971 | DiagArgValue::Str(Cow::Borrowed(match self { |
| 972 | 972 | InternKind::Static(Mutability::Not) => "static", |
| 973 | 973 | InternKind::Static(Mutability::Mut) => "static_mut", |
compiler/rustc_errors/src/diagnostic.rs+9-3| ... | ... | @@ -148,11 +148,17 @@ where |
| 148 | 148 | /// converted rather than on `DiagArgValue`, which enables types from other `rustc_*` crates to |
| 149 | 149 | /// implement this. |
| 150 | 150 | pub trait IntoDiagArg { |
| 151 | fn into_diag_arg(self) -> DiagArgValue; | |
| 151 | /// Convert `Self` into a `DiagArgValue` suitable for rendering in a diagnostic. | |
| 152 | /// | |
| 153 | /// It takes a `path` where "long values" could be written to, if the `DiagArgValue` is too big | |
| 154 | /// for displaying on the terminal. This path comes from the `Diag` itself. When rendering | |
| 155 | /// values that come from `TyCtxt`, like `Ty<'_>`, they can use `TyCtxt::short_string`. If a | |
| 156 | /// value has no shortening logic that could be used, the argument can be safely ignored. | |
| 157 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue; | |
| 152 | 158 | } |
| 153 | 159 | |
| 154 | 160 | impl IntoDiagArg for DiagArgValue { |
| 155 | fn into_diag_arg(self) -> DiagArgValue { | |
| 161 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 156 | 162 | self |
| 157 | 163 | } |
| 158 | 164 | } |
| ... | ... | @@ -395,7 +401,7 @@ impl DiagInner { |
| 395 | 401 | } |
| 396 | 402 | |
| 397 | 403 | pub(crate) fn arg(&mut self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) { |
| 398 | self.args.insert(name.into(), arg.into_diag_arg()); | |
| 404 | self.args.insert(name.into(), arg.into_diag_arg(&mut self.long_ty_path)); | |
| 399 | 405 | } |
| 400 | 406 | |
| 401 | 407 | /// Fields used for Hash, and PartialEq trait. |
compiler/rustc_errors/src/diagnostic_impls.rs+49-49| ... | ... | @@ -25,8 +25,8 @@ use crate::{ |
| 25 | 25 | pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display); |
| 26 | 26 | |
| 27 | 27 | impl IntoDiagArg for DiagArgFromDisplay<'_> { |
| 28 | fn into_diag_arg(self) -> DiagArgValue { | |
| 29 | self.0.to_string().into_diag_arg() | |
| 28 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 29 | self.0.to_string().into_diag_arg(path) | |
| 30 | 30 | } |
| 31 | 31 | } |
| 32 | 32 | |
| ... | ... | @@ -43,8 +43,8 @@ impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> { |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T { |
| 46 | fn into_diag_arg(self) -> DiagArgValue { | |
| 47 | self.clone().into_diag_arg() | |
| 46 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 47 | self.clone().into_diag_arg(path) | |
| 48 | 48 | } |
| 49 | 49 | } |
| 50 | 50 | |
| ... | ... | @@ -53,8 +53,8 @@ macro_rules! into_diag_arg_using_display { |
| 53 | 53 | ($( $ty:ty ),+ $(,)?) => { |
| 54 | 54 | $( |
| 55 | 55 | impl IntoDiagArg for $ty { |
| 56 | fn into_diag_arg(self) -> DiagArgValue { | |
| 57 | self.to_string().into_diag_arg() | |
| 56 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 57 | self.to_string().into_diag_arg(path) | |
| 58 | 58 | } |
| 59 | 59 | } |
| 60 | 60 | )+ |
| ... | ... | @@ -65,13 +65,13 @@ macro_rules! into_diag_arg_for_number { |
| 65 | 65 | ($( $ty:ty ),+ $(,)?) => { |
| 66 | 66 | $( |
| 67 | 67 | impl IntoDiagArg for $ty { |
| 68 | fn into_diag_arg(self) -> DiagArgValue { | |
| 68 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 69 | 69 | // Convert to a string if it won't fit into `Number`. |
| 70 | 70 | #[allow(irrefutable_let_patterns)] |
| 71 | 71 | if let Ok(n) = TryInto::<i32>::try_into(self) { |
| 72 | 72 | DiagArgValue::Number(n) |
| 73 | 73 | } else { |
| 74 | self.to_string().into_diag_arg() | |
| 74 | self.to_string().into_diag_arg(path) | |
| 75 | 75 | } |
| 76 | 76 | } |
| 77 | 77 | } |
| ... | ... | @@ -98,32 +98,32 @@ into_diag_arg_using_display!( |
| 98 | 98 | ); |
| 99 | 99 | |
| 100 | 100 | impl IntoDiagArg for RustcVersion { |
| 101 | fn into_diag_arg(self) -> DiagArgValue { | |
| 101 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 102 | 102 | DiagArgValue::Str(Cow::Owned(self.to_string())) |
| 103 | 103 | } |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | 106 | impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> { |
| 107 | fn into_diag_arg(self) -> DiagArgValue { | |
| 108 | self.to_string().into_diag_arg() | |
| 107 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 108 | self.to_string().into_diag_arg(path) | |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTraitRef<I> { |
| 113 | fn into_diag_arg(self) -> DiagArgValue { | |
| 114 | self.to_string().into_diag_arg() | |
| 113 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 114 | self.to_string().into_diag_arg(path) | |
| 115 | 115 | } |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst<I> { |
| 119 | fn into_diag_arg(self) -> DiagArgValue { | |
| 120 | format!("{self:?}").into_diag_arg() | |
| 119 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 120 | format!("{self:?}").into_diag_arg(path) | |
| 121 | 121 | } |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::FnSig<I> { |
| 125 | fn into_diag_arg(self) -> DiagArgValue { | |
| 126 | format!("{self:?}").into_diag_arg() | |
| 125 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 126 | format!("{self:?}").into_diag_arg(path) | |
| 127 | 127 | } |
| 128 | 128 | } |
| 129 | 129 | |
| ... | ... | @@ -131,15 +131,15 @@ impl<I: rustc_type_ir::Interner, T> IntoDiagArg for rustc_type_ir::Binder<I, T> |
| 131 | 131 | where |
| 132 | 132 | T: IntoDiagArg, |
| 133 | 133 | { |
| 134 | fn into_diag_arg(self) -> DiagArgValue { | |
| 135 | self.skip_binder().into_diag_arg() | |
| 134 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 135 | self.skip_binder().into_diag_arg(path) | |
| 136 | 136 | } |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); |
| 140 | 140 | |
| 141 | 141 | impl IntoDiagArg for bool { |
| 142 | fn into_diag_arg(self) -> DiagArgValue { | |
| 142 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 143 | 143 | if self { |
| 144 | 144 | DiagArgValue::Str(Cow::Borrowed("true")) |
| 145 | 145 | } else { |
| ... | ... | @@ -149,13 +149,13 @@ impl IntoDiagArg for bool { |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | 151 | impl IntoDiagArg for char { |
| 152 | fn into_diag_arg(self) -> DiagArgValue { | |
| 152 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 153 | 153 | DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) |
| 154 | 154 | } |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | impl IntoDiagArg for Vec<char> { |
| 158 | fn into_diag_arg(self) -> DiagArgValue { | |
| 158 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 159 | 159 | DiagArgValue::StrListSepByAnd( |
| 160 | 160 | self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(), |
| 161 | 161 | ) |
| ... | ... | @@ -163,49 +163,49 @@ impl IntoDiagArg for Vec<char> { |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | impl IntoDiagArg for Symbol { |
| 166 | fn into_diag_arg(self) -> DiagArgValue { | |
| 167 | self.to_ident_string().into_diag_arg() | |
| 166 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 167 | self.to_ident_string().into_diag_arg(path) | |
| 168 | 168 | } |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | impl<'a> IntoDiagArg for &'a str { |
| 172 | fn into_diag_arg(self) -> DiagArgValue { | |
| 173 | self.to_string().into_diag_arg() | |
| 172 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 173 | self.to_string().into_diag_arg(path) | |
| 174 | 174 | } |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | 177 | impl IntoDiagArg for String { |
| 178 | fn into_diag_arg(self) -> DiagArgValue { | |
| 178 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 179 | 179 | DiagArgValue::Str(Cow::Owned(self)) |
| 180 | 180 | } |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | impl<'a> IntoDiagArg for Cow<'a, str> { |
| 184 | fn into_diag_arg(self) -> DiagArgValue { | |
| 184 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 185 | 185 | DiagArgValue::Str(Cow::Owned(self.into_owned())) |
| 186 | 186 | } |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | impl<'a> IntoDiagArg for &'a Path { |
| 190 | fn into_diag_arg(self) -> DiagArgValue { | |
| 190 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 191 | 191 | DiagArgValue::Str(Cow::Owned(self.display().to_string())) |
| 192 | 192 | } |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | 195 | impl IntoDiagArg for PathBuf { |
| 196 | fn into_diag_arg(self) -> DiagArgValue { | |
| 196 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 197 | 197 | DiagArgValue::Str(Cow::Owned(self.display().to_string())) |
| 198 | 198 | } |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | 201 | impl IntoDiagArg for PanicStrategy { |
| 202 | fn into_diag_arg(self) -> DiagArgValue { | |
| 202 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 203 | 203 | DiagArgValue::Str(Cow::Owned(self.desc().to_string())) |
| 204 | 204 | } |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | 207 | impl IntoDiagArg for hir::ConstContext { |
| 208 | fn into_diag_arg(self) -> DiagArgValue { | |
| 208 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 209 | 209 | DiagArgValue::Str(Cow::Borrowed(match self { |
| 210 | 210 | hir::ConstContext::ConstFn => "const_fn", |
| 211 | 211 | hir::ConstContext::Static(_) => "static", |
| ... | ... | @@ -215,49 +215,49 @@ impl IntoDiagArg for hir::ConstContext { |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | 217 | impl IntoDiagArg for ast::Expr { |
| 218 | fn into_diag_arg(self) -> DiagArgValue { | |
| 218 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 219 | 219 | DiagArgValue::Str(Cow::Owned(pprust::expr_to_string(&self))) |
| 220 | 220 | } |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | impl IntoDiagArg for ast::Path { |
| 224 | fn into_diag_arg(self) -> DiagArgValue { | |
| 224 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 225 | 225 | DiagArgValue::Str(Cow::Owned(pprust::path_to_string(&self))) |
| 226 | 226 | } |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | impl IntoDiagArg for ast::token::Token { |
| 230 | fn into_diag_arg(self) -> DiagArgValue { | |
| 230 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 231 | 231 | DiagArgValue::Str(pprust::token_to_string(&self)) |
| 232 | 232 | } |
| 233 | 233 | } |
| 234 | 234 | |
| 235 | 235 | impl IntoDiagArg for ast::token::TokenKind { |
| 236 | fn into_diag_arg(self) -> DiagArgValue { | |
| 236 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 237 | 237 | DiagArgValue::Str(pprust::token_kind_to_string(&self)) |
| 238 | 238 | } |
| 239 | 239 | } |
| 240 | 240 | |
| 241 | 241 | impl IntoDiagArg for FloatTy { |
| 242 | fn into_diag_arg(self) -> DiagArgValue { | |
| 242 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 243 | 243 | DiagArgValue::Str(Cow::Borrowed(self.name_str())) |
| 244 | 244 | } |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | impl IntoDiagArg for std::ffi::CString { |
| 248 | fn into_diag_arg(self) -> DiagArgValue { | |
| 248 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 249 | 249 | DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) |
| 250 | 250 | } |
| 251 | 251 | } |
| 252 | 252 | |
| 253 | 253 | impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr { |
| 254 | fn into_diag_arg(self) -> DiagArgValue { | |
| 254 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 255 | 255 | DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) |
| 256 | 256 | } |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | impl IntoDiagArg for ast::Visibility { |
| 260 | fn into_diag_arg(self) -> DiagArgValue { | |
| 260 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 261 | 261 | let s = pprust::vis_to_string(&self); |
| 262 | 262 | let s = s.trim_end().to_string(); |
| 263 | 263 | DiagArgValue::Str(Cow::Owned(s)) |
| ... | ... | @@ -265,49 +265,49 @@ impl IntoDiagArg for ast::Visibility { |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | 267 | impl IntoDiagArg for rustc_lint_defs::Level { |
| 268 | fn into_diag_arg(self) -> DiagArgValue { | |
| 268 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 269 | 269 | DiagArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) |
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | 273 | impl<Id> IntoDiagArg for hir::def::Res<Id> { |
| 274 | fn into_diag_arg(self) -> DiagArgValue { | |
| 274 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 275 | 275 | DiagArgValue::Str(Cow::Borrowed(self.descr())) |
| 276 | 276 | } |
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 | impl IntoDiagArg for DiagLocation { |
| 280 | fn into_diag_arg(self) -> DiagArgValue { | |
| 280 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 281 | 281 | DiagArgValue::Str(Cow::from(self.to_string())) |
| 282 | 282 | } |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | impl IntoDiagArg for Backtrace { |
| 286 | fn into_diag_arg(self) -> DiagArgValue { | |
| 286 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 287 | 287 | DiagArgValue::Str(Cow::from(self.to_string())) |
| 288 | 288 | } |
| 289 | 289 | } |
| 290 | 290 | |
| 291 | 291 | impl IntoDiagArg for Level { |
| 292 | fn into_diag_arg(self) -> DiagArgValue { | |
| 292 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 293 | 293 | DiagArgValue::Str(Cow::from(self.to_string())) |
| 294 | 294 | } |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | 297 | impl IntoDiagArg for ClosureKind { |
| 298 | fn into_diag_arg(self) -> DiagArgValue { | |
| 298 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 299 | 299 | DiagArgValue::Str(self.as_str().into()) |
| 300 | 300 | } |
| 301 | 301 | } |
| 302 | 302 | |
| 303 | 303 | impl IntoDiagArg for hir::def::Namespace { |
| 304 | fn into_diag_arg(self) -> DiagArgValue { | |
| 304 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 305 | 305 | DiagArgValue::Str(Cow::Borrowed(self.descr())) |
| 306 | 306 | } |
| 307 | 307 | } |
| 308 | 308 | |
| 309 | 309 | impl IntoDiagArg for ExprPrecedence { |
| 310 | fn into_diag_arg(self) -> DiagArgValue { | |
| 310 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 311 | 311 | DiagArgValue::Number(self as i32) |
| 312 | 312 | } |
| 313 | 313 | } |
| ... | ... | @@ -328,7 +328,7 @@ impl<S> FromIterator<S> for DiagSymbolList<S> { |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | 330 | impl<S: std::fmt::Display> IntoDiagArg for DiagSymbolList<S> { |
| 331 | fn into_diag_arg(self) -> DiagArgValue { | |
| 331 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 332 | 332 | DiagArgValue::StrListSepByAnd( |
| 333 | 333 | self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), |
| 334 | 334 | ) |
compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs+5-1| ... | ... | @@ -789,7 +789,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 789 | 789 | |
| 790 | 790 | Some(args.constraints.iter().filter_map(|constraint| { |
| 791 | 791 | let ident = constraint.ident; |
| 792 | let trait_def = path.res.def_id(); | |
| 792 | ||
| 793 | let Res::Def(DefKind::Trait, trait_def) = path.res else { | |
| 794 | return None; | |
| 795 | }; | |
| 796 | ||
| 793 | 797 | let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind( |
| 794 | 798 | tcx, |
| 795 | 799 | ident, |
compiler/rustc_hir_typeck/messages.ftl+20-1| ... | ... | @@ -10,6 +10,7 @@ hir_typeck_address_of_temporary_taken = cannot take address of a temporary |
| 10 | 10 | hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where |
| 11 | 11 | .note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new |
| 12 | 12 | |
| 13 | hir_typeck_as_deref_suggestion = consider using `as_deref` here | |
| 13 | 14 | hir_typeck_base_expression_double_dot = base expression required after `..` |
| 14 | 15 | hir_typeck_base_expression_double_dot_add_expr = add a base expression here |
| 15 | 16 | hir_typeck_base_expression_double_dot_enable_default_field_values = |
| ... | ... | @@ -27,6 +28,9 @@ hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool` |
| 27 | 28 | .help = compare with zero instead |
| 28 | 29 | .label = unsupported cast |
| 29 | 30 | |
| 31 | hir_typeck_cant_dereference = type `{$ty}` cannot be dereferenced | |
| 32 | hir_typeck_cant_dereference_label = can't be dereferenced | |
| 33 | ||
| 30 | 34 | hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop` |
| 31 | 35 | |
| 32 | 36 | hir_typeck_cast_thin_pointer_to_wide_pointer = cannot cast thin pointer `{$expr_ty}` to wide pointer `{$cast_ty}` |
| ... | ... | @@ -72,6 +76,9 @@ hir_typeck_dependency_on_unit_never_type_fallback = this function depends on nev |
| 72 | 76 | |
| 73 | 77 | hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` |
| 74 | 78 | |
| 79 | hir_typeck_expected_array_or_slice = expected an array or slice, found `{$ty}` | |
| 80 | hir_typeck_expected_array_or_slice_label = pattern cannot match with input type `{$ty}` | |
| 81 | ||
| 75 | 82 | hir_typeck_expected_default_return_type = expected `()` because of default return type |
| 76 | 83 | |
| 77 | 84 | hir_typeck_expected_return_type = expected `{$expected}` because of return type |
| ... | ... | @@ -112,7 +119,11 @@ hir_typeck_int_to_fat = cannot cast `{$expr_ty}` to a pointer that {$known_wide |
| 112 | 119 | hir_typeck_int_to_fat_label = creating a `{$cast_ty}` requires both an address and {$metadata} |
| 113 | 120 | hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` |
| 114 | 121 | |
| 115 | hir_typeck_invalid_callee = expected function, found {$ty} | |
| 122 | hir_typeck_invalid_callee = expected function, found {$found} | |
| 123 | hir_typeck_invalid_defined = `{$path}` defined here | |
| 124 | hir_typeck_invalid_defined_kind = {$kind} `{$path}` defined here | |
| 125 | hir_typeck_invalid_fn_defined = `{$func}` defined here returns `{$ty}` | |
| 126 | hir_typeck_invalid_local = `{$local_name}` has type `{$ty}` | |
| 116 | 127 | |
| 117 | 128 | hir_typeck_lossy_provenance_int2ptr = |
| 118 | 129 | strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}` |
| ... | ... | @@ -142,6 +153,12 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for { |
| 142 | 153 | *[other] {" "}in the current scope |
| 143 | 154 | } |
| 144 | 155 | |
| 156 | hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}` | |
| 157 | ||
| 158 | hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}` | |
| 159 | hir_typeck_no_field_on_variant_enum = this enum variant... | |
| 160 | hir_typeck_no_field_on_variant_field = ...does not have this field | |
| 161 | ||
| 145 | 162 | hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}` |
| 146 | 163 | |
| 147 | 164 | hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide |
| ... | ... | @@ -183,6 +200,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o |
| 183 | 200 | .label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference |
| 184 | 201 | .suggestion = replace `Self` with the actual type |
| 185 | 202 | |
| 203 | hir_typeck_slicing_suggestion = consider slicing here | |
| 204 | ||
| 186 | 205 | hir_typeck_struct_expr_non_exhaustive = |
| 187 | 206 | cannot create non-exhaustive {$what} using struct expression |
| 188 | 207 |
compiler/rustc_hir_typeck/src/callee.rs+27-18| ... | ... | @@ -23,7 +23,7 @@ use tracing::{debug, instrument}; |
| 23 | 23 | use super::method::MethodCallee; |
| 24 | 24 | use super::method::probe::ProbeScope; |
| 25 | 25 | use super::{Expectation, FnCtxt, TupleArgumentsFlag}; |
| 26 | use crate::errors; | |
| 26 | use crate::{errors, fluent_generated}; | |
| 27 | 27 | |
| 28 | 28 | /// Checks that it is legal to call methods of the trait corresponding |
| 29 | 29 | /// to `trait_id` (this only cares about the trait, not the specific |
| ... | ... | @@ -674,13 +674,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 674 | 674 | } |
| 675 | 675 | |
| 676 | 676 | let callee_ty = self.resolve_vars_if_possible(callee_ty); |
| 677 | let mut path = None; | |
| 677 | 678 | let mut err = self.dcx().create_err(errors::InvalidCallee { |
| 678 | 679 | span: callee_expr.span, |
| 679 | ty: match &unit_variant { | |
| 680 | ty: callee_ty, | |
| 681 | found: match &unit_variant { | |
| 680 | 682 | Some((_, kind, path)) => format!("{kind} `{path}`"), |
| 681 | None => format!("`{callee_ty}`"), | |
| 683 | None => format!("`{}`", self.tcx.short_string(callee_ty, &mut path)), | |
| 682 | 684 | }, |
| 683 | 685 | }); |
| 686 | *err.long_ty_path() = path; | |
| 684 | 687 | if callee_ty.references_error() { |
| 685 | 688 | err.downgrade_to_delayed_bug(); |
| 686 | 689 | } |
| ... | ... | @@ -780,27 +783,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 780 | 783 | if let Some(span) = self.tcx.hir().res_span(def) { |
| 781 | 784 | let callee_ty = callee_ty.to_string(); |
| 782 | 785 | let label = match (unit_variant, inner_callee_path) { |
| 783 | (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")), | |
| 784 | (_, Some(hir::QPath::Resolved(_, path))) => self | |
| 785 | .tcx | |
| 786 | .sess | |
| 787 | .source_map() | |
| 788 | .span_to_snippet(path.span) | |
| 789 | .ok() | |
| 790 | .map(|p| format!("`{p}` defined here returns `{callee_ty}`")), | |
| 786 | (Some((_, kind, path)), _) => { | |
| 787 | err.arg("kind", kind); | |
| 788 | err.arg("path", path); | |
| 789 | Some(fluent_generated::hir_typeck_invalid_defined_kind) | |
| 790 | } | |
| 791 | (_, Some(hir::QPath::Resolved(_, path))) => { | |
| 792 | self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| { | |
| 793 | err.arg("func", p); | |
| 794 | fluent_generated::hir_typeck_invalid_fn_defined | |
| 795 | }) | |
| 796 | } | |
| 791 | 797 | _ => { |
| 792 | 798 | match def { |
| 793 | 799 | // Emit a different diagnostic for local variables, as they are not |
| 794 | 800 | // type definitions themselves, but rather variables *of* that type. |
| 795 | Res::Local(hir_id) => Some(format!( | |
| 796 | "`{}` has type `{}`", | |
| 797 | self.tcx.hir().name(hir_id), | |
| 798 | callee_ty | |
| 799 | )), | |
| 801 | Res::Local(hir_id) => { | |
| 802 | err.arg("local_name", self.tcx.hir().name(hir_id)); | |
| 803 | Some(fluent_generated::hir_typeck_invalid_local) | |
| 804 | } | |
| 800 | 805 | Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { |
| 801 | Some(format!("`{}` defined here", self.tcx.def_path_str(def_id),)) | |
| 806 | err.arg("path", self.tcx.def_path_str(def_id)); | |
| 807 | Some(fluent_generated::hir_typeck_invalid_defined) | |
| 808 | } | |
| 809 | _ => { | |
| 810 | err.arg("path", callee_ty); | |
| 811 | Some(fluent_generated::hir_typeck_invalid_defined) | |
| 802 | 812 | } |
| 803 | _ => Some(format!("`{callee_ty}` defined here")), | |
| 804 | 813 | } |
| 805 | 814 | } |
| 806 | 815 | }; |
compiler/rustc_hir_typeck/src/cast.rs+7-8| ... | ... | @@ -548,17 +548,19 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 548 | 548 | err.emit(); |
| 549 | 549 | } |
| 550 | 550 | CastError::SizedUnsizedCast => { |
| 551 | let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); | |
| 552 | let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); | |
| 551 | 553 | fcx.dcx().emit_err(errors::CastThinPointerToWidePointer { |
| 552 | 554 | span: self.span, |
| 553 | expr_ty: self.expr_ty, | |
| 554 | cast_ty: fcx.ty_to_string(self.cast_ty), | |
| 555 | expr_ty, | |
| 556 | cast_ty, | |
| 555 | 557 | teach: fcx.tcx.sess.teach(E0607), |
| 556 | 558 | }); |
| 557 | 559 | } |
| 558 | 560 | CastError::IntToWideCast(known_metadata) => { |
| 559 | 561 | let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span); |
| 560 | 562 | let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); |
| 561 | let expr_ty = fcx.ty_to_string(self.expr_ty); | |
| 563 | let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); | |
| 562 | 564 | let metadata = known_metadata.unwrap_or("type-specific metadata"); |
| 563 | 565 | let known_wide = known_metadata.is_some(); |
| 564 | 566 | let span = self.cast_span; |
| ... | ... | @@ -1164,10 +1166,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 1164 | 1166 | if let Some((deref_ty, _)) = derefed { |
| 1165 | 1167 | // Give a note about what the expr derefs to. |
| 1166 | 1168 | if deref_ty != self.expr_ty.peel_refs() { |
| 1167 | err.subdiagnostic(errors::DerefImplsIsEmpty { | |
| 1168 | span: self.expr_span, | |
| 1169 | deref_ty: fcx.ty_to_string(deref_ty), | |
| 1170 | }); | |
| 1169 | err.subdiagnostic(errors::DerefImplsIsEmpty { span: self.expr_span, deref_ty }); | |
| 1171 | 1170 | } |
| 1172 | 1171 | |
| 1173 | 1172 | // Create a multipart suggestion: add `!` and `.is_empty()` in |
| ... | ... | @@ -1175,7 +1174,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { |
| 1175 | 1174 | err.subdiagnostic(errors::UseIsEmpty { |
| 1176 | 1175 | lo: self.expr_span.shrink_to_lo(), |
| 1177 | 1176 | hi: self.span.with_lo(self.expr_span.hi()), |
| 1178 | expr_ty: fcx.ty_to_string(self.expr_ty), | |
| 1177 | expr_ty: self.expr_ty, | |
| 1179 | 1178 | }); |
| 1180 | 1179 | } |
| 1181 | 1180 | } |
compiler/rustc_hir_typeck/src/errors.rs+80-9| ... | ... | @@ -91,7 +91,7 @@ pub(crate) enum ReturnLikeStatementKind { |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | impl IntoDiagArg for ReturnLikeStatementKind { |
| 94 | fn into_diag_arg(self) -> DiagArgValue { | |
| 94 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 95 | 95 | let kind = match self { |
| 96 | 96 | Self::Return => "return", |
| 97 | 97 | Self::Become => "become", |
| ... | ... | @@ -454,12 +454,83 @@ impl HelpUseLatestEdition { |
| 454 | 454 | } |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | #[derive(Diagnostic)] | |
| 458 | #[diag(hir_typeck_no_field_on_type, code = E0609)] | |
| 459 | pub(crate) struct NoFieldOnType<'tcx> { | |
| 460 | #[primary_span] | |
| 461 | pub(crate) span: Span, | |
| 462 | pub(crate) ty: Ty<'tcx>, | |
| 463 | pub(crate) field: Ident, | |
| 464 | } | |
| 465 | ||
| 466 | #[derive(Diagnostic)] | |
| 467 | #[diag(hir_typeck_no_field_on_variant, code = E0609)] | |
| 468 | pub(crate) struct NoFieldOnVariant<'tcx> { | |
| 469 | #[primary_span] | |
| 470 | pub(crate) span: Span, | |
| 471 | pub(crate) container: Ty<'tcx>, | |
| 472 | pub(crate) ident: Ident, | |
| 473 | pub(crate) field: Ident, | |
| 474 | #[label(hir_typeck_no_field_on_variant_enum)] | |
| 475 | pub(crate) enum_span: Span, | |
| 476 | #[label(hir_typeck_no_field_on_variant_field)] | |
| 477 | pub(crate) field_span: Span, | |
| 478 | } | |
| 479 | ||
| 480 | #[derive(Diagnostic)] | |
| 481 | #[diag(hir_typeck_cant_dereference, code = E0614)] | |
| 482 | pub(crate) struct CantDereference<'tcx> { | |
| 483 | #[primary_span] | |
| 484 | #[label(hir_typeck_cant_dereference_label)] | |
| 485 | pub(crate) span: Span, | |
| 486 | pub(crate) ty: Ty<'tcx>, | |
| 487 | } | |
| 488 | ||
| 489 | #[derive(Diagnostic)] | |
| 490 | #[diag(hir_typeck_expected_array_or_slice, code = E0529)] | |
| 491 | pub(crate) struct ExpectedArrayOrSlice<'tcx> { | |
| 492 | #[primary_span] | |
| 493 | #[label(hir_typeck_expected_array_or_slice_label)] | |
| 494 | pub(crate) span: Span, | |
| 495 | pub(crate) ty: Ty<'tcx>, | |
| 496 | pub(crate) slice_pat_semantics: bool, | |
| 497 | #[subdiagnostic] | |
| 498 | pub(crate) as_deref: Option<AsDerefSuggestion>, | |
| 499 | #[subdiagnostic] | |
| 500 | pub(crate) slicing: Option<SlicingSuggestion>, | |
| 501 | } | |
| 502 | ||
| 503 | #[derive(Subdiagnostic)] | |
| 504 | #[suggestion( | |
| 505 | hir_typeck_as_deref_suggestion, | |
| 506 | code = ".as_deref()", | |
| 507 | style = "verbose", | |
| 508 | applicability = "maybe-incorrect" | |
| 509 | )] | |
| 510 | pub(crate) struct AsDerefSuggestion { | |
| 511 | #[primary_span] | |
| 512 | pub(crate) span: Span, | |
| 513 | } | |
| 514 | ||
| 515 | #[derive(Subdiagnostic)] | |
| 516 | #[suggestion( | |
| 517 | hir_typeck_slicing_suggestion, | |
| 518 | code = "[..]", | |
| 519 | style = "verbose", | |
| 520 | applicability = "maybe-incorrect" | |
| 521 | )] | |
| 522 | pub(crate) struct SlicingSuggestion { | |
| 523 | #[primary_span] | |
| 524 | pub(crate) span: Span, | |
| 525 | } | |
| 526 | ||
| 457 | 527 | #[derive(Diagnostic)] |
| 458 | 528 | #[diag(hir_typeck_invalid_callee, code = E0618)] |
| 459 | pub(crate) struct InvalidCallee { | |
| 529 | pub(crate) struct InvalidCallee<'tcx> { | |
| 460 | 530 | #[primary_span] |
| 461 | 531 | pub span: Span, |
| 462 | pub ty: String, | |
| 532 | pub ty: Ty<'tcx>, | |
| 533 | pub found: String, | |
| 463 | 534 | } |
| 464 | 535 | |
| 465 | 536 | #[derive(Diagnostic)] |
| ... | ... | @@ -469,7 +540,7 @@ pub(crate) struct IntToWide<'tcx> { |
| 469 | 540 | #[label(hir_typeck_int_to_fat_label)] |
| 470 | 541 | pub span: Span, |
| 471 | 542 | pub metadata: &'tcx str, |
| 472 | pub expr_ty: String, | |
| 543 | pub expr_ty: Ty<'tcx>, | |
| 473 | 544 | pub cast_ty: Ty<'tcx>, |
| 474 | 545 | #[label(hir_typeck_int_to_fat_label_nightly)] |
| 475 | 546 | pub expr_if_nightly: Option<Span>, |
| ... | ... | @@ -581,12 +652,12 @@ pub(crate) struct UnionPatDotDot { |
| 581 | 652 | applicability = "maybe-incorrect", |
| 582 | 653 | style = "verbose" |
| 583 | 654 | )] |
| 584 | pub(crate) struct UseIsEmpty { | |
| 655 | pub(crate) struct UseIsEmpty<'tcx> { | |
| 585 | 656 | #[suggestion_part(code = "!")] |
| 586 | 657 | pub lo: Span, |
| 587 | 658 | #[suggestion_part(code = ".is_empty()")] |
| 588 | 659 | pub hi: Span, |
| 589 | pub expr_ty: String, | |
| 660 | pub expr_ty: Ty<'tcx>, | |
| 590 | 661 | } |
| 591 | 662 | |
| 592 | 663 | #[derive(Diagnostic)] |
| ... | ... | @@ -745,10 +816,10 @@ pub(crate) struct CtorIsPrivate { |
| 745 | 816 | |
| 746 | 817 | #[derive(Subdiagnostic)] |
| 747 | 818 | #[note(hir_typeck_deref_is_empty)] |
| 748 | pub(crate) struct DerefImplsIsEmpty { | |
| 819 | pub(crate) struct DerefImplsIsEmpty<'tcx> { | |
| 749 | 820 | #[primary_span] |
| 750 | 821 | pub span: Span, |
| 751 | pub deref_ty: String, | |
| 822 | pub deref_ty: Ty<'tcx>, | |
| 752 | 823 | } |
| 753 | 824 | |
| 754 | 825 | #[derive(Subdiagnostic)] |
| ... | ... | @@ -826,7 +897,7 @@ pub(crate) struct CastThinPointerToWidePointer<'tcx> { |
| 826 | 897 | #[primary_span] |
| 827 | 898 | pub span: Span, |
| 828 | 899 | pub expr_ty: Ty<'tcx>, |
| 829 | pub cast_ty: String, | |
| 900 | pub cast_ty: Ty<'tcx>, | |
| 830 | 901 | #[note(hir_typeck_teach_help)] |
| 831 | 902 | pub(crate) teach: bool, |
| 832 | 903 | } |
compiler/rustc_hir_typeck/src/expr.rs+20-27| ... | ... | @@ -45,9 +45,10 @@ use crate::coercion::{CoerceMany, DynamicCoerceMany}; |
| 45 | 45 | use crate::errors::{ |
| 46 | 46 | AddressOfTemporaryTaken, BaseExpressionDoubleDot, BaseExpressionDoubleDotAddExpr, |
| 47 | 47 | BaseExpressionDoubleDotEnableDefaultFieldValues, BaseExpressionDoubleDotRemove, |
| 48 | FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition, | |
| 49 | ReturnLikeStatementKind, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, | |
| 50 | TypeMismatchFruTypo, YieldExprOutsideOfCoroutine, | |
| 48 | CantDereference, FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, | |
| 49 | HelpUseLatestEdition, NoFieldOnType, NoFieldOnVariant, ReturnLikeStatementKind, | |
| 50 | ReturnStmtOutsideOfFnBody, StructExprNonExhaustive, TypeMismatchFruTypo, | |
| 51 | YieldExprOutsideOfCoroutine, | |
| 51 | 52 | }; |
| 52 | 53 | use crate::{ |
| 53 | 54 | BreakableCtxt, CoroutineTypes, Diverges, FnCtxt, Needs, cast, fatally_break_rust, |
| ... | ... | @@ -607,13 +608,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 607 | 608 | if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) { |
| 608 | 609 | oprnd_t = ty; |
| 609 | 610 | } else { |
| 610 | let mut err = type_error_struct!( | |
| 611 | self.dcx(), | |
| 612 | expr.span, | |
| 613 | oprnd_t, | |
| 614 | E0614, | |
| 615 | "type `{oprnd_t}` cannot be dereferenced", | |
| 616 | ); | |
| 611 | let mut err = | |
| 612 | self.dcx().create_err(CantDereference { span: expr.span, ty: oprnd_t }); | |
| 617 | 613 | let sp = tcx.sess.source_map().start_point(expr.span).with_parent(None); |
| 618 | 614 | if let Some(sp) = |
| 619 | 615 | tcx.sess.psess.ambiguous_block_expr_parse.borrow().get(&sp) |
| ... | ... | @@ -3287,13 +3283,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 3287 | 3283 | let span = field.span; |
| 3288 | 3284 | debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t); |
| 3289 | 3285 | |
| 3290 | let mut err = type_error_struct!( | |
| 3291 | self.dcx(), | |
| 3292 | span, | |
| 3293 | expr_t, | |
| 3294 | E0609, | |
| 3295 | "no field `{field}` on type `{expr_t}`", | |
| 3296 | ); | |
| 3286 | let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field }); | |
| 3287 | if expr_t.references_error() { | |
| 3288 | err.downgrade_to_delayed_bug(); | |
| 3289 | } | |
| 3297 | 3290 | |
| 3298 | 3291 | // try to add a suggestion in case the field is a nested field of a field of the Adt |
| 3299 | 3292 | let mod_id = self.tcx.parent_module(id).to_def_id(); |
| ... | ... | @@ -3867,16 +3860,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 3867 | 3860 | .iter_enumerated() |
| 3868 | 3861 | .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) |
| 3869 | 3862 | else { |
| 3870 | type_error_struct!( | |
| 3871 | self.dcx(), | |
| 3872 | ident.span, | |
| 3873 | container, | |
| 3874 | E0609, | |
| 3875 | "no field named `{subfield}` on enum variant `{container}::{ident}`", | |
| 3876 | ) | |
| 3877 | .with_span_label(field.span, "this enum variant...") | |
| 3878 | .with_span_label(subident.span, "...does not have this field") | |
| 3879 | .emit(); | |
| 3863 | self.dcx() | |
| 3864 | .create_err(NoFieldOnVariant { | |
| 3865 | span: ident.span, | |
| 3866 | container, | |
| 3867 | ident, | |
| 3868 | field: subfield, | |
| 3869 | enum_span: field.span, | |
| 3870 | field_span: subident.span, | |
| 3871 | }) | |
| 3872 | .emit_unless(container.references_error()); | |
| 3880 | 3873 | break; |
| 3881 | 3874 | }; |
| 3882 | 3875 |
compiler/rustc_hir_typeck/src/pat.rs+13-21| ... | ... | @@ -2771,16 +2771,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2771 | 2771 | ) -> ErrorGuaranteed { |
| 2772 | 2772 | let PatInfo { top_info: ti, current_depth, .. } = pat_info; |
| 2773 | 2773 | |
| 2774 | let mut err = struct_span_code_err!( | |
| 2775 | self.dcx(), | |
| 2776 | span, | |
| 2777 | E0529, | |
| 2778 | "expected an array or slice, found `{expected_ty}`" | |
| 2779 | ); | |
| 2774 | let mut slice_pat_semantics = false; | |
| 2775 | let mut as_deref = None; | |
| 2776 | let mut slicing = None; | |
| 2780 | 2777 | if let ty::Ref(_, ty, _) = expected_ty.kind() |
| 2781 | 2778 | && let ty::Array(..) | ty::Slice(..) = ty.kind() |
| 2782 | 2779 | { |
| 2783 | err.help("the semantics of slice patterns changed recently; see issue #62254"); | |
| 2780 | slice_pat_semantics = true; | |
| 2784 | 2781 | } else if self |
| 2785 | 2782 | .autoderef(span, expected_ty) |
| 2786 | 2783 | .silence_errors() |
| ... | ... | @@ -2797,28 +2794,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2797 | 2794 | || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => |
| 2798 | 2795 | { |
| 2799 | 2796 | // Slicing won't work here, but `.as_deref()` might (issue #91328). |
| 2800 | err.span_suggestion_verbose( | |
| 2801 | span.shrink_to_hi(), | |
| 2802 | "consider using `as_deref` here", | |
| 2803 | ".as_deref()", | |
| 2804 | Applicability::MaybeIncorrect, | |
| 2805 | ); | |
| 2797 | as_deref = Some(errors::AsDerefSuggestion { span: span.shrink_to_hi() }); | |
| 2806 | 2798 | } |
| 2807 | 2799 | _ => (), |
| 2808 | 2800 | } |
| 2809 | 2801 | |
| 2810 | 2802 | let is_top_level = current_depth <= 1; |
| 2811 | 2803 | if is_slice_or_array_or_vector && is_top_level { |
| 2812 | err.span_suggestion_verbose( | |
| 2813 | span.shrink_to_hi(), | |
| 2814 | "consider slicing here", | |
| 2815 | "[..]", | |
| 2816 | Applicability::MachineApplicable, | |
| 2817 | ); | |
| 2804 | slicing = Some(errors::SlicingSuggestion { span: span.shrink_to_hi() }); | |
| 2818 | 2805 | } |
| 2819 | 2806 | } |
| 2820 | err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`")); | |
| 2821 | err.emit() | |
| 2807 | self.dcx().emit_err(errors::ExpectedArrayOrSlice { | |
| 2808 | span, | |
| 2809 | ty: expected_ty, | |
| 2810 | slice_pat_semantics, | |
| 2811 | as_deref, | |
| 2812 | slicing, | |
| 2813 | }) | |
| 2822 | 2814 | } |
| 2823 | 2815 | |
| 2824 | 2816 | fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) { |
compiler/rustc_metadata/src/locator.rs+1-1| ... | ... | @@ -290,7 +290,7 @@ impl fmt::Display for CrateFlavor { |
| 290 | 290 | } |
| 291 | 291 | |
| 292 | 292 | impl IntoDiagArg for CrateFlavor { |
| 293 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 293 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 294 | 294 | match self { |
| 295 | 295 | CrateFlavor::Rlib => DiagArgValue::Str(Cow::Borrowed("rlib")), |
| 296 | 296 | CrateFlavor::Rmeta => DiagArgValue::Str(Cow::Borrowed("rmeta")), |
compiler/rustc_middle/src/error.rs+2-2| ... | ... | @@ -47,10 +47,10 @@ pub struct UnsupportedUnion { |
| 47 | 47 | // FIXME(autodiff): I should get used somewhere |
| 48 | 48 | #[derive(Diagnostic)] |
| 49 | 49 | #[diag(middle_autodiff_unsafe_inner_const_ref)] |
| 50 | pub struct AutodiffUnsafeInnerConstRef { | |
| 50 | pub struct AutodiffUnsafeInnerConstRef<'tcx> { | |
| 51 | 51 | #[primary_span] |
| 52 | 52 | pub span: Span, |
| 53 | pub ty: String, | |
| 53 | pub ty: Ty<'tcx>, | |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | #[derive(Subdiagnostic)] |
compiler/rustc_middle/src/mir/interpret/error.rs+4-4| ... | ... | @@ -248,7 +248,7 @@ pub enum InvalidMetaKind { |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | 250 | impl IntoDiagArg for InvalidMetaKind { |
| 251 | fn into_diag_arg(self) -> DiagArgValue { | |
| 251 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 252 | 252 | DiagArgValue::Str(Cow::Borrowed(match self { |
| 253 | 253 | InvalidMetaKind::SliceTooBig => "slice_too_big", |
| 254 | 254 | InvalidMetaKind::TooBig => "too_big", |
| ... | ... | @@ -282,7 +282,7 @@ pub struct Misalignment { |
| 282 | 282 | macro_rules! impl_into_diag_arg_through_debug { |
| 283 | 283 | ($($ty:ty),*$(,)?) => {$( |
| 284 | 284 | impl IntoDiagArg for $ty { |
| 285 | fn into_diag_arg(self) -> DiagArgValue { | |
| 285 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 286 | 286 | DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) |
| 287 | 287 | } |
| 288 | 288 | } |
| ... | ... | @@ -401,7 +401,7 @@ pub enum PointerKind { |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | impl IntoDiagArg for PointerKind { |
| 404 | fn into_diag_arg(self) -> DiagArgValue { | |
| 404 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 405 | 405 | DiagArgValue::Str( |
| 406 | 406 | match self { |
| 407 | 407 | Self::Ref(_) => "ref", |
| ... | ... | @@ -666,7 +666,7 @@ macro_rules! err_ub_custom { |
| 666 | 666 | msg: || $msg, |
| 667 | 667 | add_args: Box::new(move |mut set_arg| { |
| 668 | 668 | $($( |
| 669 | set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); | |
| 669 | set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name, &mut None)); | |
| 670 | 670 | )*)? |
| 671 | 671 | }) |
| 672 | 672 | } |
compiler/rustc_middle/src/mir/pretty.rs+1| ... | ... | @@ -319,6 +319,7 @@ pub fn write_mir_pretty<'tcx>( |
| 319 | 319 | |
| 320 | 320 | writeln!(w, "// WARNING: This output format is intended for human consumers only")?; |
| 321 | 321 | writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; |
| 322 | writeln!(w, "// HINT: See also -Z dump-mir for MIR at specific points during compilation.")?; | |
| 322 | 323 | |
| 323 | 324 | let mut first = true; |
| 324 | 325 | for def_id in dump_mir_def_ids(tcx, single) { |
compiler/rustc_middle/src/mir/terminator.rs+1-1| ... | ... | @@ -357,7 +357,7 @@ impl<O> AssertKind<O> { |
| 357 | 357 | |
| 358 | 358 | macro_rules! add { |
| 359 | 359 | ($name: expr, $value: expr) => { |
| 360 | adder($name.into(), $value.into_diag_arg()); | |
| 360 | adder($name.into(), $value.into_diag_arg(&mut None)); | |
| 361 | 361 | }; |
| 362 | 362 | } |
| 363 | 363 |
compiler/rustc_middle/src/ty/consts/int.rs+1-1| ... | ... | @@ -118,7 +118,7 @@ impl std::fmt::Debug for ConstInt { |
| 118 | 118 | impl IntoDiagArg for ConstInt { |
| 119 | 119 | // FIXME this simply uses the Debug impl, but we could probably do better by converting both |
| 120 | 120 | // to an inherent method that returns `Cow`. |
| 121 | fn into_diag_arg(self) -> DiagArgValue { | |
| 121 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 122 | 122 | DiagArgValue::Str(format!("{self:?}").into()) |
| 123 | 123 | } |
| 124 | 124 | } |
compiler/rustc_middle/src/ty/diagnostics.rs+9-1| ... | ... | @@ -19,8 +19,16 @@ use crate::ty::{ |
| 19 | 19 | TypeSuperVisitable, TypeVisitable, TypeVisitor, |
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | impl IntoDiagArg for Ty<'_> { | |
| 23 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 24 | ty::tls::with(|tcx| { | |
| 25 | let ty = tcx.short_string(self, path); | |
| 26 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(ty)) | |
| 27 | }) | |
| 28 | } | |
| 29 | } | |
| 30 | ||
| 22 | 31 | into_diag_arg_using_display! { |
| 23 | Ty<'_>, | |
| 24 | 32 | ty::Region<'_>, |
| 25 | 33 | } |
| 26 | 34 |
compiler/rustc_middle/src/ty/error.rs+4-6| ... | ... | @@ -213,10 +213,9 @@ impl<'tcx> Ty<'tcx> { |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | 215 | impl<'tcx> TyCtxt<'tcx> { |
| 216 | pub fn string_with_limit<'a, T>(self, p: T, length_limit: usize) -> String | |
| 216 | pub fn string_with_limit<T>(self, p: T, length_limit: usize) -> String | |
| 217 | 217 | where |
| 218 | T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy, | |
| 219 | <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, | |
| 218 | T: Copy + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, | |
| 220 | 219 | { |
| 221 | 220 | let mut type_limit = 50; |
| 222 | 221 | let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { |
| ... | ... | @@ -253,10 +252,9 @@ impl<'tcx> TyCtxt<'tcx> { |
| 253 | 252 | /// `tcx.short_string(ty, diag.long_ty_path())`. The diagnostic itself is the one that keeps |
| 254 | 253 | /// the existence of a "long type" anywhere in the diagnostic, so the note telling the user |
| 255 | 254 | /// where we wrote the file to is only printed once. |
| 256 | pub fn short_string<'a, T>(self, p: T, path: &mut Option<PathBuf>) -> String | |
| 255 | pub fn short_string<T>(self, p: T, path: &mut Option<PathBuf>) -> String | |
| 257 | 256 | where |
| 258 | T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy + Hash, | |
| 259 | <T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, | |
| 257 | T: Copy + Hash + for<'a, 'b> Lift<TyCtxt<'b>, Lifted: Print<'b, FmtPrinter<'a, 'b>>>, | |
| 260 | 258 | { |
| 261 | 259 | let regular = FmtPrinter::print_string(self, hir::def::Namespace::TypeNS, |cx| { |
| 262 | 260 | self.lift(p).expect("could not lift for printing").print(cx) |
compiler/rustc_middle/src/ty/generic_args.rs+2-2| ... | ... | @@ -159,8 +159,8 @@ unsafe impl<'tcx> Sync for GenericArg<'tcx> where |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | impl<'tcx> IntoDiagArg for GenericArg<'tcx> { |
| 162 | fn into_diag_arg(self) -> DiagArgValue { | |
| 163 | self.to_string().into_diag_arg() | |
| 162 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 163 | self.to_string().into_diag_arg(&mut None) | |
| 164 | 164 | } |
| 165 | 165 | } |
| 166 | 166 |
compiler/rustc_middle/src/ty/layout.rs+2-2| ... | ... | @@ -315,8 +315,8 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | impl<'tcx> IntoDiagArg for LayoutError<'tcx> { |
| 318 | fn into_diag_arg(self) -> DiagArgValue { | |
| 319 | self.to_string().into_diag_arg() | |
| 318 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 319 | self.to_string().into_diag_arg(&mut None) | |
| 320 | 320 | } |
| 321 | 321 | } |
| 322 | 322 |
compiler/rustc_middle/src/ty/predicate.rs+12-6| ... | ... | @@ -158,15 +158,21 @@ impl<'tcx> Predicate<'tcx> { |
| 158 | 158 | } |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | impl rustc_errors::IntoDiagArg for Predicate<'_> { | |
| 162 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 163 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) | |
| 161 | impl<'tcx> rustc_errors::IntoDiagArg for Predicate<'tcx> { | |
| 162 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 163 | ty::tls::with(|tcx| { | |
| 164 | let pred = tcx.short_string(self, path); | |
| 165 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(pred)) | |
| 166 | }) | |
| 164 | 167 | } |
| 165 | 168 | } |
| 166 | 169 | |
| 167 | impl rustc_errors::IntoDiagArg for Clause<'_> { | |
| 168 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 169 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(self.to_string())) | |
| 170 | impl<'tcx> rustc_errors::IntoDiagArg for Clause<'tcx> { | |
| 171 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 172 | ty::tls::with(|tcx| { | |
| 173 | let clause = tcx.short_string(self, path); | |
| 174 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(clause)) | |
| 175 | }) | |
| 170 | 176 | } |
| 171 | 177 | } |
| 172 | 178 |
compiler/rustc_middle/src/ty/print/pretty.rs+12-6| ... | ... | @@ -2898,12 +2898,15 @@ where |
| 2898 | 2898 | /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only |
| 2899 | 2899 | /// the trait path. That is, it will print `Trait<U>` instead of |
| 2900 | 2900 | /// `<T as Trait<U>>`. |
| 2901 | #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] | |
| 2901 | #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] | |
| 2902 | 2902 | pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>); |
| 2903 | 2903 | |
| 2904 | 2904 | impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintOnlyTraitPath<'tcx> { |
| 2905 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 2906 | self.to_string().into_diag_arg() | |
| 2905 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 2906 | ty::tls::with(|tcx| { | |
| 2907 | let trait_ref = tcx.short_string(self, path); | |
| 2908 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) | |
| 2909 | }) | |
| 2907 | 2910 | } |
| 2908 | 2911 | } |
| 2909 | 2912 | |
| ... | ... | @@ -2915,12 +2918,15 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> { |
| 2915 | 2918 | |
| 2916 | 2919 | /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only |
| 2917 | 2920 | /// the trait path, and additionally tries to "sugar" `Fn(...)` trait bounds. |
| 2918 | #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)] | |
| 2921 | #[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift, Hash)] | |
| 2919 | 2922 | pub struct TraitRefPrintSugared<'tcx>(ty::TraitRef<'tcx>); |
| 2920 | 2923 | |
| 2921 | 2924 | impl<'tcx> rustc_errors::IntoDiagArg for TraitRefPrintSugared<'tcx> { |
| 2922 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 2923 | self.to_string().into_diag_arg() | |
| 2925 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 2926 | ty::tls::with(|tcx| { | |
| 2927 | let trait_ref = tcx.short_string(self, path); | |
| 2928 | rustc_errors::DiagArgValue::Str(std::borrow::Cow::Owned(trait_ref)) | |
| 2929 | }) | |
| 2924 | 2930 | } |
| 2925 | 2931 | } |
| 2926 | 2932 |
compiler/rustc_mir_build/src/errors.rs+2-2| ... | ... | @@ -828,7 +828,7 @@ pub(crate) struct IrrefutableLetPatternsWhileLet { |
| 828 | 828 | |
| 829 | 829 | #[derive(Diagnostic)] |
| 830 | 830 | #[diag(mir_build_borrow_of_moved_value)] |
| 831 | pub(crate) struct BorrowOfMovedValue { | |
| 831 | pub(crate) struct BorrowOfMovedValue<'tcx> { | |
| 832 | 832 | #[primary_span] |
| 833 | 833 | #[label] |
| 834 | 834 | #[label(mir_build_occurs_because_label)] |
| ... | ... | @@ -836,7 +836,7 @@ pub(crate) struct BorrowOfMovedValue { |
| 836 | 836 | #[label(mir_build_value_borrowed_label)] |
| 837 | 837 | pub(crate) conflicts_ref: Vec<Span>, |
| 838 | 838 | pub(crate) name: Ident, |
| 839 | pub(crate) ty: String, | |
| 839 | pub(crate) ty: Ty<'tcx>, | |
| 840 | 840 | #[suggestion(code = "ref ", applicability = "machine-applicable")] |
| 841 | 841 | pub(crate) suggest_borrowing: Option<Span>, |
| 842 | 842 | } |
compiler/rustc_mir_build/src/thir/pattern/check_match.rs+1-5| ... | ... | @@ -786,17 +786,13 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: |
| 786 | 786 | } |
| 787 | 787 | }); |
| 788 | 788 | if !conflicts_ref.is_empty() { |
| 789 | let mut path = None; | |
| 790 | let ty = cx.tcx.short_string(ty, &mut path); | |
| 791 | let mut err = sess.dcx().create_err(BorrowOfMovedValue { | |
| 789 | sess.dcx().emit_err(BorrowOfMovedValue { | |
| 792 | 790 | binding_span: pat.span, |
| 793 | 791 | conflicts_ref, |
| 794 | 792 | name: Ident::new(name, pat.span), |
| 795 | 793 | ty, |
| 796 | 794 | suggest_borrowing: Some(pat.span.shrink_to_lo()), |
| 797 | 795 | }); |
| 798 | *err.long_ty_path() = path; | |
| 799 | err.emit(); | |
| 800 | 796 | } |
| 801 | 797 | return; |
| 802 | 798 | } |
compiler/rustc_parse/src/errors.rs-1| ... | ... | @@ -772,7 +772,6 @@ pub(crate) struct LabeledLoopInBreak { |
| 772 | 772 | } |
| 773 | 773 | |
| 774 | 774 | #[derive(Subdiagnostic)] |
| 775 | ||
| 776 | 775 | pub(crate) enum WrapInParentheses { |
| 777 | 776 | #[multipart_suggestion( |
| 778 | 777 | parse_sugg_wrap_expression_in_parentheses, |
compiler/rustc_passes/src/check_attr.rs+2-2| ... | ... | @@ -80,13 +80,13 @@ pub(crate) enum ProcMacroKind { |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | impl IntoDiagArg for ProcMacroKind { |
| 83 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 83 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 84 | 84 | match self { |
| 85 | 85 | ProcMacroKind::Attribute => "attribute proc macro", |
| 86 | 86 | ProcMacroKind::Derive => "derive proc macro", |
| 87 | 87 | ProcMacroKind::FunctionLike => "function-like proc macro", |
| 88 | 88 | } |
| 89 | .into_diag_arg() | |
| 89 | .into_diag_arg(&mut None) | |
| 90 | 90 | } |
| 91 | 91 | } |
| 92 | 92 |
compiler/rustc_passes/src/errors.rs+2-2| ... | ... | @@ -1005,10 +1005,10 @@ pub(crate) struct LayoutHomogeneousAggregate { |
| 1005 | 1005 | |
| 1006 | 1006 | #[derive(Diagnostic)] |
| 1007 | 1007 | #[diag(passes_layout_of)] |
| 1008 | pub(crate) struct LayoutOf { | |
| 1008 | pub(crate) struct LayoutOf<'tcx> { | |
| 1009 | 1009 | #[primary_span] |
| 1010 | 1010 | pub span: Span, |
| 1011 | pub normalized_ty: String, | |
| 1011 | pub normalized_ty: Ty<'tcx>, | |
| 1012 | 1012 | pub ty_layout: String, |
| 1013 | 1013 | } |
| 1014 | 1014 |
compiler/rustc_passes/src/layout_test.rs+1-2| ... | ... | @@ -112,8 +112,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | sym::debug => { |
| 115 | let normalized_ty = | |
| 116 | format!("{}", tcx.normalize_erasing_regions(typing_env, ty)); | |
| 115 | let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty); | |
| 117 | 116 | // FIXME: using the `Debug` impl here isn't ideal. |
| 118 | 117 | let ty_layout = format!("{:#?}", *ty_layout); |
| 119 | 118 | tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout }); |
compiler/rustc_resolve/src/late.rs+1-1| ... | ... | @@ -94,7 +94,7 @@ impl PatternSource { |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | impl IntoDiagArg for PatternSource { |
| 97 | fn into_diag_arg(self) -> DiagArgValue { | |
| 97 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 98 | 98 | DiagArgValue::Str(Cow::Borrowed(self.descr())) |
| 99 | 99 | } |
| 100 | 100 | } |
compiler/rustc_session/src/config.rs+2-2| ... | ... | @@ -2807,8 +2807,8 @@ impl fmt::Display for CrateType { |
| 2807 | 2807 | } |
| 2808 | 2808 | |
| 2809 | 2809 | impl IntoDiagArg for CrateType { |
| 2810 | fn into_diag_arg(self) -> DiagArgValue { | |
| 2811 | self.to_string().into_diag_arg() | |
| 2810 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| 2811 | self.to_string().into_diag_arg(&mut None) | |
| 2812 | 2812 | } |
| 2813 | 2813 | } |
| 2814 | 2814 |
compiler/rustc_session/src/session.rs+2-2| ... | ... | @@ -109,8 +109,8 @@ impl Mul<usize> for Limit { |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | impl rustc_errors::IntoDiagArg for Limit { |
| 112 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 113 | self.to_string().into_diag_arg() | |
| 112 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 113 | self.to_string().into_diag_arg(&mut None) | |
| 114 | 114 | } |
| 115 | 115 | } |
| 116 | 116 |
compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs+1-1| ... | ... | @@ -2418,7 +2418,7 @@ impl<'tcx> ObligationCause<'tcx> { |
| 2418 | 2418 | pub struct ObligationCauseAsDiagArg<'tcx>(pub ObligationCause<'tcx>); |
| 2419 | 2419 | |
| 2420 | 2420 | impl IntoDiagArg for ObligationCauseAsDiagArg<'_> { |
| 2421 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 2421 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 2422 | 2422 | let kind = match self.0.code() { |
| 2423 | 2423 | ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn, .. } => "method_compat", |
| 2424 | 2424 | ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => "type_compat", |
compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs+1-1| ... | ... | @@ -137,7 +137,7 @@ impl InferenceDiagnosticsParentData { |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | impl IntoDiagArg for UnderspecifiedArgKind { |
| 140 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 140 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 141 | 141 | let kind = match self { |
| 142 | 142 | Self::Type { .. } => "type", |
| 143 | 143 | Self::Const { is_parameter: true } => "const_with_param", |
compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs+1-1| ... | ... | @@ -31,7 +31,7 @@ impl<'tcx, T> IntoDiagArg for Highlighted<'tcx, T> |
| 31 | 31 | where |
| 32 | 32 | T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>>, |
| 33 | 33 | { |
| 34 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 34 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 35 | 35 | rustc_errors::DiagArgValue::Str(self.to_string().into()) |
| 36 | 36 | } |
| 37 | 37 | } |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs+4-1| ... | ... | @@ -136,7 +136,10 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( |
| 136 | 136 | ) { |
| 137 | 137 | if hir_generics.where_clause_span.from_expansion() |
| 138 | 138 | || hir_generics.where_clause_span.desugaring_kind().is_some() |
| 139 | || projection.is_some_and(|projection| tcx.is_impl_trait_in_trait(projection.def_id)) | |
| 139 | || projection.is_some_and(|projection| { | |
| 140 | tcx.is_impl_trait_in_trait(projection.def_id) | |
| 141 | || tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable()) | |
| 142 | }) | |
| 140 | 143 | { |
| 141 | 144 | return; |
| 142 | 145 | } |
compiler/rustc_trait_selection/src/errors.rs+3-3| ... | ... | @@ -784,10 +784,10 @@ pub enum TyOrSig<'tcx> { |
| 784 | 784 | } |
| 785 | 785 | |
| 786 | 786 | impl IntoDiagArg for TyOrSig<'_> { |
| 787 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 787 | fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 788 | 788 | match self { |
| 789 | TyOrSig::Ty(ty) => ty.into_diag_arg(), | |
| 790 | TyOrSig::ClosureSig(sig) => sig.into_diag_arg(), | |
| 789 | TyOrSig::Ty(ty) => ty.into_diag_arg(path), | |
| 790 | TyOrSig::ClosureSig(sig) => sig.into_diag_arg(path), | |
| 791 | 791 | } |
| 792 | 792 | } |
| 793 | 793 | } |
compiler/rustc_trait_selection/src/errors/note_and_explain.rs+2-2| ... | ... | @@ -105,7 +105,7 @@ pub enum SuffixKind { |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | impl IntoDiagArg for PrefixKind { |
| 108 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 108 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 109 | 109 | let kind = match self { |
| 110 | 110 | Self::Empty => "empty", |
| 111 | 111 | Self::RefValidFor => "ref_valid_for", |
| ... | ... | @@ -127,7 +127,7 @@ impl IntoDiagArg for PrefixKind { |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | impl IntoDiagArg for SuffixKind { |
| 130 | fn into_diag_arg(self) -> rustc_errors::DiagArgValue { | |
| 130 | fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue { | |
| 131 | 131 | let kind = match self { |
| 132 | 132 | Self::Empty => "empty", |
| 133 | 133 | Self::Continues => "continues", |
library/core/src/ffi/c_str.rs+37-36| ... | ... | @@ -55,18 +55,15 @@ use crate::{fmt, ops, slice, str}; |
| 55 | 55 | /// Passing a Rust-originating C string: |
| 56 | 56 | /// |
| 57 | 57 | /// ``` |
| 58 | /// use std::ffi::{CString, CStr}; | |
| 58 | /// use std::ffi::CStr; | |
| 59 | 59 | /// use std::os::raw::c_char; |
| 60 | 60 | /// |
| 61 | 61 | /// fn work(data: &CStr) { |
| 62 | /// # /* Extern functions are awkward in doc comments - fake it instead | |
| 63 | /// extern "C" { fn work_with(data: *const c_char); } | |
| 64 | /// # */ unsafe extern "C" fn work_with(s: *const c_char) {} | |
| 65 | /// | |
| 62 | /// unsafe extern "C" fn work_with(s: *const c_char) {} | |
| 66 | 63 | /// unsafe { work_with(data.as_ptr()) } |
| 67 | 64 | /// } |
| 68 | 65 | /// |
| 69 | /// let s = CString::new("data data data data").expect("CString::new failed"); | |
| 66 | /// let s = c"Hello world!"; | |
| 70 | 67 | /// work(&s); |
| 71 | 68 | /// ``` |
| 72 | 69 | /// |
| ... | ... | @@ -384,13 +381,12 @@ impl CStr { |
| 384 | 381 | /// # Examples |
| 385 | 382 | /// |
| 386 | 383 | /// ``` |
| 387 | /// use std::ffi::{CStr, CString}; | |
| 384 | /// use std::ffi::CStr; | |
| 388 | 385 | /// |
| 389 | /// unsafe { | |
| 390 | /// let cstring = CString::new("hello").expect("CString::new failed"); | |
| 391 | /// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); | |
| 392 | /// assert_eq!(cstr, &*cstring); | |
| 393 | /// } | |
| 386 | /// let bytes = b"Hello world!\0"; | |
| 387 | /// | |
| 388 | /// let cstr = unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }; | |
| 389 | /// assert_eq!(cstr.to_bytes_with_nul(), bytes); | |
| 394 | 390 | /// ``` |
| 395 | 391 | #[inline] |
| 396 | 392 | #[must_use] |
| ... | ... | @@ -449,38 +445,43 @@ impl CStr { |
| 449 | 445 | /// behavior when `ptr` is used inside the `unsafe` block: |
| 450 | 446 | /// |
| 451 | 447 | /// ```no_run |
| 452 | /// # #![allow(unused_must_use)] | |
| 453 | 448 | /// # #![expect(dangling_pointers_from_temporaries)] |
| 454 | /// use std::ffi::CString; | |
| 449 | /// use std::ffi::{CStr, CString}; | |
| 455 | 450 | /// |
| 456 | /// // Do not do this: | |
| 457 | /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); | |
| 458 | /// unsafe { | |
| 459 | /// // `ptr` is dangling | |
| 460 | /// *ptr; | |
| 461 | /// } | |
| 451 | /// // 💀 The meaning of this entire program is undefined, | |
| 452 | /// // 💀 and nothing about its behavior is guaranteed, | |
| 453 | /// // 💀 not even that its behavior resembles the code as written, | |
| 454 | /// // 💀 just because it contains a single instance of undefined behavior! | |
| 455 | /// | |
| 456 | /// // 🚨 creates a dangling pointer to a temporary `CString` | |
| 457 | /// // 🚨 that is deallocated at the end of the statement | |
| 458 | /// let ptr = CString::new("Hi!".to_uppercase()).unwrap().as_ptr(); | |
| 459 | /// | |
| 460 | /// // without undefined behavior, you would expect that `ptr` equals: | |
| 461 | /// dbg!(CStr::from_bytes_with_nul(b"HI!\0").unwrap()); | |
| 462 | /// | |
| 463 | /// // 🙏 Possibly the program behaved as expected so far, | |
| 464 | /// // 🙏 and this just shows `ptr` is now garbage..., but | |
| 465 | /// // 💀 this violates `CStr::from_ptr`'s safety contract | |
| 466 | /// // 💀 leading to a dereference of a dangling pointer, | |
| 467 | /// // 💀 which is immediate undefined behavior. | |
| 468 | /// // 💀 *BOOM*, you're dead, you're entire program has no meaning. | |
| 469 | /// dbg!(unsafe { CStr::from_ptr(ptr) }); | |
| 462 | 470 | /// ``` |
| 463 | 471 | /// |
| 464 | /// This happens because the pointer returned by `as_ptr` does not carry any | |
| 465 | /// lifetime information and the `CString` is deallocated immediately after | |
| 466 | /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` | |
| 467 | /// expression is evaluated. | |
| 472 | /// This happens because, the pointer returned by `as_ptr` does not carry any | |
| 473 | /// lifetime information, and the `CString` is deallocated immediately after | |
| 474 | /// the expression that it is part of has been evaluated. | |
| 468 | 475 | /// To fix the problem, bind the `CString` to a local variable: |
| 469 | 476 | /// |
| 470 | /// ```no_run | |
| 471 | /// # #![allow(unused_must_use)] | |
| 472 | /// use std::ffi::CString; | |
| 473 | /// | |
| 474 | /// let hello = CString::new("Hello").expect("CString::new failed"); | |
| 475 | /// let ptr = hello.as_ptr(); | |
| 476 | /// unsafe { | |
| 477 | /// // `ptr` is valid because `hello` is in scope | |
| 478 | /// *ptr; | |
| 479 | /// } | |
| 480 | 477 | /// ``` |
| 478 | /// use std::ffi::{CStr, CString}; | |
| 481 | 479 | /// |
| 482 | /// This way, the lifetime of the `CString` in `hello` encompasses | |
| 483 | /// the lifetime of `ptr` and the `unsafe` block. | |
| 480 | /// let c_str = CString::new("Hi!".to_uppercase()).unwrap(); | |
| 481 | /// let ptr = c_str.as_ptr(); | |
| 482 | /// | |
| 483 | /// assert_eq!(unsafe { CStr::from_ptr(ptr) }, c"HI!"); | |
| 484 | /// ``` | |
| 484 | 485 | #[inline] |
| 485 | 486 | #[must_use] |
| 486 | 487 | #[stable(feature = "rust1", since = "1.0.0")] |
library/core/src/mem/maybe_uninit.rs-36| ... | ... | @@ -331,42 +331,6 @@ impl<T> MaybeUninit<T> { |
| 331 | 331 | MaybeUninit { uninit: () } |
| 332 | 332 | } |
| 333 | 333 | |
| 334 | /// Creates a new array of `MaybeUninit<T>` items, in an uninitialized state. | |
| 335 | /// | |
| 336 | /// Note: in a future Rust version this method may become unnecessary | |
| 337 | /// when Rust allows | |
| 338 | /// [inline const expressions](https://github.com/rust-lang/rust/issues/76001). | |
| 339 | /// The example below could then use `let mut buf = [const { MaybeUninit::<u8>::uninit() }; 32];`. | |
| 340 | /// | |
| 341 | /// # Examples | |
| 342 | /// | |
| 343 | /// ```no_run | |
| 344 | /// #![feature(maybe_uninit_uninit_array, maybe_uninit_slice)] | |
| 345 | /// | |
| 346 | /// use std::mem::MaybeUninit; | |
| 347 | /// | |
| 348 | /// unsafe extern "C" { | |
| 349 | /// fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize; | |
| 350 | /// } | |
| 351 | /// | |
| 352 | /// /// Returns a (possibly smaller) slice of data that was actually read | |
| 353 | /// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] { | |
| 354 | /// unsafe { | |
| 355 | /// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len()); | |
| 356 | /// buf[..len].assume_init_ref() | |
| 357 | /// } | |
| 358 | /// } | |
| 359 | /// | |
| 360 | /// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array(); | |
| 361 | /// let data = read(&mut buf); | |
| 362 | /// ``` | |
| 363 | #[unstable(feature = "maybe_uninit_uninit_array", issue = "96097")] | |
| 364 | #[must_use] | |
| 365 | #[inline(always)] | |
| 366 | pub const fn uninit_array<const N: usize>() -> [Self; N] { | |
| 367 | [const { MaybeUninit::uninit() }; N] | |
| 368 | } | |
| 369 | ||
| 370 | 334 | /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being |
| 371 | 335 | /// filled with `0` bytes. It depends on `T` whether that already makes for |
| 372 | 336 | /// proper initialization. For example, `MaybeUninit<usize>::zeroed()` is initialized, |
library/std/src/sys/pal/unix/thread.rs+1-1| ... | ... | @@ -59,7 +59,7 @@ impl Thread { |
| 59 | 59 | assert_eq!( |
| 60 | 60 | libc::pthread_attr_setstacksize( |
| 61 | 61 | attr.as_mut_ptr(), |
| 62 | cmp::max(stack, min_stack_size(&attr)) | |
| 62 | cmp::max(stack, min_stack_size(attr.as_ptr())) | |
| 63 | 63 | ), |
| 64 | 64 | 0 |
| 65 | 65 | ); |
src/build_helper/src/git.rs+1| ... | ... | @@ -154,6 +154,7 @@ pub fn get_closest_merge_commit( |
| 154 | 154 | "rev-list", |
| 155 | 155 | &format!("--author={}", config.git_merge_commit_email), |
| 156 | 156 | "-n1", |
| 157 | "--first-parent", | |
| 157 | 158 | &merge_base, |
| 158 | 159 | ]); |
| 159 | 160 |
src/doc/rustc-dev-guide/.github/workflows/ci.yml+3-3| ... | ... | @@ -6,8 +6,8 @@ on: |
| 6 | 6 | - master |
| 7 | 7 | pull_request: |
| 8 | 8 | schedule: |
| 9 | # Run at 18:00 UTC every day | |
| 10 | - cron: '0 18 * * *' | |
| 9 | # Run multiple times a day as the successfull cached links are not checked every time. | |
| 10 | - cron: '0 */8 * * *' | |
| 11 | 11 | |
| 12 | 12 | jobs: |
| 13 | 13 | ci: |
| ... | ... | @@ -15,7 +15,7 @@ jobs: |
| 15 | 15 | runs-on: ubuntu-latest |
| 16 | 16 | env: |
| 17 | 17 | MDBOOK_VERSION: 0.4.21 |
| 18 | MDBOOK_LINKCHECK2_VERSION: 0.8.1 | |
| 18 | MDBOOK_LINKCHECK2_VERSION: 0.9.1 | |
| 19 | 19 | MDBOOK_MERMAID_VERSION: 0.12.6 |
| 20 | 20 | MDBOOK_TOC_VERSION: 0.11.2 |
| 21 | 21 | DEPLOY_DIR: book/html |
src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml+1-1| ... | ... | @@ -111,4 +111,4 @@ jobs: |
| 111 | 111 | to: 196385 |
| 112 | 112 | type: "stream" |
| 113 | 113 | topic: "Subtree sync automation" |
| 114 | content: ${{ steps.message.outputs.message }} | |
| 114 | content: ${{ steps.create-message.outputs.message }} |
src/doc/rustc-dev-guide/examples/README+4-1| ... | ... | @@ -4,7 +4,10 @@ For each example to compile, you will need to first run the following: |
| 4 | 4 | |
| 5 | 5 | To create an executable: |
| 6 | 6 | |
| 7 | rustc rustc-driver-example.rs | |
| 7 | rustup run nightly rustc rustc-driver-example.rs | |
| 8 | ||
| 9 | You might need to be more specific about the exact nightly version. See the comments at the top of | |
| 10 | the examples for the version they were written for. | |
| 8 | 11 | |
| 9 | 12 | To run an executable: |
| 10 | 13 |
src/doc/rustc-dev-guide/examples/rustc-driver-example.rs+12-2| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | // Tested with nightly-2025-02-13 | |
| 2 | ||
| 1 | 3 | #![feature(rustc_private)] |
| 2 | 4 | |
| 3 | 5 | extern crate rustc_ast; |
| ... | ... | @@ -73,7 +75,7 @@ impl rustc_driver::Callbacks for MyCallbacks { |
| 73 | 75 | let hir = tcx.hir(); |
| 74 | 76 | let item = hir.item(id); |
| 75 | 77 | match item.kind { |
| 76 | rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn(_, _, _) => { | |
| 78 | rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { | |
| 77 | 79 | let name = item.ident; |
| 78 | 80 | let ty = tcx.type_of(item.hir_id().owner.def_id); |
| 79 | 81 | println!("{name:?}:\t{ty:?}") |
| ... | ... | @@ -87,5 +89,13 @@ impl rustc_driver::Callbacks for MyCallbacks { |
| 87 | 89 | } |
| 88 | 90 | |
| 89 | 91 | fn main() { |
| 90 | run_compiler(&["main.rs".to_string()], &mut MyCallbacks); | |
| 92 | run_compiler( | |
| 93 | &[ | |
| 94 | // The first argument, which in practice contains the name of the binary being executed | |
| 95 | // (i.e. "rustc") is ignored by rustc. | |
| 96 | "ignored".to_string(), | |
| 97 | "main.rs".to_string(), | |
| 98 | ], | |
| 99 | &mut MyCallbacks, | |
| 100 | ); | |
| 91 | 101 | } |
src/doc/rustc-dev-guide/examples/rustc-driver-interacting-with-the-ast.rs+14-4| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | // Tested with nightly-2025-02-13 | |
| 2 | ||
| 1 | 3 | #![feature(rustc_private)] |
| 2 | 4 | |
| 3 | 5 | extern crate rustc_ast; |
| ... | ... | @@ -18,7 +20,7 @@ use std::path::Path; |
| 18 | 20 | use std::sync::Arc; |
| 19 | 21 | |
| 20 | 22 | use rustc_ast_pretty::pprust::item_to_string; |
| 21 | use rustc_driver::{Compilation, run_compiler}; | |
| 23 | use rustc_driver::{run_compiler, Compilation}; | |
| 22 | 24 | use rustc_interface::interface::{Compiler, Config}; |
| 23 | 25 | use rustc_middle::ty::TyCtxt; |
| 24 | 26 | |
| ... | ... | @@ -74,8 +76,8 @@ impl rustc_driver::Callbacks for MyCallbacks { |
| 74 | 76 | for id in hir_krate.items() { |
| 75 | 77 | let item = hir_krate.item(id); |
| 76 | 78 | // Use pattern-matching to find a specific node inside the main function. |
| 77 | if let rustc_hir::ItemKind::Fn(_, _, body_id) = item.kind { | |
| 78 | let expr = &tcx.hir_body(body_id).value; | |
| 79 | if let rustc_hir::ItemKind::Fn { body, .. } = item.kind { | |
| 80 | let expr = &tcx.hir_body(body).value; | |
| 79 | 81 | if let rustc_hir::ExprKind::Block(block, _) = expr.kind { |
| 80 | 82 | if let rustc_hir::StmtKind::Let(let_stmt) = block.stmts[0].kind { |
| 81 | 83 | if let Some(expr) = let_stmt.init { |
| ... | ... | @@ -94,5 +96,13 @@ impl rustc_driver::Callbacks for MyCallbacks { |
| 94 | 96 | } |
| 95 | 97 | |
| 96 | 98 | fn main() { |
| 97 | run_compiler(&["main.rs".to_string()], &mut MyCallbacks); | |
| 99 | run_compiler( | |
| 100 | &[ | |
| 101 | // The first argument, which in practice contains the name of the binary being executed | |
| 102 | // (i.e. "rustc") is ignored by rustc. | |
| 103 | "ignored".to_string(), | |
| 104 | "main.rs".to_string(), | |
| 105 | ], | |
| 106 | &mut MyCallbacks, | |
| 107 | ); | |
| 98 | 108 | } |
src/doc/rustc-dev-guide/examples/rustc-interface-example.rs+4-4| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | // Tested with nightly-2025-02-13 | |
| 2 | ||
| 1 | 3 | #![feature(rustc_private)] |
| 2 | 4 | |
| 3 | 5 | extern crate rustc_driver; |
| ... | ... | @@ -9,8 +11,6 @@ extern crate rustc_interface; |
| 9 | 11 | extern crate rustc_session; |
| 10 | 12 | extern crate rustc_span; |
| 11 | 13 | |
| 12 | use std::sync::Arc; | |
| 13 | ||
| 14 | 14 | use rustc_errors::registry; |
| 15 | 15 | use rustc_hash::FxHashMap; |
| 16 | 16 | use rustc_session::config; |
| ... | ... | @@ -56,7 +56,7 @@ fn main() { |
| 56 | 56 | expanded_args: Vec::new(), |
| 57 | 57 | ice_file: None, |
| 58 | 58 | hash_untracked_state: None, |
| 59 | using_internal_features: Arc::default(), | |
| 59 | using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, | |
| 60 | 60 | }; |
| 61 | 61 | rustc_interface::run_compiler(config, |compiler| { |
| 62 | 62 | // Parse the program and print the syntax tree. |
| ... | ... | @@ -68,7 +68,7 @@ fn main() { |
| 68 | 68 | let hir = tcx.hir(); |
| 69 | 69 | let item = hir.item(id); |
| 70 | 70 | match item.kind { |
| 71 | rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn(_, _, _) => { | |
| 71 | rustc_hir::ItemKind::Static(_, _, _) | rustc_hir::ItemKind::Fn { .. } => { | |
| 72 | 72 | let name = item.ident; |
| 73 | 73 | let ty = tcx.type_of(item.hir_id().owner.def_id); |
| 74 | 74 | println!("{name:?}:\t{ty:?}") |
src/doc/rustc-dev-guide/examples/rustc-interface-getting-diagnostics.rs+4-2| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | // Tested with nightly-2025-02-13 | |
| 2 | ||
| 1 | 3 | #![feature(rustc_private)] |
| 2 | 4 | |
| 3 | 5 | extern crate rustc_data_structures; |
| ... | ... | @@ -15,7 +17,7 @@ use std::sync::{Arc, Mutex}; |
| 15 | 17 | use rustc_errors::emitter::Emitter; |
| 16 | 18 | use rustc_errors::registry::{self, Registry}; |
| 17 | 19 | use rustc_errors::translation::Translate; |
| 18 | use rustc_errors::{DiagCtxt, DiagInner, FluentBundle}; | |
| 20 | use rustc_errors::{DiagInner, FluentBundle}; | |
| 19 | 21 | use rustc_session::config; |
| 20 | 22 | use rustc_span::source_map::SourceMap; |
| 21 | 23 | |
| ... | ... | @@ -79,7 +81,7 @@ fn main() { |
| 79 | 81 | expanded_args: Vec::new(), |
| 80 | 82 | ice_file: None, |
| 81 | 83 | hash_untracked_state: None, |
| 82 | using_internal_features: Arc::default(), | |
| 84 | using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, | |
| 83 | 85 | }; |
| 84 | 86 | rustc_interface::run_compiler(config, |compiler| { |
| 85 | 87 | let krate = rustc_interface::passes::parse(&compiler.sess); |
src/doc/rustc-dev-guide/rust-version+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 124cc92199ffa924f6b4c7cc819a85b65e0c3984 | |
| 1 | 4ecd70ddd1039a3954056c1071e40278048476fa |
src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md+41-2| ... | ... | @@ -1,7 +1,46 @@ |
| 1 | 1 | # Debugging bootstrap |
| 2 | 2 | |
| 3 | There are two main ways to debug bootstrap itself. The first is through println logging, and the second is through the `tracing` feature. | |
| 4 | ||
| 3 | 5 | > FIXME: this section should be expanded |
| 4 | 6 | |
| 7 | ## `println` logging | |
| 8 | ||
| 9 | Bootstrap has extensive unstructured logging. Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail). | |
| 10 | ||
| 11 | If you want to know which `Step` ran a command, you could invoke bootstrap like so: | |
| 12 | ||
| 13 | ``` | |
| 14 | $ ./x dist rustc --dry-run -vv | |
| 15 | learning about cargo | |
| 16 | running: RUSTC_BOOTSTRAP="1" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "metadata" "--format-version" "1" "--no-deps" "--manifest-path" "/home/jyn/src/rust2/Cargo.toml" (failure_mode=Exit) (created at src/bootstrap/src/core/metadata.rs:81:25, executed at src/bootstrap/src/core/metadata.rs:92:50) | |
| 17 | running: RUSTC_BOOTSTRAP="1" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "metadata" "--format-version" "1" "--no-deps" "--manifest-path" "/home/jyn/src/rust2/library/Cargo.toml" (failure_mode=Exit) (created at src/bootstrap/src/core/metadata.rs:81:25, executed at src/bootstrap/src/core/metadata.rs:92:50) | |
| 18 | > Assemble { target_compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu } } | |
| 19 | > Libdir { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, target: x86_64-unknown-linux-gnu } | |
| 20 | > Sysroot { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, force_recompile: false } | |
| 21 | Removing sysroot /home/jyn/src/rust2/build/tmp-dry-run/x86_64-unknown-linux-gnu/stage1 to avoid caching bugs | |
| 22 | < Sysroot { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, force_recompile: false } | |
| 23 | < Libdir { compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu }, target: x86_64-unknown-linux-gnu } | |
| 24 | ... | |
| 25 | ``` | |
| 26 | ||
| 27 | This will go through all the recursive dependency calculations, where `Step`s internally call `builder.ensure()`, without actually running cargo or the compiler. | |
| 28 | ||
| 29 | In some cases, even this may not be enough logging (if so, please add more!). In that case, you can omit `--dry-run`, which will show the normal output inline with the debug logging: | |
| 30 | ||
| 31 | ``` | |
| 32 | c Sysroot { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu }, force_recompile: false } | |
| 33 | using sysroot /home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0-sysroot | |
| 34 | Building stage0 library artifacts (x86_64-unknown-linux-gnu) | |
| 35 | running: cd "/home/jyn/src/rust2" && env ... RUSTC_VERBOSE="2" RUSTC_WRAPPER="/home/jyn/src/rust2/build/bootstrap/debug/rustc" "/home/jyn/src/rust2/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-Zroot-dir=/home/jyn/src/rust2" "-v" "-v" "--manifest-path" "/home/jyn/src/rust2/library/sysroot/Cargo.toml" "--message-format" "json-render-diagnostics" | |
| 36 | 0.293440230s INFO prepare_target{force=false package_id=sysroot v0.0.0 (/home/jyn/src/rust2/library/sysroot) target="sysroot"}: cargo::core::compiler::fingerprint: fingerprint error for sysroot v0.0.0 (/home/jyn/src/rust2/library/sysroot)/Build/TargetInner { name_inferred: true, ..: lib_target("sysroot", ["lib"], "/home/jyn/src/rust2/library/sysroot/src/lib.rs", Edition2021) } | |
| 37 | ... | |
| 38 | ``` | |
| 39 | ||
| 40 | In most cases this should not be necessary. | |
| 41 | ||
| 42 | TODO: we should convert all this to structured logging so it's easier to control precisely. | |
| 43 | ||
| 5 | 44 | ## `tracing` in bootstrap |
| 6 | 45 | |
| 7 | 46 | Bootstrap has conditional [`tracing`][tracing] setup to provide structured logging. |
| ... | ... | @@ -53,11 +92,11 @@ Checking stage0 bootstrap artifacts (x86_64-unknown-linux-gnu) |
| 53 | 92 | Build completed successfully in 0:00:08 |
| 54 | 93 | ``` |
| 55 | 94 | |
| 56 | #### Controlling log output | |
| 95 | #### Controlling tracing output | |
| 57 | 96 | |
| 58 | 97 | The env var `BOOTSTRAP_TRACING` accepts a [`tracing` env-filter][tracing-env-filter]. |
| 59 | 98 | |
| 60 | There are two orthogonal ways to control which kind of logs you want: | |
| 99 | There are two orthogonal ways to control which kind of tracing logs you want: | |
| 61 | 100 | |
| 62 | 101 | 1. You can specify the log **level**, e.g. `DEBUG` or `TRACE`. |
| 63 | 102 | 2. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` vs custom targets like `CONFIG_HANDLING`. |
src/doc/rustc-dev-guide/src/building/suggested.md+29-4| ... | ... | @@ -120,10 +120,35 @@ create a `.vim/coc-settings.json`. The settings can be edited with |
| 120 | 120 | [`src/etc/rust_analyzer_settings.json`]. |
| 121 | 121 | |
| 122 | 122 | Another way is without a plugin, and creating your own logic in your |
| 123 | configuration. To do this you must translate the JSON to Lua yourself. The | |
| 124 | translation is 1:1 and fairly straight-forward. It must be put in the | |
| 125 | `["rust-analyzer"]` key of the setup table, which is [shown | |
| 126 | here](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#rust_analyzer). | |
| 123 | configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): | |
| 124 | ||
| 125 | ```lua | |
| 126 | lspconfig.rust_analyzer.setup { | |
| 127 | root_dir = function() | |
| 128 | local default = lspconfig.rust_analyzer.config_def.default_config.root_dir() | |
| 129 | -- the default root detection uses the cargo workspace root. | |
| 130 | -- but for rust-lang/rust, the standard library is in its own workspace. | |
| 131 | -- use the git root instead. | |
| 132 | local compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml") | |
| 133 | if vim.fs.basename(default) == "library" and vim.uv.fs_stat(compiler_config) then | |
| 134 | return vim.fs.dirname(default) | |
| 135 | end | |
| 136 | return default | |
| 137 | end, | |
| 138 | on_init = function(client) | |
| 139 | local path = client.workspace_folders[1].name | |
| 140 | local config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json") | |
| 141 | if vim.uv.fs_stat(config) then | |
| 142 | -- load rust-lang/rust settings | |
| 143 | local file = io.open(config) | |
| 144 | local json = vim.json.decode(file:read("*a")) | |
| 145 | client.config.settings["rust-analyzer"] = json.lsp["rust-analyzer"].initialization_options | |
| 146 | client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) | |
| 147 | end | |
| 148 | return true | |
| 149 | end | |
| 150 | } | |
| 151 | ``` | |
| 127 | 152 | |
| 128 | 153 | If you would like to use the build task that is described above, you may either |
| 129 | 154 | make your own command in your config, or you can install a plugin such as |
src/doc/rustc-dev-guide/src/compiler-debugging.md+1-1| ... | ... | @@ -368,7 +368,7 @@ error: layout_of(&'a u32) = Layout { |
| 368 | 368 | error: aborting due to previous error |
| 369 | 369 | ``` |
| 370 | 370 | |
| 371 | [`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/abi/struct.Layout.html | |
| 371 | [`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/stable_mir/abi/struct.Layout.html | |
| 372 | 372 | |
| 373 | 373 | |
| 374 | 374 | ## Configuring CodeLLDB for debugging `rustc` |
src/doc/rustc-dev-guide/src/profiling/with_perf.md+7| ... | ... | @@ -52,6 +52,13 @@ you made in the beginning. But there are some things to be aware of: |
| 52 | 52 | - You probably don't want incremental messing about with your |
| 53 | 53 | profile. So something like `CARGO_INCREMENTAL=0` can be helpful. |
| 54 | 54 | |
| 55 | In case to avoid the issue of `addr2line xxx/elf: could not read first record` when reading | |
| 56 | collected data from `cargo`, you may need use the latest version of `addr2line`: | |
| 57 | ||
| 58 | ```bash | |
| 59 | cargo install addr2line --features="bin" | |
| 60 | ``` | |
| 61 | ||
| 55 | 62 | ### Gathering a perf profile from a `perf.rust-lang.org` test |
| 56 | 63 | |
| 57 | 64 | Often we want to analyze a specific test from `perf.rust-lang.org`. |
src/doc/rustc-dev-guide/src/rustc-driver/getting-diagnostics.md-1| ... | ... | @@ -8,7 +8,6 @@ otherwise be printed to stderr. |
| 8 | 8 | To get diagnostics from the compiler, |
| 9 | 9 | configure [`rustc_interface::Config`] to output diagnostic to a buffer, |
| 10 | 10 | and run [`TyCtxt.analysis`]. |
| 11 | The following was tested with <!-- date-check: september 2024 --> `nightly-2024-09-16`: | |
| 12 | 11 | |
| 13 | 12 | ```rust |
| 14 | 13 | {{#include ../../examples/rustc-interface-getting-diagnostics.rs}} |
src/doc/rustc-dev-guide/src/rustc-driver/interacting-with-the-ast.md-1| ... | ... | @@ -5,7 +5,6 @@ |
| 5 | 5 | ## Getting the type of an expression |
| 6 | 6 | |
| 7 | 7 | To get the type of an expression, use the [`after_analysis`] callback to get a [`TyCtxt`]. |
| 8 | The following was tested with <!-- date-check: december 2024 --> `nightly-2024-12-15`: | |
| 9 | 8 | |
| 10 | 9 | ```rust |
| 11 | 10 | {{#include ../../examples/rustc-driver-interacting-with-the-ast.rs}} |
src/gcc+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | Subproject commit e607be166673a8de9fc07f6f02c60426e556c5f2 | |
| 1 | Subproject commit 48664a6cab29d48138ffa004b7978d52ef73e3ac |
tests/run-make/const_fn_mir/dump.mir+1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | // WARNING: This output format is intended for human consumers only |
| 2 | 2 | // and is subject to change without notice. Knock yourself out. |
| 3 | // HINT: See also -Z dump-mir for MIR at specific points during compilation. | |
| 3 | 4 | fn foo() -> i32 { |
| 4 | 5 | let mut _0: i32; |
| 5 | 6 | let mut _1: (i32, bool); |
tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | // Regression test for <https://github.com/rust-lang/rust/issues/137554>. | |
| 2 | ||
| 3 | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | |
| 4 | //~^ ERROR `?Trait` is not permitted in trait object types | |
| 5 | //~| ERROR expected trait, found associated function `Iterator::advance_by` | |
| 6 | //~| ERROR the value of the associated type `Item` in `Iterator` must be specified | |
| 7 | todo!() | |
| 8 | } |
tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | error[E0658]: `?Trait` is not permitted in trait object types | |
| 2 | --> $DIR/missing-associated_item_or_field_def_ids.rs:3:29 | |
| 3 | | | |
| 4 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable | |
| 8 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 9 | ||
| 10 | error[E0404]: expected trait, found associated function `Iterator::advance_by` | |
| 11 | --> $DIR/missing-associated_item_or_field_def_ids.rs:3:30 | |
| 12 | | | |
| 13 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait | |
| 15 | ||
| 16 | error[E0191]: the value of the associated type `Item` in `Iterator` must be specified | |
| 17 | --> $DIR/missing-associated_item_or_field_def_ids.rs:3:18 | |
| 18 | | | |
| 19 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | |
| 20 | | ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>` | |
| 21 | ||
| 22 | error: aborting due to 3 previous errors | |
| 23 | ||
| 24 | Some errors have detailed explanations: E0191, E0404, E0658. | |
| 25 | For more information about an error, try `rustc --explain E0191`. |
tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | // Fix for <https://github.com/rust-lang/rust/issues/137508>. | |
| 2 | ||
| 3 | trait Tr { | |
| 4 | type Item; | |
| 5 | } | |
| 6 | ||
| 7 | fn main() { | |
| 8 | let _: dyn Tr + ?Foo<Assoc = ()>; | |
| 9 | //~^ ERROR: `?Trait` is not permitted in trait object types | |
| 10 | //~| ERROR: cannot find trait `Foo` in this scope | |
| 11 | //~| ERROR: the value of the associated type `Item` in `Tr` must be specified | |
| 12 | } |
tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | error[E0658]: `?Trait` is not permitted in trait object types | |
| 2 | --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21 | |
| 3 | | | |
| 4 | LL | let _: dyn Tr + ?Foo<Assoc = ()>; | |
| 5 | | ^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable | |
| 8 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | |
| 9 | ||
| 10 | error[E0405]: cannot find trait `Foo` in this scope | |
| 11 | --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:22 | |
| 12 | | | |
| 13 | LL | let _: dyn Tr + ?Foo<Assoc = ()>; | |
| 14 | | ^^^ not found in this scope | |
| 15 | ||
| 16 | error[E0191]: the value of the associated type `Item` in `Tr` must be specified | |
| 17 | --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:16 | |
| 18 | | | |
| 19 | LL | type Item; | |
| 20 | | --------- `Item` defined here | |
| 21 | ... | |
| 22 | LL | let _: dyn Tr + ?Foo<Assoc = ()>; | |
| 23 | | ^^ help: specify the associated type: `Tr<Item = Type>` | |
| 24 | ||
| 25 | error: aborting due to 3 previous errors | |
| 26 | ||
| 27 | Some errors have detailed explanations: E0191, E0405, E0658. | |
| 28 | For more information about an error, try `rustc --explain E0191`. |
tests/ui/async-await/async-fn/suggest-constrain.rs created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | // Ensure that we don't suggest constraining `CallRefFuture` here, | |
| 2 | // since that isn't stable. | |
| 3 | ||
| 4 | fn spawn<F: AsyncFn() + Send>(f: F) { | |
| 5 | check_send(f()); | |
| 6 | //~^ ERROR cannot be sent between threads safely | |
| 7 | } | |
| 8 | ||
| 9 | fn check_send<T: Send>(_: T) {} | |
| 10 | ||
| 11 | fn main() {} |
tests/ui/async-await/async-fn/suggest-constrain.stderr created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | error[E0277]: `<F as AsyncFnMut<()>>::CallRefFuture<'_>` cannot be sent between threads safely | |
| 2 | --> $DIR/suggest-constrain.rs:5:16 | |
| 3 | | | |
| 4 | LL | check_send(f()); | |
| 5 | | ---------- ^^^ `<F as AsyncFnMut<()>>::CallRefFuture<'_>` cannot be sent between threads safely | |
| 6 | | | | |
| 7 | | required by a bound introduced by this call | |
| 8 | | | |
| 9 | = help: the trait `Send` is not implemented for `<F as AsyncFnMut<()>>::CallRefFuture<'_>` | |
| 10 | note: required by a bound in `check_send` | |
| 11 | --> $DIR/suggest-constrain.rs:9:18 | |
| 12 | | | |
| 13 | LL | fn check_send<T: Send>(_: T) {} | |
| 14 | | ^^^^ required by this bound in `check_send` | |
| 15 | ||
| 16 | error: aborting due to 1 previous error | |
| 17 | ||
| 18 | For more information about this error, try `rustc --explain E0277`. |
tests/ui/deref-non-pointer.stderr+1-1| ... | ... | @@ -2,7 +2,7 @@ error[E0614]: type `{integer}` cannot be dereferenced |
| 2 | 2 | --> $DIR/deref-non-pointer.rs:2:9 |
| 3 | 3 | | |
| 4 | 4 | LL | match *1 { |
| 5 | | ^^ | |
| 5 | | ^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/diagnostic-width/long-E0529.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes | |
| 2 | // The regex below normalizes the long type file name to make it suitable for compare-modes. | |
| 3 | //@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" | |
| 4 | type A = (i32, i32, i32, i32); | |
| 5 | type B = (A, A, A, A); | |
| 6 | type C = (B, B, B, B); | |
| 7 | type D = (C, C, C, C); | |
| 8 | ||
| 9 | fn foo(x: D) { | |
| 10 | let [] = x; //~ ERROR expected an array or slice, found `(... | |
| 11 | //~^ pattern cannot match with input type `(... | |
| 12 | } | |
| 13 | ||
| 14 | fn main() {} |
tests/ui/diagnostic-width/long-E0529.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[E0529]: expected an array or slice, found `(..., ..., ..., ...)` | |
| 2 | --> $DIR/long-E0529.rs:10:9 | |
| 3 | | | |
| 4 | LL | let [] = x; | |
| 5 | | ^^ pattern cannot match with input type `(..., ..., ..., ...)` | |
| 6 | | | |
| 7 | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' | |
| 8 | = note: consider using `--verbose` to print the full type name to the console | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For more information about this error, try `rustc --explain E0529`. |
tests/ui/diagnostic-width/long-E0609.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes | |
| 2 | // The regex below normalizes the long type file name to make it suitable for compare-modes. | |
| 3 | //@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" | |
| 4 | type A = (i32, i32, i32, i32); | |
| 5 | type B = (A, A, A, A); | |
| 6 | type C = (B, B, B, B); | |
| 7 | type D = (C, C, C, C); | |
| 8 | ||
| 9 | fn foo(x: D) { | |
| 10 | x.field; //~ ERROR no field `field` on type `(... | |
| 11 | } | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/diagnostic-width/long-E0609.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[E0609]: no field `field` on type `(..., ..., ..., ...)` | |
| 2 | --> $DIR/long-E0609.rs:10:7 | |
| 3 | | | |
| 4 | LL | x.field; | |
| 5 | | ^^^^^ unknown field | |
| 6 | | | |
| 7 | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' | |
| 8 | = note: consider using `--verbose` to print the full type name to the console | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For more information about this error, try `rustc --explain E0609`. |
tests/ui/diagnostic-width/long-E0614.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes | |
| 2 | // The regex below normalizes the long type file name to make it suitable for compare-modes. | |
| 3 | //@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" | |
| 4 | type A = (i32, i32, i32, i32); | |
| 5 | type B = (A, A, A, A); | |
| 6 | type C = (B, B, B, B); | |
| 7 | type D = (C, C, C, C); | |
| 8 | ||
| 9 | fn foo(x: D) { | |
| 10 | *x; //~ ERROR type `(... | |
| 11 | } | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/diagnostic-width/long-E0614.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced | |
| 2 | --> $DIR/long-E0614.rs:10:5 | |
| 3 | | | |
| 4 | LL | *x; | |
| 5 | | ^^ can't be dereferenced | |
| 6 | | | |
| 7 | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' | |
| 8 | = note: consider using `--verbose` to print the full type name to the console | |
| 9 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For more information about this error, try `rustc --explain E0614`. |
tests/ui/diagnostic-width/long-E0618.rs created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes | |
| 2 | // The regex below normalizes the long type file name to make it suitable for compare-modes. | |
| 3 | //@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'" | |
| 4 | type A = (i32, i32, i32, i32); | |
| 5 | type B = (A, A, A, A); | |
| 6 | type C = (B, B, B, B); | |
| 7 | type D = (C, C, C, C); | |
| 8 | ||
| 9 | fn foo(x: D) { //~ `x` has type `(... | |
| 10 | x(); //~ ERROR expected function, found `(... | |
| 11 | } | |
| 12 | ||
| 13 | fn main() {} |
tests/ui/diagnostic-width/long-E0618.stderr created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | error[E0618]: expected function, found `(..., ..., ..., ...)` | |
| 2 | --> $DIR/long-E0618.rs:10:5 | |
| 3 | | | |
| 4 | LL | fn foo(x: D) { | |
| 5 | | - `x` has type `(..., ..., ..., ...)` | |
| 6 | LL | x(); | |
| 7 | | ^-- | |
| 8 | | | | |
| 9 | | call expression requires function | |
| 10 | | | |
| 11 | = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt' | |
| 12 | = note: consider using `--verbose` to print the full type name to the console | |
| 13 | ||
| 14 | error: aborting due to 1 previous error | |
| 15 | ||
| 16 | For more information about this error, try `rustc --explain E0618`. |
tests/ui/error-codes/E0614.stderr+1-1| ... | ... | @@ -2,7 +2,7 @@ error[E0614]: type `u32` cannot be dereferenced |
| 2 | 2 | --> $DIR/E0614.rs:3:5 |
| 3 | 3 | | |
| 4 | 4 | LL | *y; |
| 5 | | ^^ | |
| 5 | | ^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/issues/issue-17373.stderr+1-1| ... | ... | @@ -2,7 +2,7 @@ error[E0614]: type `!` cannot be dereferenced |
| 2 | 2 | --> $DIR/issue-17373.rs:2:5 |
| 3 | 3 | | |
| 4 | 4 | LL | *return |
| 5 | | ^^^^^^^ | |
| 5 | | ^^^^^^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/issues/issue-9814.stderr+1-1| ... | ... | @@ -2,7 +2,7 @@ error[E0614]: type `Foo` cannot be dereferenced |
| 2 | 2 | --> $DIR/issue-9814.rs:7:13 |
| 3 | 3 | | |
| 4 | 4 | LL | let _ = *Foo::Bar(2); |
| 5 | | ^^^^^^^^^^^^ | |
| 5 | | ^^^^^^^^^^^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error: aborting due to 1 previous error |
| 8 | 8 |
tests/ui/parser/expr-as-stmt.stderr+1-1| ... | ... | @@ -133,7 +133,7 @@ error[E0614]: type `{integer}` cannot be dereferenced |
| 133 | 133 | --> $DIR/expr-as-stmt.rs:25:11 |
| 134 | 134 | | |
| 135 | 135 | LL | { 3 } * 3 |
| 136 | | ^^^ | |
| 136 | | ^^^ can't be dereferenced | |
| 137 | 137 | | |
| 138 | 138 | help: parentheses are required to parse this as an expression |
| 139 | 139 | | |
tests/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr+2-2| ... | ... | @@ -2,13 +2,13 @@ error[E0614]: type `{integer}` cannot be dereferenced |
| 2 | 2 | --> $DIR/nested-binding-modes-ref.rs:4:5 |
| 3 | 3 | | |
| 4 | 4 | LL | *is_val; |
| 5 | | ^^^^^^^ | |
| 5 | | ^^^^^^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error[E0614]: type `{integer}` cannot be dereferenced |
| 8 | 8 | --> $DIR/nested-binding-modes-ref.rs:9:5 |
| 9 | 9 | | |
| 10 | 10 | LL | *is_val; |
| 11 | | ^^^^^^^ | |
| 11 | | ^^^^^^^ can't be dereferenced | |
| 12 | 12 | |
| 13 | 13 | error: aborting due to 2 previous errors |
| 14 | 14 |
tests/ui/reachable/expr_unary.stderr+1-1| ... | ... | @@ -2,7 +2,7 @@ error[E0614]: type `!` cannot be dereferenced |
| 2 | 2 | --> $DIR/expr_unary.rs:8:16 |
| 3 | 3 | | |
| 4 | 4 | LL | let x: ! = * { return; }; |
| 5 | | ^^^^^^^^^^^^^ | |
| 5 | | ^^^^^^^^^^^^^ can't be dereferenced | |
| 6 | 6 | |
| 7 | 7 | error: unreachable expression |
| 8 | 8 | --> $DIR/expr_unary.rs:8:16 |
tests/ui/type/type-check/missing_trait_impl.stderr+1-1| ... | ... | @@ -50,7 +50,7 @@ error[E0614]: type `T` cannot be dereferenced |
| 50 | 50 | --> $DIR/missing_trait_impl.rs:15:13 |
| 51 | 51 | | |
| 52 | 52 | LL | let y = *x; |
| 53 | | ^^ | |
| 53 | | ^^ can't be dereferenced | |
| 54 | 54 | |
| 55 | 55 | error: aborting due to 5 previous errors |
| 56 | 56 |