| author | bors <bors@rust-lang.org> 2025-06-24 10:22:30 UTC |
| committer | bors <bors@rust-lang.org> 2025-06-24 10:22:30 UTC |
| log | 36b21637e93b038453924d3c66821089e71d8baa |
| tree | e5abef64f88d9244a0394e45b105762d68ed275f |
| parent | e4b9d0141fdd210fcceebd2b67f7be113401c461 |
| parent | 7b864ac1905f0b118d2e4ca1beeede86ac91e5a1 |
Rollup of 9 pull requests
Successful merges:
- rust-lang/rust#140005 (Set MSG_NOSIGNAL for UnixStream)
- rust-lang/rust#140622 (compiletest: Improve diagnostics for line annotation mismatches)
- rust-lang/rust#142354 (Fixes firefox copy paste issue)
- rust-lang/rust#142695 (Port `#[rustc_skip_during_method_dispatch]` to the new attribute system)
- rust-lang/rust#142779 (Add note about `str::split` handling of no matches.)
- rust-lang/rust#142894 (phantom_variance_markers: fix identifier usage in macro)
- rust-lang/rust#142928 (Fix hang in --print=file-names in bootstrap)
- rust-lang/rust#142932 (rustdoc-json: Keep empty generic args if parenthesized)
- rust-lang/rust#142933 (Simplify root goal API of solver a bit)
r? `@ghost`
`@rustbot` modify labels: rollup56 files changed, 681 insertions(+), 236 deletions(-)
compiler/rustc_attr_data_structures/src/attributes.rs+3| ... | ... | @@ -259,6 +259,9 @@ pub enum AttributeKind { |
| 259 | 259 | /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). |
| 260 | 260 | Repr(ThinVec<(ReprAttr, Span)>), |
| 261 | 261 | |
| 262 | /// Represents `#[rustc_skip_during_method_dispatch]`. | |
| 263 | SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, | |
| 264 | ||
| 262 | 265 | /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. |
| 263 | 266 | Stability { |
| 264 | 267 | stability: Stability, |
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+7-7| ... | ... | @@ -50,8 +50,8 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser { |
| 50 | 50 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 51 | 51 | |
| 52 | 52 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { |
| 53 | if !args.no_args() { | |
| 54 | cx.expected_no_args(args.span().unwrap_or(cx.attr_span)); | |
| 53 | if let Err(span) = args.no_args() { | |
| 54 | cx.expected_no_args(span); | |
| 55 | 55 | return None; |
| 56 | 56 | } |
| 57 | 57 | |
| ... | ... | @@ -67,8 +67,8 @@ pub(crate) struct NakedParser { |
| 67 | 67 | impl<S: Stage> AttributeParser<S> for NakedParser { |
| 68 | 68 | const ATTRIBUTES: AcceptMapping<Self, S> = |
| 69 | 69 | &[(&[sym::naked], template!(Word), |this, cx, args| { |
| 70 | if !args.no_args() { | |
| 71 | cx.expected_no_args(args.span().unwrap_or(cx.attr_span)); | |
| 70 | if let Err(span) = args.no_args() { | |
| 71 | cx.expected_no_args(span); | |
| 72 | 72 | return; |
| 73 | 73 | } |
| 74 | 74 | |
| ... | ... | @@ -175,10 +175,10 @@ impl<S: Stage> SingleAttributeParser<S> for NoMangleParser { |
| 175 | 175 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 176 | 176 | |
| 177 | 177 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { |
| 178 | if !args.no_args() { | |
| 179 | cx.expected_no_args(args.span().unwrap_or(cx.attr_span)); | |
| 178 | if let Err(span) = args.no_args() { | |
| 179 | cx.expected_no_args(span); | |
| 180 | 180 | return None; |
| 181 | }; | |
| 181 | } | |
| 182 | 182 | |
| 183 | 183 | Some(AttributeKind::NoMangle(cx.attr_span)) |
| 184 | 184 | } |
compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs+8-4| ... | ... | @@ -14,8 +14,10 @@ impl<S: Stage> SingleAttributeParser<S> for AsPtrParser { |
| 14 | 14 | const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| 15 | 15 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 16 | 16 | |
| 17 | fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 18 | // FIXME: check that there's no args (this is currently checked elsewhere) | |
| 17 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 18 | if let Err(span) = args.no_args() { | |
| 19 | cx.expected_no_args(span); | |
| 20 | } | |
| 19 | 21 | Some(AttributeKind::AsPtr(cx.attr_span)) |
| 20 | 22 | } |
| 21 | 23 | } |
| ... | ... | @@ -27,8 +29,10 @@ impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser { |
| 27 | 29 | const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| 28 | 30 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 29 | 31 | |
| 30 | fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 31 | // FIXME: check that there's no args (this is currently checked elsewhere) | |
| 32 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 33 | if let Err(span) = args.no_args() { | |
| 34 | cx.expected_no_args(span); | |
| 35 | } | |
| 32 | 36 | Some(AttributeKind::PubTransparent(cx.attr_span)) |
| 33 | 37 | } |
| 34 | 38 | } |
compiler/rustc_attr_parsing/src/attributes/mod.rs+1| ... | ... | @@ -36,6 +36,7 @@ pub(crate) mod must_use; |
| 36 | 36 | pub(crate) mod repr; |
| 37 | 37 | pub(crate) mod semantics; |
| 38 | 38 | pub(crate) mod stability; |
| 39 | pub(crate) mod traits; | |
| 39 | 40 | pub(crate) mod transparency; |
| 40 | 41 | pub(crate) mod util; |
| 41 | 42 |
compiler/rustc_attr_parsing/src/attributes/semantics.rs+4-1| ... | ... | @@ -13,7 +13,10 @@ impl<S: Stage> SingleAttributeParser<S> for MayDangleParser { |
| 13 | 13 | const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; |
| 14 | 14 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 15 | 15 | |
| 16 | fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 16 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 17 | if let Err(span) = args.no_args() { | |
| 18 | cx.expected_no_args(span); | |
| 19 | } | |
| 17 | 20 | Some(AttributeKind::MayDangle(cx.attr_span)) |
| 18 | 21 | } |
| 19 | 22 | } |
compiler/rustc_attr_parsing/src/attributes/stability.rs+6-3| ... | ... | @@ -139,7 +139,10 @@ impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser { |
| 139 | 139 | const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore; |
| 140 | 140 | const TEMPLATE: AttributeTemplate = template!(Word); |
| 141 | 141 | |
| 142 | fn convert(_cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 142 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 143 | if let Err(span) = args.no_args() { | |
| 144 | cx.expected_no_args(span); | |
| 145 | } | |
| 143 | 146 | Some(AttributeKind::ConstStabilityIndirect) |
| 144 | 147 | } |
| 145 | 148 | } |
| ... | ... | @@ -361,8 +364,8 @@ pub(crate) fn parse_unstability<S: Stage>( |
| 361 | 364 | }; |
| 362 | 365 | } |
| 363 | 366 | Some(sym::soft) => { |
| 364 | if !param.args().no_args() { | |
| 365 | cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() }); | |
| 367 | if let Err(span) = args.no_args() { | |
| 368 | cx.emit_err(session_diagnostics::SoftNoArgs { span }); | |
| 366 | 369 | } |
| 367 | 370 | is_soft = true; |
| 368 | 371 | } |
compiler/rustc_attr_parsing/src/attributes/traits.rs created+54| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | use core::mem; | |
| 2 | ||
| 3 | use rustc_attr_data_structures::AttributeKind; | |
| 4 | use rustc_feature::{AttributeTemplate, template}; | |
| 5 | use rustc_span::{Symbol, sym}; | |
| 6 | ||
| 7 | use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; | |
| 8 | use crate::context::{AcceptContext, Stage}; | |
| 9 | use crate::parser::ArgParser; | |
| 10 | ||
| 11 | pub(crate) struct SkipDuringMethodDispatchParser; | |
| 12 | ||
| 13 | impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser { | |
| 14 | const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; | |
| 15 | const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; | |
| 16 | const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; | |
| 17 | ||
| 18 | const TEMPLATE: AttributeTemplate = template!(List: "array, boxed_slice"); | |
| 19 | ||
| 20 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { | |
| 21 | let mut array = false; | |
| 22 | let mut boxed_slice = false; | |
| 23 | let Some(args) = args.list() else { | |
| 24 | cx.expected_list(cx.attr_span); | |
| 25 | return None; | |
| 26 | }; | |
| 27 | if args.is_empty() { | |
| 28 | cx.expected_at_least_one_argument(args.span); | |
| 29 | return None; | |
| 30 | } | |
| 31 | for arg in args.mixed() { | |
| 32 | let Some(arg) = arg.meta_item() else { | |
| 33 | cx.unexpected_literal(arg.span()); | |
| 34 | continue; | |
| 35 | }; | |
| 36 | if let Err(span) = arg.args().no_args() { | |
| 37 | cx.expected_no_args(span); | |
| 38 | } | |
| 39 | let path = arg.path(); | |
| 40 | let (key, skip): (Symbol, &mut bool) = match path.word_sym() { | |
| 41 | Some(key @ sym::array) => (key, &mut array), | |
| 42 | Some(key @ sym::boxed_slice) => (key, &mut boxed_slice), | |
| 43 | _ => { | |
| 44 | cx.expected_specific_argument(path.span(), vec!["array", "boxed_slice"]); | |
| 45 | continue; | |
| 46 | } | |
| 47 | }; | |
| 48 | if mem::replace(skip, true) { | |
| 49 | cx.duplicate_key(arg.span(), key); | |
| 50 | } | |
| 51 | } | |
| 52 | Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span }) | |
| 53 | } | |
| 54 | } |
compiler/rustc_attr_parsing/src/context.rs+12| ... | ... | @@ -26,6 +26,7 @@ use crate::attributes::semantics::MayDangleParser; |
| 26 | 26 | use crate::attributes::stability::{ |
| 27 | 27 | BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, |
| 28 | 28 | }; |
| 29 | use crate::attributes::traits::SkipDuringMethodDispatchParser; | |
| 29 | 30 | use crate::attributes::transparency::TransparencyParser; |
| 30 | 31 | use crate::attributes::{AttributeParser as _, Combine, Single}; |
| 31 | 32 | use crate::parser::{ArgParser, MetaItemParser, PathParser}; |
| ... | ... | @@ -119,6 +120,7 @@ attribute_parsers!( |
| 119 | 120 | Single<OptimizeParser>, |
| 120 | 121 | Single<PubTransparentParser>, |
| 121 | 122 | Single<RustcForceInlineParser>, |
| 123 | Single<SkipDuringMethodDispatchParser>, | |
| 122 | 124 | Single<TransparencyParser>, |
| 123 | 125 | // tidy-alphabetical-end |
| 124 | 126 | ]; |
| ... | ... | @@ -325,6 +327,16 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { |
| 325 | 327 | }) |
| 326 | 328 | } |
| 327 | 329 | |
| 330 | pub(crate) fn expected_at_least_one_argument(&self, span: Span) -> ErrorGuaranteed { | |
| 331 | self.emit_err(AttributeParseError { | |
| 332 | span, | |
| 333 | attr_span: self.attr_span, | |
| 334 | template: self.template.clone(), | |
| 335 | attribute: self.attr_path.clone(), | |
| 336 | reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument, | |
| 337 | }) | |
| 338 | } | |
| 339 | ||
| 328 | 340 | pub(crate) fn expected_specific_argument( |
| 329 | 341 | &self, |
| 330 | 342 | span: Span, |
compiler/rustc_attr_parsing/src/parser.rs+9-3| ... | ... | @@ -169,9 +169,15 @@ impl<'a> ArgParser<'a> { |
| 169 | 169 | } |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | /// Asserts that there are no arguments | |
| 173 | pub fn no_args(&self) -> bool { | |
| 174 | matches!(self, Self::NoArgs) | |
| 172 | /// Assert that there were no args. | |
| 173 | /// If there were, get a span to the arguments | |
| 174 | /// (to pass to [`AcceptContext::expected_no_args`](crate::context::AcceptContext::expected_no_args)). | |
| 175 | pub fn no_args(&self) -> Result<(), Span> { | |
| 176 | match self { | |
| 177 | Self::NoArgs => Ok(()), | |
| 178 | Self::List(args) => Err(args.span), | |
| 179 | Self::NameValue(args) => Err(args.eq_span.to(args.value_span)), | |
| 180 | } | |
| 175 | 181 | } |
| 176 | 182 | } |
| 177 | 183 |
compiler/rustc_attr_parsing/src/session_diagnostics.rs+4| ... | ... | @@ -496,6 +496,7 @@ pub(crate) struct NakedFunctionIncompatibleAttribute { |
| 496 | 496 | pub(crate) enum AttributeParseErrorReason { |
| 497 | 497 | ExpectedNoArgs, |
| 498 | 498 | ExpectedStringLiteral { byte_string: Option<Span> }, |
| 499 | ExpectedAtLeastOneArgument, | |
| 499 | 500 | ExpectedSingleArgument, |
| 500 | 501 | ExpectedList, |
| 501 | 502 | UnexpectedLiteral, |
| ... | ... | @@ -539,6 +540,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { |
| 539 | 540 | diag.span_label(self.span, "expected a single argument here"); |
| 540 | 541 | diag.code(E0805); |
| 541 | 542 | } |
| 543 | AttributeParseErrorReason::ExpectedAtLeastOneArgument => { | |
| 544 | diag.span_label(self.span, "expected at least 1 argument here"); | |
| 545 | } | |
| 542 | 546 | AttributeParseErrorReason::ExpectedList => { |
| 543 | 547 | diag.span_label(self.span, "expected this to be a list"); |
| 544 | 548 | } |
compiler/rustc_feature/src/builtin_attrs.rs+1-1| ... | ... | @@ -1083,7 +1083,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ |
| 1083 | 1083 | "the `#[rustc_main]` attribute is used internally to specify test entry point function", |
| 1084 | 1084 | ), |
| 1085 | 1085 | rustc_attr!( |
| 1086 | rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), WarnFollowing, | |
| 1086 | rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), ErrorFollowing, | |
| 1087 | 1087 | EncodeCrossCrate::No, |
| 1088 | 1088 | "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ |
| 1089 | 1089 | from method dispatch when the receiver is of the following type, for compatibility in \ |
compiler/rustc_hir_analysis/src/collect.rs+6-16| ... | ... | @@ -21,6 +21,7 @@ use std::ops::Bound; |
| 21 | 21 | |
| 22 | 22 | use rustc_abi::ExternAbi; |
| 23 | 23 | use rustc_ast::Recovered; |
| 24 | use rustc_attr_data_structures::{AttributeKind, find_attr}; | |
| 24 | 25 | use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; |
| 25 | 26 | use rustc_data_structures::unord::UnordMap; |
| 26 | 27 | use rustc_errors::{ |
| ... | ... | @@ -1151,22 +1152,11 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { |
| 1151 | 1152 | let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); |
| 1152 | 1153 | let is_fundamental = tcx.has_attr(def_id, sym::fundamental); |
| 1153 | 1154 | |
| 1154 | // FIXME: We could probably do way better attribute validation here. | |
| 1155 | let mut skip_array_during_method_dispatch = false; | |
| 1156 | let mut skip_boxed_slice_during_method_dispatch = false; | |
| 1157 | for attr in tcx.get_attrs(def_id, sym::rustc_skip_during_method_dispatch) { | |
| 1158 | if let Some(lst) = attr.meta_item_list() { | |
| 1159 | for item in lst { | |
| 1160 | if let Some(ident) = item.ident() { | |
| 1161 | match ident.as_str() { | |
| 1162 | "array" => skip_array_during_method_dispatch = true, | |
| 1163 | "boxed_slice" => skip_boxed_slice_during_method_dispatch = true, | |
| 1164 | _ => (), | |
| 1165 | } | |
| 1166 | } | |
| 1167 | } | |
| 1168 | } | |
| 1169 | } | |
| 1155 | let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( | |
| 1156 | tcx.get_all_attrs(def_id), | |
| 1157 | AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice] | |
| 1158 | ) | |
| 1159 | .unwrap_or([false; 2]); | |
| 1170 | 1160 | |
| 1171 | 1161 | let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { |
| 1172 | 1162 | ty::trait_def::TraitSpecializationKind::Marker |
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+22-25| ... | ... | @@ -147,13 +147,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate { |
| 147 | 147 | fn evaluate_root_goal( |
| 148 | 148 | &self, |
| 149 | 149 | goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>, |
| 150 | generate_proof_tree: GenerateProofTree, | |
| 151 | 150 | span: <Self::Interner as Interner>::Span, |
| 152 | 151 | stalled_on: Option<GoalStalledOn<Self::Interner>>, |
| 153 | ) -> ( | |
| 154 | Result<GoalEvaluation<Self::Interner>, NoSolution>, | |
| 155 | Option<inspect::GoalEvaluation<Self::Interner>>, | |
| 156 | ); | |
| 152 | ) -> Result<GoalEvaluation<Self::Interner>, NoSolution>; | |
| 157 | 153 | |
| 158 | 154 | /// Check whether evaluating `goal` with a depth of `root_depth` may |
| 159 | 155 | /// succeed. This only returns `false` if the goal is guaranteed to |
| ... | ... | @@ -170,17 +166,16 @@ pub trait SolverDelegateEvalExt: SolverDelegate { |
| 170 | 166 | |
| 171 | 167 | // FIXME: This is only exposed because we need to use it in `analyse.rs` |
| 172 | 168 | // which is not yet uplifted. Once that's done, we should remove this. |
| 173 | fn evaluate_root_goal_raw( | |
| 169 | fn evaluate_root_goal_for_proof_tree( | |
| 174 | 170 | &self, |
| 175 | 171 | goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>, |
| 176 | generate_proof_tree: GenerateProofTree, | |
| 177 | stalled_on: Option<GoalStalledOn<Self::Interner>>, | |
| 172 | span: <Self::Interner as Interner>::Span, | |
| 178 | 173 | ) -> ( |
| 179 | 174 | Result< |
| 180 | 175 | (NestedNormalizationGoals<Self::Interner>, GoalEvaluation<Self::Interner>), |
| 181 | 176 | NoSolution, |
| 182 | 177 | >, |
| 183 | Option<inspect::GoalEvaluation<Self::Interner>>, | |
| 178 | inspect::GoalEvaluation<Self::Interner>, | |
| 184 | 179 | ); |
| 185 | 180 | } |
| 186 | 181 | |
| ... | ... | @@ -193,13 +188,17 @@ where |
| 193 | 188 | fn evaluate_root_goal( |
| 194 | 189 | &self, |
| 195 | 190 | goal: Goal<I, I::Predicate>, |
| 196 | generate_proof_tree: GenerateProofTree, | |
| 197 | 191 | span: I::Span, |
| 198 | 192 | stalled_on: Option<GoalStalledOn<I>>, |
| 199 | ) -> (Result<GoalEvaluation<I>, NoSolution>, Option<inspect::GoalEvaluation<I>>) { | |
| 200 | EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, span, |ecx| { | |
| 201 | ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on) | |
| 202 | }) | |
| 193 | ) -> Result<GoalEvaluation<I>, NoSolution> { | |
| 194 | EvalCtxt::enter_root( | |
| 195 | self, | |
| 196 | self.cx().recursion_limit(), | |
| 197 | GenerateProofTree::No, | |
| 198 | span, | |
| 199 | |ecx| ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on), | |
| 200 | ) | |
| 201 | .0 | |
| 203 | 202 | } |
| 204 | 203 | |
| 205 | 204 | fn root_goal_may_hold_with_depth( |
| ... | ... | @@ -217,24 +216,22 @@ where |
| 217 | 216 | } |
| 218 | 217 | |
| 219 | 218 | #[instrument(level = "debug", skip(self))] |
| 220 | fn evaluate_root_goal_raw( | |
| 219 | fn evaluate_root_goal_for_proof_tree( | |
| 221 | 220 | &self, |
| 222 | 221 | goal: Goal<I, I::Predicate>, |
| 223 | generate_proof_tree: GenerateProofTree, | |
| 224 | stalled_on: Option<GoalStalledOn<I>>, | |
| 222 | span: I::Span, | |
| 225 | 223 | ) -> ( |
| 226 | 224 | Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolution>, |
| 227 | Option<inspect::GoalEvaluation<I>>, | |
| 225 | inspect::GoalEvaluation<I>, | |
| 228 | 226 | ) { |
| 229 | EvalCtxt::enter_root( | |
| 227 | let (result, proof_tree) = EvalCtxt::enter_root( | |
| 230 | 228 | self, |
| 231 | 229 | self.cx().recursion_limit(), |
| 232 | generate_proof_tree, | |
| 233 | I::Span::dummy(), | |
| 234 | |ecx| { | |
| 235 | ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on) | |
| 236 | }, | |
| 237 | ) | |
| 230 | GenerateProofTree::Yes, | |
| 231 | span, | |
| 232 | |ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, None), | |
| 233 | ); | |
| 234 | (result, proof_tree.unwrap()) | |
| 238 | 235 | } |
| 239 | 236 | } |
| 240 | 237 |
compiler/rustc_parse/src/validate_attr.rs+7| ... | ... | @@ -286,13 +286,20 @@ fn emit_malformed_attribute( |
| 286 | 286 | if matches!( |
| 287 | 287 | name, |
| 288 | 288 | sym::inline |
| 289 | | sym::may_dangle | |
| 290 | | sym::rustc_as_ptr | |
| 291 | | sym::rustc_pub_transparent | |
| 292 | | sym::rustc_const_stable_indirect | |
| 289 | 293 | | sym::rustc_force_inline |
| 290 | 294 | | sym::rustc_confusables |
| 295 | | sym::rustc_skip_during_method_dispatch | |
| 291 | 296 | | sym::repr |
| 292 | 297 | | sym::align |
| 293 | 298 | | sym::deprecated |
| 294 | 299 | | sym::optimize |
| 295 | 300 | | sym::cold |
| 301 | | sym::naked | |
| 302 | | sym::no_mangle | |
| 296 | 303 | | sym::must_use |
| 297 | 304 | ) { |
| 298 | 305 | return; |
compiler/rustc_passes/src/check_attr.rs+9-6| ... | ... | @@ -118,6 +118,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 118 | 118 | for attr in attrs { |
| 119 | 119 | let mut style = None; |
| 120 | 120 | match attr { |
| 121 | Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch { | |
| 122 | span: attr_span, | |
| 123 | .. | |
| 124 | }) => { | |
| 125 | self.check_must_be_applied_to_trait(*attr_span, span, target); | |
| 126 | } | |
| 121 | 127 | Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { |
| 122 | 128 | self.check_confusables(*first_span, target); |
| 123 | 129 | } |
| ... | ... | @@ -250,7 +256,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 250 | 256 | | [sym::rustc_must_implement_one_of, ..] |
| 251 | 257 | | [sym::rustc_deny_explicit_impl, ..] |
| 252 | 258 | | [sym::rustc_do_not_implement_via_object, ..] |
| 253 | | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target), | |
| 259 | | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), | |
| 254 | 260 | [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), |
| 255 | 261 | [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), |
| 256 | 262 | [sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), |
| ... | ... | @@ -1805,14 +1811,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { |
| 1805 | 1811 | } |
| 1806 | 1812 | |
| 1807 | 1813 | /// Checks if the attribute is applied to a trait. |
| 1808 | fn check_must_be_applied_to_trait(&self, attr: &Attribute, span: Span, target: Target) { | |
| 1814 | fn check_must_be_applied_to_trait(&self, attr_span: Span, defn_span: Span, target: Target) { | |
| 1809 | 1815 | match target { |
| 1810 | 1816 | Target::Trait => {} |
| 1811 | 1817 | _ => { |
| 1812 | self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { | |
| 1813 | attr_span: attr.span(), | |
| 1814 | defn_span: span, | |
| 1815 | }); | |
| 1818 | self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span }); | |
| 1816 | 1819 | } |
| 1817 | 1820 | } |
| 1818 | 1821 | } |
compiler/rustc_span/src/symbol.rs+1| ... | ... | @@ -577,6 +577,7 @@ symbols! { |
| 577 | 577 | box_new, |
| 578 | 578 | box_patterns, |
| 579 | 579 | box_syntax, |
| 580 | boxed_slice, | |
| 580 | 581 | bpf_target_feature, |
| 581 | 582 | braced_empty_structs, |
| 582 | 583 | branch, |
compiler/rustc_trait_selection/src/solve/fulfill.rs+7-17| ... | ... | @@ -14,7 +14,7 @@ use rustc_middle::ty::{ |
| 14 | 14 | }; |
| 15 | 15 | use rustc_next_trait_solver::delegate::SolverDelegate as _; |
| 16 | 16 | use rustc_next_trait_solver::solve::{ |
| 17 | GenerateProofTree, GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _, | |
| 17 | GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _, | |
| 18 | 18 | }; |
| 19 | 19 | use rustc_span::Span; |
| 20 | 20 | use thin_vec::ThinVec; |
| ... | ... | @@ -106,14 +106,11 @@ impl<'tcx> ObligationStorage<'tcx> { |
| 106 | 106 | self.overflowed.extend( |
| 107 | 107 | ExtractIf::new(&mut self.pending, |(o, stalled_on)| { |
| 108 | 108 | let goal = o.as_goal(); |
| 109 | let result = <&SolverDelegate<'tcx>>::from(infcx) | |
| 110 | .evaluate_root_goal( | |
| 111 | goal, | |
| 112 | GenerateProofTree::No, | |
| 113 | o.cause.span, | |
| 114 | stalled_on.take(), | |
| 115 | ) | |
| 116 | .0; | |
| 109 | let result = <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal( | |
| 110 | goal, | |
| 111 | o.cause.span, | |
| 112 | stalled_on.take(), | |
| 113 | ); | |
| 117 | 114 | matches!(result, Ok(GoalEvaluation { has_changed: HasChanged::Yes, .. })) |
| 118 | 115 | }) |
| 119 | 116 | .map(|(o, _)| o), |
| ... | ... | @@ -207,14 +204,7 @@ where |
| 207 | 204 | continue; |
| 208 | 205 | } |
| 209 | 206 | |
| 210 | let result = delegate | |
| 211 | .evaluate_root_goal( | |
| 212 | goal, | |
| 213 | GenerateProofTree::No, | |
| 214 | obligation.cause.span, | |
| 215 | stalled_on, | |
| 216 | ) | |
| 217 | .0; | |
| 207 | let result = delegate.evaluate_root_goal(goal, obligation.cause.span, stalled_on); | |
| 218 | 208 | self.inspect_evaluated_obligation(infcx, &obligation, &result); |
| 219 | 209 | let GoalEvaluation { certainty, has_changed, stalled_on } = match result { |
| 220 | 210 | Ok(result) => result, |
compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs+6-12| ... | ... | @@ -11,9 +11,7 @@ use rustc_middle::traits::query::NoSolution; |
| 11 | 11 | use rustc_middle::ty::error::{ExpectedFound, TypeError}; |
| 12 | 12 | use rustc_middle::ty::{self, Ty, TyCtxt}; |
| 13 | 13 | use rustc_middle::{bug, span_bug}; |
| 14 | use rustc_next_trait_solver::solve::{ | |
| 15 | GenerateProofTree, GoalEvaluation, SolverDelegateEvalExt as _, | |
| 16 | }; | |
| 14 | use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _}; | |
| 17 | 15 | use tracing::{instrument, trace}; |
| 18 | 16 | |
| 19 | 17 | use crate::solve::delegate::SolverDelegate; |
| ... | ... | @@ -90,15 +88,11 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>( |
| 90 | 88 | root_obligation: PredicateObligation<'tcx>, |
| 91 | 89 | ) -> FulfillmentError<'tcx> { |
| 92 | 90 | let (code, refine_obligation) = infcx.probe(|_| { |
| 93 | match <&SolverDelegate<'tcx>>::from(infcx) | |
| 94 | .evaluate_root_goal( | |
| 95 | root_obligation.as_goal(), | |
| 96 | GenerateProofTree::No, | |
| 97 | root_obligation.cause.span, | |
| 98 | None, | |
| 99 | ) | |
| 100 | .0 | |
| 101 | { | |
| 91 | match <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal( | |
| 92 | root_obligation.as_goal(), | |
| 93 | root_obligation.cause.span, | |
| 94 | None, | |
| 95 | ) { | |
| 102 | 96 | Ok(GoalEvaluation { certainty: Certainty::Maybe(MaybeCause::Ambiguity), .. }) => { |
| 103 | 97 | (FulfillmentErrorCode::Ambiguity { overflow: None }, true) |
| 104 | 98 | } |
compiler/rustc_trait_selection/src/solve/inspect/analyse.rs+6-14| ... | ... | @@ -20,7 +20,7 @@ use rustc_middle::ty::{TyCtxt, VisitorResult, try_visit}; |
| 20 | 20 | use rustc_middle::{bug, ty}; |
| 21 | 21 | use rustc_next_trait_solver::resolve::eager_resolve_vars; |
| 22 | 22 | use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state}; |
| 23 | use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _}; | |
| 23 | use rustc_next_trait_solver::solve::{MaybeCause, SolverDelegateEvalExt as _}; | |
| 24 | 24 | use rustc_span::Span; |
| 25 | 25 | use tracing::instrument; |
| 26 | 26 | |
| ... | ... | @@ -248,9 +248,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { |
| 248 | 248 | // considering the constrained RHS, and pass the resulting certainty to |
| 249 | 249 | // `InspectGoal::new` so that the goal has the right result (and maintains |
| 250 | 250 | // the impression that we don't do this normalizes-to infer hack at all). |
| 251 | let (nested, proof_tree) = | |
| 252 | infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes, None); | |
| 253 | let proof_tree = proof_tree.unwrap(); | |
| 251 | let (nested, proof_tree) = infcx.evaluate_root_goal_for_proof_tree(goal, span); | |
| 254 | 252 | let nested_goals_result = nested.and_then(|(nested, _)| { |
| 255 | 253 | normalizes_to_term_hack.constrain_and( |
| 256 | 254 | infcx, |
| ... | ... | @@ -284,9 +282,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { |
| 284 | 282 | // into another candidate who ends up with different inference |
| 285 | 283 | // constraints, we get an ICE if we already applied the constraints |
| 286 | 284 | // from the chosen candidate. |
| 287 | let proof_tree = infcx | |
| 288 | .probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes, span, None).1) | |
| 289 | .unwrap(); | |
| 285 | let proof_tree = | |
| 286 | infcx.probe(|_| infcx.evaluate_root_goal_for_proof_tree(goal, span).1); | |
| 290 | 287 | InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source) |
| 291 | 288 | } |
| 292 | 289 | } |
| ... | ... | @@ -488,13 +485,8 @@ impl<'tcx> InferCtxt<'tcx> { |
| 488 | 485 | depth: usize, |
| 489 | 486 | visitor: &mut V, |
| 490 | 487 | ) -> V::Result { |
| 491 | let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self).evaluate_root_goal( | |
| 492 | goal, | |
| 493 | GenerateProofTree::Yes, | |
| 494 | visitor.span(), | |
| 495 | None, | |
| 496 | ); | |
| 497 | let proof_tree = proof_tree.unwrap(); | |
| 488 | let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self) | |
| 489 | .evaluate_root_goal_for_proof_tree(goal, visitor.span()); | |
| 498 | 490 | visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc)) |
| 499 | 491 | } |
| 500 | 492 | } |
library/core/src/marker/variance.rs+1-1| ... | ... | @@ -18,7 +18,7 @@ macro_rules! phantom_type { |
| 18 | 18 | pub struct $name:ident <$t:ident> ($($inner:tt)*); |
| 19 | 19 | )*) => {$( |
| 20 | 20 | $(#[$attr])* |
| 21 | pub struct $name<$t>($($inner)*) where T: ?Sized; | |
| 21 | pub struct $name<$t>($($inner)*) where $t: ?Sized; | |
| 22 | 22 | |
| 23 | 23 | impl<T> $name<T> |
| 24 | 24 | where T: ?Sized |
library/core/src/str/mod.rs+6| ... | ... | @@ -1495,6 +1495,9 @@ impl str { |
| 1495 | 1495 | /// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a |
| 1496 | 1496 | /// function or closure that determines if a character matches. |
| 1497 | 1497 | /// |
| 1498 | /// If there are no matches the full string slice is returned as the only | |
| 1499 | /// item in the iterator. | |
| 1500 | /// | |
| 1498 | 1501 | /// [`char`]: prim@char |
| 1499 | 1502 | /// [pattern]: self::pattern |
| 1500 | 1503 | /// |
| ... | ... | @@ -1526,6 +1529,9 @@ impl str { |
| 1526 | 1529 | /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect(); |
| 1527 | 1530 | /// assert_eq!(v, ["lion", "tiger", "leopard"]); |
| 1528 | 1531 | /// |
| 1532 | /// let v: Vec<&str> = "AABBCC".split("DD").collect(); | |
| 1533 | /// assert_eq!(v, ["AABBCC"]); | |
| 1534 | /// | |
| 1529 | 1535 | /// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect(); |
| 1530 | 1536 | /// assert_eq!(v, ["abc", "def", "ghi"]); |
| 1531 | 1537 | /// |
library/std/src/net/tcp.rs+6| ... | ... | @@ -53,6 +53,12 @@ use crate::time::Duration; |
| 53 | 53 | /// Ok(()) |
| 54 | 54 | /// } // the stream is closed here |
| 55 | 55 | /// ``` |
| 56 | /// | |
| 57 | /// # Platform-specific Behavior | |
| 58 | /// | |
| 59 | /// On Unix, writes to the underlying socket in `SOCK_STREAM` mode are made with | |
| 60 | /// `MSG_NOSIGNAL` flag. This suppresses the emission of the `SIGPIPE` signal when writing | |
| 61 | /// to disconnected socket. In some cases, getting a `SIGPIPE` would trigger process termination. | |
| 56 | 62 | #[stable(feature = "rust1", since = "1.0.0")] |
| 57 | 63 | pub struct TcpStream(net_imp::TcpStream); |
| 58 | 64 |
library/std/src/os/unix/net/stream.rs+22-1| ... | ... | @@ -1,3 +1,18 @@ |
| 1 | cfg_if::cfg_if! { | |
| 2 | if #[cfg(any( | |
| 3 | target_os = "linux", target_os = "android", | |
| 4 | target_os = "hurd", | |
| 5 | target_os = "dragonfly", target_os = "freebsd", | |
| 6 | target_os = "openbsd", target_os = "netbsd", | |
| 7 | target_os = "solaris", target_os = "illumos", | |
| 8 | target_os = "haiku", target_os = "nto", | |
| 9 | target_os = "cygwin"))] { | |
| 10 | use libc::MSG_NOSIGNAL; | |
| 11 | } else { | |
| 12 | const MSG_NOSIGNAL: core::ffi::c_int = 0x0; | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 1 | 16 | use super::{SocketAddr, sockaddr_un}; |
| 2 | 17 | #[cfg(any(doc, target_os = "android", target_os = "linux"))] |
| 3 | 18 | use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to}; |
| ... | ... | @@ -41,6 +56,12 @@ use crate::time::Duration; |
| 41 | 56 | /// Ok(()) |
| 42 | 57 | /// } |
| 43 | 58 | /// ``` |
| 59 | /// | |
| 60 | /// # `SIGPIPE` | |
| 61 | /// | |
| 62 | /// Writes to the underlying socket in `SOCK_STREAM` mode are made with `MSG_NOSIGNAL` flag. | |
| 63 | /// This suppresses the emission of the `SIGPIPE` signal when writing to disconnected socket. | |
| 64 | /// In some cases getting a `SIGPIPE` would trigger process termination. | |
| 44 | 65 | #[stable(feature = "unix_socket", since = "1.10.0")] |
| 45 | 66 | pub struct UnixStream(pub(super) Socket); |
| 46 | 67 | |
| ... | ... | @@ -633,7 +654,7 @@ impl io::Write for UnixStream { |
| 633 | 654 | #[stable(feature = "unix_socket", since = "1.10.0")] |
| 634 | 655 | impl<'a> io::Write for &'a UnixStream { |
| 635 | 656 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| 636 | self.0.write(buf) | |
| 657 | self.0.send_with_flags(buf, MSG_NOSIGNAL) | |
| 637 | 658 | } |
| 638 | 659 | |
| 639 | 660 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
library/std/src/sys/net/connection/socket/unix.rs+8| ... | ... | @@ -281,6 +281,14 @@ impl Socket { |
| 281 | 281 | self.0.duplicate().map(Socket) |
| 282 | 282 | } |
| 283 | 283 | |
| 284 | pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result<usize> { | |
| 285 | let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t; | |
| 286 | let ret = cvt(unsafe { | |
| 287 | libc::send(self.as_raw_fd(), buf.as_ptr() as *const c_void, len, flags) | |
| 288 | })?; | |
| 289 | Ok(ret as usize) | |
| 290 | } | |
| 291 | ||
| 284 | 292 | fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { |
| 285 | 293 | let ret = cvt(unsafe { |
| 286 | 294 | libc::recv( |
src/bootstrap/src/core/builder/cargo.rs+1| ... | ... | @@ -683,6 +683,7 @@ impl Builder<'_> { |
| 683 | 683 | .arg("--print=file-names") |
| 684 | 684 | .arg("--crate-type=proc-macro") |
| 685 | 685 | .arg("-") |
| 686 | .stdin(std::process::Stdio::null()) | |
| 686 | 687 | .run_capture(self) |
| 687 | 688 | .stderr(); |
| 688 | 689 |
src/bootstrap/src/utils/exec.rs+5| ... | ... | @@ -119,6 +119,11 @@ impl<'a> BootstrapCommand { |
| 119 | 119 | self |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | pub fn stdin(&mut self, stdin: std::process::Stdio) -> &mut Self { | |
| 123 | self.command.stdin(stdin); | |
| 124 | self | |
| 125 | } | |
| 126 | ||
| 122 | 127 | #[must_use] |
| 123 | 128 | pub fn delay_failure(self) -> Self { |
| 124 | 129 | Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self } |
src/librustdoc/html/static/js/main.js+29-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // Local js definitions: |
| 2 | 2 | /* global addClass, getSettingValue, hasClass, updateLocalStorage */ |
| 3 | /* global onEachLazy, removeClass, getVar */ | |
| 3 | /* global onEachLazy, removeClass, getVar, nonnull */ | |
| 4 | 4 | |
| 5 | 5 | "use strict"; |
| 6 | 6 | |
| ... | ... | @@ -2138,3 +2138,31 @@ function preLoadCss(cssUrl) { |
| 2138 | 2138 | elem.addEventListener("click", showHideCodeExampleButtons); |
| 2139 | 2139 | }); |
| 2140 | 2140 | }()); |
| 2141 | ||
| 2142 | // This section is a bugfix for firefox: when copying text with `user-select: none`, it adds | |
| 2143 | // extra backline characters. | |
| 2144 | // | |
| 2145 | // Rustdoc issue: Workaround for https://github.com/rust-lang/rust/issues/141464 | |
| 2146 | // Firefox issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1273836 | |
| 2147 | (function() { | |
| 2148 | document.body.addEventListener("copy", event => { | |
| 2149 | let target = nonnull(event.target); | |
| 2150 | let isInsideCode = false; | |
| 2151 | while (target && target !== document.body) { | |
| 2152 | // @ts-expect-error | |
| 2153 | if (target.tagName === "CODE") { | |
| 2154 | isInsideCode = true; | |
| 2155 | break; | |
| 2156 | } | |
| 2157 | // @ts-expect-error | |
| 2158 | target = target.parentElement; | |
| 2159 | } | |
| 2160 | if (!isInsideCode) { | |
| 2161 | return; | |
| 2162 | } | |
| 2163 | const selection = document.getSelection(); | |
| 2164 | // @ts-expect-error | |
| 2165 | nonnull(event.clipboardData).setData("text/plain", selection.toString()); | |
| 2166 | event.preventDefault(); | |
| 2167 | }); | |
| 2168 | }()); |
src/librustdoc/json/conversions.rs+16-13| ... | ... | @@ -194,22 +194,25 @@ impl FromClean<attrs::Deprecation> for Deprecation { |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | impl FromClean<clean::GenericArgs> for Option<Box<GenericArgs>> { |
| 197 | fn from_clean(args: &clean::GenericArgs, renderer: &JsonRenderer<'_>) -> Self { | |
| 197 | fn from_clean(generic_args: &clean::GenericArgs, renderer: &JsonRenderer<'_>) -> Self { | |
| 198 | 198 | use clean::GenericArgs::*; |
| 199 | if args.is_empty() { | |
| 200 | return None; | |
| 201 | } | |
| 202 | Some(Box::new(match args { | |
| 203 | AngleBracketed { args, constraints } => GenericArgs::AngleBracketed { | |
| 204 | args: args.into_json(renderer), | |
| 205 | constraints: constraints.into_json(renderer), | |
| 206 | }, | |
| 207 | Parenthesized { inputs, output } => GenericArgs::Parenthesized { | |
| 199 | match generic_args { | |
| 200 | AngleBracketed { args, constraints } => { | |
| 201 | if generic_args.is_empty() { | |
| 202 | None | |
| 203 | } else { | |
| 204 | Some(Box::new(GenericArgs::AngleBracketed { | |
| 205 | args: args.into_json(renderer), | |
| 206 | constraints: constraints.into_json(renderer), | |
| 207 | })) | |
| 208 | } | |
| 209 | } | |
| 210 | Parenthesized { inputs, output } => Some(Box::new(GenericArgs::Parenthesized { | |
| 208 | 211 | inputs: inputs.into_json(renderer), |
| 209 | 212 | output: output.into_json(renderer), |
| 210 | }, | |
| 211 | ReturnTypeNotation => GenericArgs::ReturnTypeNotation, | |
| 212 | })) | |
| 213 | })), | |
| 214 | ReturnTypeNotation => Some(Box::new(GenericArgs::ReturnTypeNotation)), | |
| 215 | } | |
| 213 | 216 | } |
| 214 | 217 | } |
| 215 | 218 |
src/tools/compiletest/src/errors.rs+23-23| ... | ... | @@ -16,6 +16,8 @@ pub enum ErrorKind { |
| 16 | 16 | Suggestion, |
| 17 | 17 | Warning, |
| 18 | 18 | Raw, |
| 19 | /// Used for better recovery and diagnostics in compiletest. | |
| 20 | Unknown, | |
| 19 | 21 | } |
| 20 | 22 | |
| 21 | 23 | impl ErrorKind { |
| ... | ... | @@ -31,21 +33,25 @@ impl ErrorKind { |
| 31 | 33 | |
| 32 | 34 | /// Either the canonical uppercase string, or some additional versions for compatibility. |
| 33 | 35 | /// FIXME: consider keeping only the canonical versions here. |
| 34 | pub fn from_user_str(s: &str) -> ErrorKind { | |
| 35 | match s { | |
| 36 | fn from_user_str(s: &str) -> Option<ErrorKind> { | |
| 37 | Some(match s { | |
| 36 | 38 | "HELP" | "help" => ErrorKind::Help, |
| 37 | 39 | "ERROR" | "error" => ErrorKind::Error, |
| 38 | // `MONO_ITEM` makes annotations in `codegen-units` tests syntactically correct, | |
| 39 | // but those tests never use the error kind later on. | |
| 40 | "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note, | |
| 40 | "NOTE" | "note" => ErrorKind::Note, | |
| 41 | 41 | "SUGGESTION" => ErrorKind::Suggestion, |
| 42 | 42 | "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning, |
| 43 | 43 | "RAW" => ErrorKind::Raw, |
| 44 | _ => panic!( | |
| 44 | _ => return None, | |
| 45 | }) | |
| 46 | } | |
| 47 | ||
| 48 | pub fn expect_from_user_str(s: &str) -> ErrorKind { | |
| 49 | ErrorKind::from_user_str(s).unwrap_or_else(|| { | |
| 50 | panic!( | |
| 45 | 51 | "unexpected diagnostic kind `{s}`, expected \ |
| 46 | `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`" | |
| 47 | ), | |
| 48 | } | |
| 52 | `ERROR`, `WARN`, `NOTE`, `HELP`, `SUGGESTION` or `RAW`" | |
| 53 | ) | |
| 54 | }) | |
| 49 | 55 | } |
| 50 | 56 | } |
| 51 | 57 | |
| ... | ... | @@ -58,6 +64,7 @@ impl fmt::Display for ErrorKind { |
| 58 | 64 | ErrorKind::Suggestion => write!(f, "SUGGESTION"), |
| 59 | 65 | ErrorKind::Warning => write!(f, "WARN"), |
| 60 | 66 | ErrorKind::Raw => write!(f, "RAW"), |
| 67 | ErrorKind::Unknown => write!(f, "UNKNOWN"), | |
| 61 | 68 | } |
| 62 | 69 | } |
| 63 | 70 | } |
| ... | ... | @@ -65,6 +72,7 @@ impl fmt::Display for ErrorKind { |
| 65 | 72 | #[derive(Debug)] |
| 66 | 73 | pub struct Error { |
| 67 | 74 | pub line_num: Option<usize>, |
| 75 | pub column_num: Option<usize>, | |
| 68 | 76 | /// What kind of message we expect (e.g., warning, error, suggestion). |
| 69 | 77 | pub kind: ErrorKind, |
| 70 | 78 | pub msg: String, |
| ... | ... | @@ -74,17 +82,6 @@ pub struct Error { |
| 74 | 82 | pub require_annotation: bool, |
| 75 | 83 | } |
| 76 | 84 | |
| 77 | impl Error { | |
| 78 | pub fn render_for_expected(&self) -> String { | |
| 79 | use colored::Colorize; | |
| 80 | format!("{: <10}line {: >3}: {}", self.kind, self.line_num_str(), self.msg.cyan()) | |
| 81 | } | |
| 82 | ||
| 83 | pub fn line_num_str(&self) -> String { | |
| 84 | self.line_num.map_or("?".to_string(), |line_num| line_num.to_string()) | |
| 85 | } | |
| 86 | } | |
| 87 | ||
| 88 | 85 | /// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE" |
| 89 | 86 | /// The former is a "follow" that inherits its target from the preceding line; |
| 90 | 87 | /// the latter is an "adjusts" that goes that many lines up. |
| ... | ... | @@ -168,8 +165,10 @@ fn parse_expected( |
| 168 | 165 | let rest = line[tag.end()..].trim_start(); |
| 169 | 166 | let (kind_str, _) = |
| 170 | 167 | rest.split_once(|c: char| c != '_' && !c.is_ascii_alphabetic()).unwrap_or((rest, "")); |
| 171 | let kind = ErrorKind::from_user_str(kind_str); | |
| 172 | let untrimmed_msg = &rest[kind_str.len()..]; | |
| 168 | let (kind, untrimmed_msg) = match ErrorKind::from_user_str(kind_str) { | |
| 169 | Some(kind) => (kind, &rest[kind_str.len()..]), | |
| 170 | None => (ErrorKind::Unknown, rest), | |
| 171 | }; | |
| 173 | 172 | let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned(); |
| 174 | 173 | |
| 175 | 174 | let line_num_adjust = &captures["adjust"]; |
| ... | ... | @@ -182,6 +181,7 @@ fn parse_expected( |
| 182 | 181 | } else { |
| 183 | 182 | (false, Some(line_num - line_num_adjust.len())) |
| 184 | 183 | }; |
| 184 | let column_num = Some(tag.start() + 1); | |
| 185 | 185 | |
| 186 | 186 | debug!( |
| 187 | 187 | "line={:?} tag={:?} follow_prev={:?} kind={:?} msg={:?}", |
| ... | ... | @@ -191,7 +191,7 @@ fn parse_expected( |
| 191 | 191 | kind, |
| 192 | 192 | msg |
| 193 | 193 | ); |
| 194 | Some((follow_prev, Error { line_num, kind, msg, require_annotation: true })) | |
| 194 | Some((follow_prev, Error { line_num, column_num, kind, msg, require_annotation: true })) | |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | 197 | #[cfg(test)] |
src/tools/compiletest/src/header.rs+1-1| ... | ... | @@ -593,7 +593,7 @@ impl TestProps { |
| 593 | 593 | config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) |
| 594 | 594 | { |
| 595 | 595 | self.dont_require_annotations |
| 596 | .insert(ErrorKind::from_user_str(err_kind.trim())); | |
| 596 | .insert(ErrorKind::expect_from_user_str(err_kind.trim())); | |
| 597 | 597 | } |
| 598 | 598 | }, |
| 599 | 599 | ); |
src/tools/compiletest/src/json.rs+15-25| ... | ... | @@ -36,9 +36,7 @@ struct UnusedExternNotification { |
| 36 | 36 | struct DiagnosticSpan { |
| 37 | 37 | file_name: String, |
| 38 | 38 | line_start: usize, |
| 39 | line_end: usize, | |
| 40 | 39 | column_start: usize, |
| 41 | column_end: usize, | |
| 42 | 40 | is_primary: bool, |
| 43 | 41 | label: Option<String>, |
| 44 | 42 | suggested_replacement: Option<String>, |
| ... | ... | @@ -148,6 +146,7 @@ pub fn parse_output(file_name: &str, output: &str) -> Vec<Error> { |
| 148 | 146 | Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name), |
| 149 | 147 | Err(_) => errors.push(Error { |
| 150 | 148 | line_num: None, |
| 149 | column_num: None, | |
| 151 | 150 | kind: ErrorKind::Raw, |
| 152 | 151 | msg: line.to_string(), |
| 153 | 152 | require_annotation: false, |
| ... | ... | @@ -193,25 +192,9 @@ fn push_actual_errors( |
| 193 | 192 | // also ensure that `//~ ERROR E123` *always* works. The |
| 194 | 193 | // assumption is that these multi-line error messages are on their |
| 195 | 194 | // way out anyhow. |
| 196 | let with_code = |span: Option<&DiagnosticSpan>, text: &str| { | |
| 197 | // FIXME(#33000) -- it'd be better to use a dedicated | |
| 198 | // UI harness than to include the line/col number like | |
| 199 | // this, but some current tests rely on it. | |
| 200 | // | |
| 201 | // Note: Do NOT include the filename. These can easily | |
| 202 | // cause false matches where the expected message | |
| 203 | // appears in the filename, and hence the message | |
| 204 | // changes but the test still passes. | |
| 205 | let span_str = match span { | |
| 206 | Some(DiagnosticSpan { line_start, column_start, line_end, column_end, .. }) => { | |
| 207 | format!("{line_start}:{column_start}: {line_end}:{column_end}") | |
| 208 | } | |
| 209 | None => format!("?:?: ?:?"), | |
| 210 | }; | |
| 211 | match &diagnostic.code { | |
| 212 | Some(code) => format!("{span_str}: {text} [{}]", code.code), | |
| 213 | None => format!("{span_str}: {text}"), | |
| 214 | } | |
| 195 | let with_code = |text| match &diagnostic.code { | |
| 196 | Some(code) => format!("{text} [{}]", code.code), | |
| 197 | None => format!("{text}"), | |
| 215 | 198 | }; |
| 216 | 199 | |
| 217 | 200 | // Convert multi-line messages into multiple errors. |
| ... | ... | @@ -225,8 +208,9 @@ fn push_actual_errors( |
| 225 | 208 | || Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap(); |
| 226 | 209 | errors.push(Error { |
| 227 | 210 | line_num: None, |
| 211 | column_num: None, | |
| 228 | 212 | kind, |
| 229 | msg: with_code(None, first_line), | |
| 213 | msg: with_code(first_line), | |
| 230 | 214 | require_annotation: diagnostic.level != "failure-note" |
| 231 | 215 | && !RE.get_or_init(re_init).is_match(first_line), |
| 232 | 216 | }); |
| ... | ... | @@ -234,8 +218,9 @@ fn push_actual_errors( |
| 234 | 218 | for span in primary_spans { |
| 235 | 219 | errors.push(Error { |
| 236 | 220 | line_num: Some(span.line_start), |
| 221 | column_num: Some(span.column_start), | |
| 237 | 222 | kind, |
| 238 | msg: with_code(Some(span), first_line), | |
| 223 | msg: with_code(first_line), | |
| 239 | 224 | require_annotation: true, |
| 240 | 225 | }); |
| 241 | 226 | } |
| ... | ... | @@ -244,16 +229,18 @@ fn push_actual_errors( |
| 244 | 229 | if primary_spans.is_empty() { |
| 245 | 230 | errors.push(Error { |
| 246 | 231 | line_num: None, |
| 232 | column_num: None, | |
| 247 | 233 | kind, |
| 248 | msg: with_code(None, next_line), | |
| 234 | msg: with_code(next_line), | |
| 249 | 235 | require_annotation: false, |
| 250 | 236 | }); |
| 251 | 237 | } else { |
| 252 | 238 | for span in primary_spans { |
| 253 | 239 | errors.push(Error { |
| 254 | 240 | line_num: Some(span.line_start), |
| 241 | column_num: Some(span.column_start), | |
| 255 | 242 | kind, |
| 256 | msg: with_code(Some(span), next_line), | |
| 243 | msg: with_code(next_line), | |
| 257 | 244 | require_annotation: false, |
| 258 | 245 | }); |
| 259 | 246 | } |
| ... | ... | @@ -266,6 +253,7 @@ fn push_actual_errors( |
| 266 | 253 | for (index, line) in suggested_replacement.lines().enumerate() { |
| 267 | 254 | errors.push(Error { |
| 268 | 255 | line_num: Some(span.line_start + index), |
| 256 | column_num: Some(span.column_start), | |
| 269 | 257 | kind: ErrorKind::Suggestion, |
| 270 | 258 | msg: line.to_string(), |
| 271 | 259 | // Empty suggestions (suggestions to remove something) are common |
| ... | ... | @@ -288,6 +276,7 @@ fn push_actual_errors( |
| 288 | 276 | if let Some(label) = &span.label { |
| 289 | 277 | errors.push(Error { |
| 290 | 278 | line_num: Some(span.line_start), |
| 279 | column_num: Some(span.column_start), | |
| 291 | 280 | kind: ErrorKind::Note, |
| 292 | 281 | msg: label.clone(), |
| 293 | 282 | // Empty labels (only underlining spans) are common and do not need annotations. |
| ... | ... | @@ -310,6 +299,7 @@ fn push_backtrace( |
| 310 | 299 | if Path::new(&expansion.span.file_name) == Path::new(&file_name) { |
| 311 | 300 | errors.push(Error { |
| 312 | 301 | line_num: Some(expansion.span.line_start), |
| 302 | column_num: Some(expansion.span.column_start), | |
| 313 | 303 | kind: ErrorKind::Note, |
| 314 | 304 | msg: format!("in this expansion of {}", expansion.macro_decl_name), |
| 315 | 305 | require_annotation: true, |
src/tools/compiletest/src/runtest.rs+120-27| ... | ... | @@ -11,7 +11,7 @@ use std::{env, iter, str}; |
| 11 | 11 | |
| 12 | 12 | use build_helper::fs::remove_and_create_dir_all; |
| 13 | 13 | use camino::{Utf8Path, Utf8PathBuf}; |
| 14 | use colored::Colorize; | |
| 14 | use colored::{Color, Colorize}; | |
| 15 | 15 | use regex::{Captures, Regex}; |
| 16 | 16 | use tracing::*; |
| 17 | 17 | |
| ... | ... | @@ -677,9 +677,6 @@ impl<'test> TestCx<'test> { |
| 677 | 677 | return; |
| 678 | 678 | } |
| 679 | 679 | |
| 680 | // On Windows, translate all '\' path separators to '/' | |
| 681 | let file_name = self.testpaths.file.to_string().replace(r"\", "/"); | |
| 682 | ||
| 683 | 680 | // On Windows, keep all '\' path separators to match the paths reported in the JSON output |
| 684 | 681 | // from the compiler |
| 685 | 682 | let diagnostic_file_name = if self.props.remap_src_base { |
| ... | ... | @@ -704,6 +701,7 @@ impl<'test> TestCx<'test> { |
| 704 | 701 | .map(|e| Error { msg: self.normalize_output(&e.msg, &[]), ..e }); |
| 705 | 702 | |
| 706 | 703 | let mut unexpected = Vec::new(); |
| 704 | let mut unimportant = Vec::new(); | |
| 707 | 705 | let mut found = vec![false; expected_errors.len()]; |
| 708 | 706 | for actual_error in actual_errors { |
| 709 | 707 | for pattern in &self.props.error_patterns { |
| ... | ... | @@ -738,14 +736,9 @@ impl<'test> TestCx<'test> { |
| 738 | 736 | && expected_kinds.contains(&actual_error.kind) |
| 739 | 737 | && !self.props.dont_require_annotations.contains(&actual_error.kind) |
| 740 | 738 | { |
| 741 | self.error(&format!( | |
| 742 | "{}:{}: unexpected {}: '{}'", | |
| 743 | file_name, | |
| 744 | actual_error.line_num_str(), | |
| 745 | actual_error.kind, | |
| 746 | actual_error.msg | |
| 747 | )); | |
| 748 | 739 | unexpected.push(actual_error); |
| 740 | } else { | |
| 741 | unimportant.push(actual_error); | |
| 749 | 742 | } |
| 750 | 743 | } |
| 751 | 744 | } |
| ... | ... | @@ -755,39 +748,140 @@ impl<'test> TestCx<'test> { |
| 755 | 748 | // anything not yet found is a problem |
| 756 | 749 | for (index, expected_error) in expected_errors.iter().enumerate() { |
| 757 | 750 | if !found[index] { |
| 758 | self.error(&format!( | |
| 759 | "{}:{}: expected {} not found: {}", | |
| 760 | file_name, | |
| 761 | expected_error.line_num_str(), | |
| 762 | expected_error.kind, | |
| 763 | expected_error.msg | |
| 764 | )); | |
| 765 | 751 | not_found.push(expected_error); |
| 766 | 752 | } |
| 767 | 753 | } |
| 768 | 754 | |
| 769 | 755 | if !unexpected.is_empty() || !not_found.is_empty() { |
| 770 | 756 | self.error(&format!( |
| 771 | "{} unexpected errors found, {} expected errors not found", | |
| 757 | "{} unexpected diagnostics reported, {} expected diagnostics not reported", | |
| 772 | 758 | unexpected.len(), |
| 773 | 759 | not_found.len() |
| 774 | 760 | )); |
| 775 | println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); | |
| 761 | ||
| 762 | // Emit locations in a format that is short (relative paths) but "clickable" in editors. | |
| 763 | // Also normalize path separators to `/`. | |
| 764 | let file_name = self | |
| 765 | .testpaths | |
| 766 | .file | |
| 767 | .strip_prefix(self.config.src_root.as_str()) | |
| 768 | .unwrap_or(&self.testpaths.file) | |
| 769 | .to_string() | |
| 770 | .replace(r"\", "/"); | |
| 771 | let line_str = |e: &Error| { | |
| 772 | let line_num = e.line_num.map_or("?".to_string(), |line_num| line_num.to_string()); | |
| 773 | // `file:?:NUM` may be confusing to editors and unclickable. | |
| 774 | let opt_col_num = match e.column_num { | |
| 775 | Some(col_num) if line_num != "?" => format!(":{col_num}"), | |
| 776 | _ => "".to_string(), | |
| 777 | }; | |
| 778 | format!("{file_name}:{line_num}{opt_col_num}") | |
| 779 | }; | |
| 780 | let print_error = |e| println!("{}: {}: {}", line_str(e), e.kind, e.msg.cyan()); | |
| 781 | let push_suggestion = | |
| 782 | |suggestions: &mut Vec<_>, e: &Error, kind, line, msg, color, rank| { | |
| 783 | let mut ret = String::new(); | |
| 784 | if kind { | |
| 785 | ret += &format!("{} {}", "with kind".color(color), e.kind); | |
| 786 | } | |
| 787 | if line { | |
| 788 | if !ret.is_empty() { | |
| 789 | ret.push(' '); | |
| 790 | } | |
| 791 | ret += &format!("{} {}", "on line".color(color), line_str(e)); | |
| 792 | } | |
| 793 | if msg { | |
| 794 | if !ret.is_empty() { | |
| 795 | ret.push(' '); | |
| 796 | } | |
| 797 | ret += &format!("{} {}", "with message".color(color), e.msg.cyan()); | |
| 798 | } | |
| 799 | suggestions.push((ret, rank)); | |
| 800 | }; | |
| 801 | let show_suggestions = |mut suggestions: Vec<_>, prefix: &str, color| { | |
| 802 | // Only show suggestions with the highest rank. | |
| 803 | suggestions.sort_by_key(|(_, rank)| *rank); | |
| 804 | if let Some(&(_, top_rank)) = suggestions.first() { | |
| 805 | for (suggestion, rank) in suggestions { | |
| 806 | if rank == top_rank { | |
| 807 | println!(" {} {suggestion}", prefix.color(color)); | |
| 808 | } | |
| 809 | } | |
| 810 | } | |
| 811 | }; | |
| 812 | ||
| 813 | // Fuzzy matching quality: | |
| 814 | // - message and line / message and kind - great, suggested | |
| 815 | // - only message - good, suggested | |
| 816 | // - known line and kind - ok, suggested | |
| 817 | // - only known line - meh, but suggested | |
| 818 | // - others are not worth suggesting | |
| 776 | 819 | if !unexpected.is_empty() { |
| 777 | println!("{}", "--- unexpected errors (from JSON output) ---".green()); | |
| 820 | let header = "--- reported in JSON output but not expected in test file ---"; | |
| 821 | println!("{}", header.green()); | |
| 778 | 822 | for error in &unexpected { |
| 779 | println!("{}", error.render_for_expected()); | |
| 823 | print_error(error); | |
| 824 | let mut suggestions = Vec::new(); | |
| 825 | for candidate in &not_found { | |
| 826 | let mut push_red_suggestion = |line, msg, rank| { | |
| 827 | push_suggestion( | |
| 828 | &mut suggestions, | |
| 829 | candidate, | |
| 830 | candidate.kind != error.kind, | |
| 831 | line, | |
| 832 | msg, | |
| 833 | Color::Red, | |
| 834 | rank, | |
| 835 | ) | |
| 836 | }; | |
| 837 | if error.msg.contains(&candidate.msg) { | |
| 838 | push_red_suggestion(candidate.line_num != error.line_num, false, 0); | |
| 839 | } else if candidate.line_num.is_some() | |
| 840 | && candidate.line_num == error.line_num | |
| 841 | { | |
| 842 | push_red_suggestion(false, true, 1); | |
| 843 | } | |
| 844 | } | |
| 845 | ||
| 846 | show_suggestions(suggestions, "expected", Color::Red); | |
| 780 | 847 | } |
| 781 | 848 | println!("{}", "---".green()); |
| 782 | 849 | } |
| 783 | 850 | if !not_found.is_empty() { |
| 784 | println!("{}", "--- not found errors (from test file) ---".red()); | |
| 851 | let header = "--- expected in test file but not reported in JSON output ---"; | |
| 852 | println!("{}", header.red()); | |
| 785 | 853 | for error in &not_found { |
| 786 | println!("{}", error.render_for_expected()); | |
| 854 | print_error(error); | |
| 855 | let mut suggestions = Vec::new(); | |
| 856 | for candidate in unexpected.iter().chain(&unimportant) { | |
| 857 | let mut push_green_suggestion = |line, msg, rank| { | |
| 858 | push_suggestion( | |
| 859 | &mut suggestions, | |
| 860 | candidate, | |
| 861 | candidate.kind != error.kind, | |
| 862 | line, | |
| 863 | msg, | |
| 864 | Color::Green, | |
| 865 | rank, | |
| 866 | ) | |
| 867 | }; | |
| 868 | if candidate.msg.contains(&error.msg) { | |
| 869 | push_green_suggestion(candidate.line_num != error.line_num, false, 0); | |
| 870 | } else if candidate.line_num.is_some() | |
| 871 | && candidate.line_num == error.line_num | |
| 872 | { | |
| 873 | push_green_suggestion(false, true, 1); | |
| 874 | } | |
| 875 | } | |
| 876 | ||
| 877 | show_suggestions(suggestions, "reported", Color::Green); | |
| 787 | 878 | } |
| 788 | println!("{}", "---\n".red()); | |
| 879 | println!("{}", "---".red()); | |
| 789 | 880 | } |
| 790 | panic!("errors differ from expected"); | |
| 881 | panic!( | |
| 882 | "errors differ from expected\nstatus: {}\ncommand: {}\n", | |
| 883 | proc_res.status, proc_res.cmdline | |
| 884 | ); | |
| 791 | 885 | } |
| 792 | 886 | } |
| 793 | 887 | |
| ... | ... | @@ -2073,7 +2167,6 @@ impl<'test> TestCx<'test> { |
| 2073 | 2167 | println!("{}", String::from_utf8_lossy(&output.stdout)); |
| 2074 | 2168 | eprintln!("{}", String::from_utf8_lossy(&output.stderr)); |
| 2075 | 2169 | } else { |
| 2076 | use colored::Colorize; | |
| 2077 | 2170 | eprintln!("warning: no pager configured, falling back to unified diff"); |
| 2078 | 2171 | eprintln!( |
| 2079 | 2172 | "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`" |
tests/incremental/issue-61323.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ revisions: rpass cfail |
| 2 | 2 | |
| 3 | 3 | enum A { |
| 4 | //[cfail]~^ ERROR 3:1: 3:7: recursive types `A` and `C` have infinite size [E0072] | |
| 4 | //[cfail]~^ ERROR recursive types `A` and `C` have infinite size [E0072] | |
| 5 | 5 | B(C), |
| 6 | 6 | } |
| 7 | 7 |
tests/rustdoc-json/generic-args.rs+3| ... | ... | @@ -17,4 +17,7 @@ pub fn my_fn1(_: <MyStruct as MyTrait>::MyType) {} |
| 17 | 17 | //@ is "$.index[?(@.name=='my_fn2')].inner.function.sig.inputs[0][1].dyn_trait.traits[0].trait.args.angle_bracketed.constraints[0].args" null |
| 18 | 18 | pub fn my_fn2(_: IntoIterator<Item = MyStruct, IntoIter = impl Clone>) {} |
| 19 | 19 | |
| 20 | //@ is "$.index[?(@.name=='my_fn3')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.args.parenthesized.inputs" [] | |
| 21 | pub fn my_fn3(f: impl FnMut()) {} | |
| 22 | ||
| 20 | 23 | fn main() {} |
tests/ui/argument-suggestions/issue-100478.rs+2-2| ... | ... | @@ -32,8 +32,8 @@ fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {} |
| 32 | 32 | |
| 33 | 33 | fn main() { |
| 34 | 34 | three_diff(T2::new(0)); //~ ERROR function takes |
| 35 | four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR 35:5: 35:17: arguments to this function are incorrect [E0308] | |
| 36 | four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR 36:5: 36:17: arguments to this function are incorrect [E0308] | |
| 35 | four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR arguments to this function are incorrect [E0308] | |
| 36 | four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR arguments to this function are incorrect [E0308] | |
| 37 | 37 | |
| 38 | 38 | let p1 = T1::new(0); |
| 39 | 39 | let p2 = Arc::new(T2::new(0)); |
tests/ui/async-await/incorrect-move-async-order-issue-79694.fixed+1-1| ... | ... | @@ -4,5 +4,5 @@ |
| 4 | 4 | // Regression test for issue 79694 |
| 5 | 5 | |
| 6 | 6 | fn main() { |
| 7 | let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect | |
| 7 | let _ = async move { }; //~ ERROR the order of `move` and `async` is incorrect | |
| 8 | 8 | } |
tests/ui/async-await/incorrect-move-async-order-issue-79694.rs+1-1| ... | ... | @@ -4,5 +4,5 @@ |
| 4 | 4 | // Regression test for issue 79694 |
| 5 | 5 | |
| 6 | 6 | fn main() { |
| 7 | let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect | |
| 7 | let _ = move async { }; //~ ERROR the order of `move` and `async` is incorrect | |
| 8 | 8 | } |
tests/ui/attributes/rustc_skip_during_method_dispatch.rs created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | #![feature(rustc_attrs)] | |
| 2 | ||
| 3 | #[rustc_skip_during_method_dispatch] | |
| 4 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input [E0539] | |
| 5 | trait NotAList {} | |
| 6 | ||
| 7 | #[rustc_skip_during_method_dispatch = "array"] | |
| 8 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input [E0539] | |
| 9 | trait AlsoNotAList {} | |
| 10 | ||
| 11 | #[rustc_skip_during_method_dispatch()] | |
| 12 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 13 | trait Argless {} | |
| 14 | ||
| 15 | #[rustc_skip_during_method_dispatch(array, boxed_slice, array)] | |
| 16 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 17 | trait Duplicate {} | |
| 18 | ||
| 19 | #[rustc_skip_during_method_dispatch(slice)] | |
| 20 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 21 | trait Unexpected {} | |
| 22 | ||
| 23 | #[rustc_skip_during_method_dispatch(array = true)] | |
| 24 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 25 | trait KeyValue {} | |
| 26 | ||
| 27 | #[rustc_skip_during_method_dispatch("array")] | |
| 28 | //~^ ERROR: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 29 | trait String {} | |
| 30 | ||
| 31 | #[rustc_skip_during_method_dispatch(array, boxed_slice)] | |
| 32 | trait OK {} | |
| 33 | ||
| 34 | #[rustc_skip_during_method_dispatch(array)] | |
| 35 | //~^ ERROR: attribute should be applied to a trait | |
| 36 | impl OK for () {} | |
| 37 | ||
| 38 | fn main() {} |
tests/ui/attributes/rustc_skip_during_method_dispatch.stderr created+76| ... | ... | @@ -0,0 +1,76 @@ |
| 1 | error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 2 | --> $DIR/rustc_skip_during_method_dispatch.rs:3:1 | |
| 3 | | | |
| 4 | LL | #[rustc_skip_during_method_dispatch] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 6 | | | | |
| 7 | | expected this to be a list | |
| 8 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 9 | ||
| 10 | error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 11 | --> $DIR/rustc_skip_during_method_dispatch.rs:7:1 | |
| 12 | | | |
| 13 | LL | #[rustc_skip_during_method_dispatch = "array"] | |
| 14 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | | | | |
| 16 | | expected this to be a list | |
| 17 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 18 | ||
| 19 | error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 20 | --> $DIR/rustc_skip_during_method_dispatch.rs:11:1 | |
| 21 | | | |
| 22 | LL | #[rustc_skip_during_method_dispatch()] | |
| 23 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--^ | |
| 24 | | | | | |
| 25 | | | expected at least 1 argument here | |
| 26 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 27 | ||
| 28 | error[E0538]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 29 | --> $DIR/rustc_skip_during_method_dispatch.rs:15:1 | |
| 30 | | | |
| 31 | LL | #[rustc_skip_during_method_dispatch(array, boxed_slice, array)] | |
| 32 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----^^ | |
| 33 | | | | | |
| 34 | | | found `array` used as a key more than once | |
| 35 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 36 | ||
| 37 | error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 38 | --> $DIR/rustc_skip_during_method_dispatch.rs:19:1 | |
| 39 | | | |
| 40 | LL | #[rustc_skip_during_method_dispatch(slice)] | |
| 41 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----^^ | |
| 42 | | | | | |
| 43 | | | valid arguments are `array` or `boxed_slice` | |
| 44 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 45 | ||
| 46 | error[E0565]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 47 | --> $DIR/rustc_skip_during_method_dispatch.rs:23:1 | |
| 48 | | | |
| 49 | LL | #[rustc_skip_during_method_dispatch(array = true)] | |
| 50 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ | |
| 51 | | | | | |
| 52 | | | didn't expect any arguments here | |
| 53 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 54 | ||
| 55 | error[E0565]: malformed `rustc_skip_during_method_dispatch` attribute input | |
| 56 | --> $DIR/rustc_skip_during_method_dispatch.rs:27:1 | |
| 57 | | | |
| 58 | LL | #[rustc_skip_during_method_dispatch("array")] | |
| 59 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^ | |
| 60 | | | | | |
| 61 | | | didn't expect a literal here | |
| 62 | | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` | |
| 63 | ||
| 64 | error: attribute should be applied to a trait | |
| 65 | --> $DIR/rustc_skip_during_method_dispatch.rs:34:1 | |
| 66 | | | |
| 67 | LL | #[rustc_skip_during_method_dispatch(array)] | |
| 68 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 69 | LL | | |
| 70 | LL | impl OK for () {} | |
| 71 | | ----------------- not a trait | |
| 72 | ||
| 73 | error: aborting due to 8 previous errors | |
| 74 | ||
| 75 | Some errors have detailed explanations: E0538, E0539, E0565. | |
| 76 | For more information about an error, try `rustc --explain E0538`. |
tests/ui/compiletest-self-test/line-annotation-mismatches.rs created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | //@ should-fail | |
| 2 | ||
| 3 | // The warning is reported with unknown line | |
| 4 | //@ compile-flags: -D raw_pointer_derive | |
| 5 | //~? WARN kind and unknown line match the reported warning, but we do not suggest it | |
| 6 | ||
| 7 | // The error is expected but not reported at all. | |
| 8 | //~ ERROR this error does not exist | |
| 9 | ||
| 10 | // The error is reported but not expected at all. | |
| 11 | // "`main` function not found in crate" (the main function is intentionally not added) | |
| 12 | ||
| 13 | // An "unimportant" diagnostic is expected on a wrong line. | |
| 14 | //~ ERROR aborting due to | |
| 15 | ||
| 16 | // An "unimportant" diagnostic is expected with a wrong kind. | |
| 17 | //~? ERROR For more information about an error | |
| 18 | ||
| 19 | fn wrong_line_or_kind() { | |
| 20 | // A diagnostic expected on a wrong line. | |
| 21 | unresolved1; | |
| 22 | //~ ERROR cannot find value `unresolved1` in this scope | |
| 23 | ||
| 24 | // A diagnostic expected with a wrong kind. | |
| 25 | unresolved2; //~ WARN cannot find value `unresolved2` in this scope | |
| 26 | ||
| 27 | // A diagnostic expected with a missing kind (treated as a wrong kind). | |
| 28 | unresolved3; //~ cannot find value `unresolved3` in this scope | |
| 29 | ||
| 30 | // A diagnostic expected with a wrong line and kind. | |
| 31 | unresolved4; | |
| 32 | //~ WARN cannot find value `unresolved4` in this scope | |
| 33 | } | |
| 34 | ||
| 35 | fn wrong_message() { | |
| 36 | // A diagnostic expected with a wrong message, but the line is known and right. | |
| 37 | unresolvedA; //~ ERROR stub message 1 | |
| 38 | ||
| 39 | // A diagnostic expected with a wrong message, but the line is known and right, | |
| 40 | // even if the kind doesn't match. | |
| 41 | unresolvedB; //~ WARN stub message 2 | |
| 42 | } |
tests/ui/compiletest-self-test/line-annotation-mismatches.stderr created+61| ... | ... | @@ -0,0 +1,61 @@ |
| 1 | warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | |
| 2 | | | |
| 3 | = note: requested on the command line with `-D raw_pointer_derive` | |
| 4 | = note: `#[warn(renamed_and_removed_lints)]` on by default | |
| 5 | ||
| 6 | error[E0425]: cannot find value `unresolved1` in this scope | |
| 7 | --> $DIR/line-annotation-mismatches.rs:21:5 | |
| 8 | | | |
| 9 | LL | unresolved1; | |
| 10 | | ^^^^^^^^^^^ not found in this scope | |
| 11 | ||
| 12 | error[E0425]: cannot find value `unresolved2` in this scope | |
| 13 | --> $DIR/line-annotation-mismatches.rs:25:5 | |
| 14 | | | |
| 15 | LL | unresolved2; | |
| 16 | | ^^^^^^^^^^^ not found in this scope | |
| 17 | ||
| 18 | error[E0425]: cannot find value `unresolved3` in this scope | |
| 19 | --> $DIR/line-annotation-mismatches.rs:28:5 | |
| 20 | | | |
| 21 | LL | unresolved3; | |
| 22 | | ^^^^^^^^^^^ not found in this scope | |
| 23 | ||
| 24 | error[E0425]: cannot find value `unresolved4` in this scope | |
| 25 | --> $DIR/line-annotation-mismatches.rs:31:5 | |
| 26 | | | |
| 27 | LL | unresolved4; | |
| 28 | | ^^^^^^^^^^^ not found in this scope | |
| 29 | ||
| 30 | error[E0425]: cannot find value `unresolvedA` in this scope | |
| 31 | --> $DIR/line-annotation-mismatches.rs:37:5 | |
| 32 | | | |
| 33 | LL | unresolvedA; | |
| 34 | | ^^^^^^^^^^^ not found in this scope | |
| 35 | ||
| 36 | error[E0425]: cannot find value `unresolvedB` in this scope | |
| 37 | --> $DIR/line-annotation-mismatches.rs:41:5 | |
| 38 | | | |
| 39 | LL | unresolvedB; | |
| 40 | | ^^^^^^^^^^^ not found in this scope | |
| 41 | ||
| 42 | warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | |
| 43 | | | |
| 44 | = note: requested on the command line with `-D raw_pointer_derive` | |
| 45 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 46 | ||
| 47 | error[E0601]: `main` function not found in crate `line_annotation_mismatches` | |
| 48 | --> $DIR/line-annotation-mismatches.rs:42:2 | |
| 49 | | | |
| 50 | LL | } | |
| 51 | | ^ consider adding a `main` function to `$DIR/line-annotation-mismatches.rs` | |
| 52 | ||
| 53 | warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok | |
| 54 | | | |
| 55 | = note: requested on the command line with `-D raw_pointer_derive` | |
| 56 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 57 | ||
| 58 | error: aborting due to 7 previous errors; 3 warnings emitted | |
| 59 | ||
| 60 | Some errors have detailed explanations: E0425, E0601. | |
| 61 | For more information about an error, try `rustc --explain E0425`. |
tests/ui/feature-gates/feature-gate-cfi_encoding.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | 1 | #![crate_type = "lib"] |
| 2 | 2 | |
| 3 | #[cfi_encoding = "3Bar"] //~ERROR 3:1: 3:25: the `#[cfi_encoding]` attribute is an experimental feature [E0658] | |
| 3 | #[cfi_encoding = "3Bar"] //~ ERROR the `#[cfi_encoding]` attribute is an experimental feature [E0658] | |
| 4 | 4 | pub struct Foo(i32); |
tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | 1 | fn main() { |
| 2 | 2 | let _ : &(dyn Send,) = &((),); |
| 3 | //~^ ERROR 2:28: 2:34: mismatched types [E0308] | |
| 3 | //~^ ERROR mismatched types [E0308] | |
| 4 | 4 | } |
tests/ui/impl-header-lifetime-elision/assoc-type.rs+1-1| ... | ... | @@ -9,7 +9,7 @@ trait MyTrait { |
| 9 | 9 | |
| 10 | 10 | impl MyTrait for &i32 { |
| 11 | 11 | type Output = &i32; |
| 12 | //~^ ERROR 11:19: 11:20: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 12 | //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | impl MyTrait for &u32 { |
tests/ui/imports/issue-28134.rs+1-1| ... | ... | @@ -2,4 +2,4 @@ |
| 2 | 2 | |
| 3 | 3 | #![allow(soft_unstable)] |
| 4 | 4 | #![test] |
| 5 | //~^ ERROR 4:1: 4:9: `test` attribute cannot be used at crate level | |
| 5 | //~^ ERROR `test` attribute cannot be used at crate level |
tests/ui/inference/hint-closure-signature-119266.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ fn main() { |
| 3 | 3 | //~^ NOTE: the found closure |
| 4 | 4 | |
| 5 | 5 | let x: fn(i32) = x; |
| 6 | //~^ ERROR: 5:22: 5:23: mismatched types [E0308] | |
| 6 | //~^ ERROR: mismatched types [E0308] | |
| 7 | 7 | //~| NOTE: incorrect number of function parameters |
| 8 | 8 | //~| NOTE: expected due to this |
| 9 | 9 | //~| NOTE: expected fn pointer `fn(i32)` |
tests/ui/integral-indexing.rs+8-8| ... | ... | @@ -3,14 +3,14 @@ pub fn main() { |
| 3 | 3 | let s: String = "abcdef".to_string(); |
| 4 | 4 | v[3_usize]; |
| 5 | 5 | v[3]; |
| 6 | v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8` | |
| 7 | v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8` | |
| 8 | v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32` | |
| 9 | v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32` | |
| 6 | v[3u8]; //~ ERROR the type `[isize]` cannot be indexed by `u8` | |
| 7 | v[3i8]; //~ ERROR the type `[isize]` cannot be indexed by `i8` | |
| 8 | v[3u32]; //~ ERROR the type `[isize]` cannot be indexed by `u32` | |
| 9 | v[3i32]; //~ ERROR the type `[isize]` cannot be indexed by `i32` | |
| 10 | 10 | s.as_bytes()[3_usize]; |
| 11 | 11 | s.as_bytes()[3]; |
| 12 | s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8` | |
| 13 | s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8` | |
| 14 | s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32` | |
| 15 | s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32` | |
| 12 | s.as_bytes()[3u8]; //~ ERROR the type `[u8]` cannot be indexed by `u8` | |
| 13 | s.as_bytes()[3i8]; //~ ERROR the type `[u8]` cannot be indexed by `i8` | |
| 14 | s.as_bytes()[3u32]; //~ ERROR the type `[u8]` cannot be indexed by `u32` | |
| 15 | s.as_bytes()[3i32]; //~ ERROR the type `[u8]` cannot be indexed by `i32` | |
| 16 | 16 | } |
tests/ui/issues/issue-92741.rs+3-3| ... | ... | @@ -1,17 +1,17 @@ |
| 1 | 1 | //@ run-rustfix |
| 2 | 2 | fn main() {} |
| 3 | 3 | fn _foo() -> bool { |
| 4 | & //~ ERROR 4:5: 6:36: mismatched types [E0308] | |
| 4 | & //~ ERROR mismatched types [E0308] | |
| 5 | 5 | mut |
| 6 | 6 | if true { true } else { false } |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | fn _bar() -> bool { |
| 10 | & //~ ERROR 10:5: 11:40: mismatched types [E0308] | |
| 10 | & //~ ERROR mismatched types [E0308] | |
| 11 | 11 | mut if true { true } else { false } |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | fn _baz() -> bool { |
| 15 | & mut //~ ERROR 15:5: 16:36: mismatched types [E0308] | |
| 15 | & mut //~ ERROR mismatched types [E0308] | |
| 16 | 16 | if true { true } else { false } |
| 17 | 17 | } |
tests/ui/lifetimes/no_lending_iterators.rs+3-3| ... | ... | @@ -2,7 +2,7 @@ struct Data(String); |
| 2 | 2 | |
| 3 | 3 | impl Iterator for Data { |
| 4 | 4 | type Item = &str; |
| 5 | //~^ ERROR 4:17: 4:18: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 5 | //~^ ERROR associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 6 | 6 | |
| 7 | 7 | fn next(&mut self) -> Option<Self::Item> { |
| 8 | 8 | Some(&self.0) |
| ... | ... | @@ -16,7 +16,7 @@ trait Bar { |
| 16 | 16 | |
| 17 | 17 | impl Bar for usize { |
| 18 | 18 | type Item = &usize; |
| 19 | //~^ ERROR 18:17: 18:18: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 19 | //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type | |
| 20 | 20 | |
| 21 | 21 | fn poke(&mut self, item: Self::Item) { |
| 22 | 22 | self += *item; |
| ... | ... | @@ -25,7 +25,7 @@ impl Bar for usize { |
| 25 | 25 | |
| 26 | 26 | impl Bar for isize { |
| 27 | 27 | type Item<'a> = &'a isize; |
| 28 | //~^ ERROR 27:14: 27:18: lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195] | |
| 28 | //~^ ERROR lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195] | |
| 29 | 29 | |
| 30 | 30 | fn poke(&mut self, item: Self::Item) { |
| 31 | 31 | self += *item; |
tests/ui/mismatched_types/transforming-option-ref-issue-127545.rs+4-4| ... | ... | @@ -2,17 +2,17 @@ |
| 2 | 2 | #![crate_type = "lib"] |
| 3 | 3 | |
| 4 | 4 | pub fn foo(arg: Option<&Vec<i32>>) -> Option<&[i32]> { |
| 5 | arg //~ ERROR 5:5: 5:8: mismatched types [E0308] | |
| 5 | arg //~ ERROR mismatched types [E0308] | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | pub fn bar(arg: Option<&Vec<i32>>) -> &[i32] { |
| 9 | arg.unwrap_or(&[]) //~ ERROR 9:19: 9:22: mismatched types [E0308] | |
| 9 | arg.unwrap_or(&[]) //~ ERROR mismatched types [E0308] | |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | pub fn barzz<'a>(arg: Option<&'a Vec<i32>>, v: &'a [i32]) -> &'a [i32] { |
| 13 | arg.unwrap_or(v) //~ ERROR 13:19: 13:20: mismatched types [E0308] | |
| 13 | arg.unwrap_or(v) //~ ERROR mismatched types [E0308] | |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | pub fn convert_result(arg: Result<&Vec<i32>, ()>) -> &[i32] { |
| 17 | arg.unwrap_or(&[]) //~ ERROR 17:19: 17:22: mismatched types [E0308] | |
| 17 | arg.unwrap_or(&[]) //~ ERROR mismatched types [E0308] | |
| 18 | 18 | } |
tests/ui/sanitizer/cfi/invalid-attr-encoding.rs+1-1| ... | ... | @@ -7,5 +7,5 @@ |
| 7 | 7 | #![no_core] |
| 8 | 8 | #![no_main] |
| 9 | 9 | |
| 10 | #[cfi_encoding] //~ERROR 10:1: 10:16: malformed `cfi_encoding` attribute input | |
| 10 | #[cfi_encoding] //~ ERROR malformed `cfi_encoding` attribute input | |
| 11 | 11 | pub struct Type1(i32); |
tests/ui/suggestions/issue-105645.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ fn main() { |
| 2 | 2 | let mut buf = [0u8; 50]; |
| 3 | 3 | let mut bref = buf.as_slice(); |
| 4 | 4 | foo(&mut bref); |
| 5 | //~^ ERROR 4:9: 4:18: the trait bound `&[u8]: std::io::Write` is not satisfied [E0277] | |
| 5 | //~^ ERROR the trait bound `&[u8]: std::io::Write` is not satisfied [E0277] | |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn foo(_: &mut impl std::io::Write) {} |
tests/ui/suggestions/suggest-full-enum-variant-for-local-module.rs+1-1| ... | ... | @@ -6,5 +6,5 @@ mod option { |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn main() { |
| 9 | let _: option::O<()> = (); //~ ERROR 9:28: 9:30: mismatched types [E0308] | |
| 9 | let _: option::O<()> = (); //~ ERROR mismatched types [E0308] | |
| 10 | 10 | } |
tests/ui/type/option-ref-advice.rs+2-2| ... | ... | @@ -3,9 +3,9 @@ |
| 3 | 3 | fn takes_option(_arg: Option<&String>) {} |
| 4 | 4 | |
| 5 | 5 | fn main() { |
| 6 | takes_option(&None); //~ ERROR 6:18: 6:23: mismatched types [E0308] | |
| 6 | takes_option(&None); //~ ERROR mismatched types [E0308] | |
| 7 | 7 | |
| 8 | 8 | let x = String::from("x"); |
| 9 | 9 | let res = Some(x); |
| 10 | takes_option(&res); //~ ERROR 10:18: 10:22: mismatched types [E0308] | |
| 10 | takes_option(&res); //~ ERROR mismatched types [E0308] | |
| 11 | 11 | } |
tests/ui/typeck/issue-100246.rs+1-1| ... | ... | @@ -25,6 +25,6 @@ fn downcast<'a, W: ?Sized>() -> std::io::Result<&'a W> { |
| 25 | 25 | struct Other; |
| 26 | 26 | |
| 27 | 27 | fn main() -> std::io::Result<()> { |
| 28 | let other: Other = downcast()?;//~ERROR 28:24: 28:35: `?` operator has incompatible types | |
| 28 | let other: Other = downcast()?; //~ ERROR `?` operator has incompatible types | |
| 29 | 29 | Ok(()) |
| 30 | 30 | } |
tests/ui/typeck/issue-89275.rs+1-1| ... | ... | @@ -25,5 +25,5 @@ fn downcast<'a, W: ?Sized>() -> &'a W { |
| 25 | 25 | struct Other; |
| 26 | 26 | |
| 27 | 27 | fn main() { |
| 28 | let other: &mut Other = downcast();//~ERROR 28:29: 28:39: mismatched types [E0308] | |
| 28 | let other: &mut Other = downcast();//~ ERROR mismatched types [E0308] | |
| 29 | 29 | } |